@ttsc/unplugin 0.31.5 → 0.32.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/lib/core/bridge/TtscProjectRecord.d.cts +8 -0
- package/lib/core/bridge/TtscProjectRecord.d.mts +8 -0
- package/lib/core/bridge/TtscProjectRecord.d.ts +8 -0
- package/lib/core/bridge/readProjectRecordFile.js +5 -1
- package/lib/core/bridge/readProjectRecordFile.js.map +1 -1
- package/lib/core/bridge/readProjectRecordFile.mjs +5 -1
- package/lib/core/bridge/readProjectRecordFile.mjs.map +1 -1
- package/lib/core/observer/WatchScope.d.cts +3 -3
- package/lib/core/observer/WatchScope.d.mts +3 -3
- package/lib/core/observer/WatchScope.d.ts +3 -3
- package/lib/core/observer/createInputObserver.d.cts +7 -8
- package/lib/core/observer/createInputObserver.d.mts +7 -8
- package/lib/core/observer/createInputObserver.d.ts +7 -8
- package/lib/core/observer/createInputObserver.js +7 -8
- package/lib/core/observer/createInputObserver.js.map +1 -1
- package/lib/core/observer/createInputObserver.mjs +7 -8
- package/lib/core/observer/createInputObserver.mjs.map +1 -1
- package/lib/core/transform/envelope/generationCaseSensitivity.d.cts +32 -0
- package/lib/core/transform/envelope/generationCaseSensitivity.d.mts +32 -0
- package/lib/core/transform/envelope/generationCaseSensitivity.d.ts +32 -0
- package/lib/core/transform/envelope/generationCaseSensitivity.js +39 -0
- package/lib/core/transform/envelope/generationCaseSensitivity.js.map +1 -0
- package/lib/core/transform/envelope/generationCaseSensitivity.mjs +37 -0
- package/lib/core/transform/envelope/generationCaseSensitivity.mjs.map +1 -0
- package/lib/core/transform/envelope/selectExternalInputPaths.js +2 -1
- package/lib/core/transform/envelope/selectExternalInputPaths.js.map +1 -1
- package/lib/core/transform/envelope/selectExternalInputPaths.mjs +2 -1
- package/lib/core/transform/envelope/selectExternalInputPaths.mjs.map +1 -1
- package/lib/core/transform/envelope/selectNotifiableAbsentInputs.js +2 -1
- package/lib/core/transform/envelope/selectNotifiableAbsentInputs.js.map +1 -1
- package/lib/core/transform/envelope/selectNotifiableAbsentInputs.mjs +2 -1
- package/lib/core/transform/envelope/selectNotifiableAbsentInputs.mjs.map +1 -1
- package/lib/core/transform/filesystem/createHostPathIdentityContext.d.cts +9 -1
- package/lib/core/transform/filesystem/createHostPathIdentityContext.d.mts +9 -1
- package/lib/core/transform/filesystem/createHostPathIdentityContext.d.ts +9 -1
- package/lib/core/transform/filesystem/createHostPathIdentityContext.js +10 -2
- package/lib/core/transform/filesystem/createHostPathIdentityContext.js.map +1 -1
- package/lib/core/transform/filesystem/createHostPathIdentityContext.mjs +10 -2
- package/lib/core/transform/filesystem/createHostPathIdentityContext.mjs.map +1 -1
- package/lib/core/transform/generation/captureTransformGeneration.js +10 -2
- package/lib/core/transform/generation/captureTransformGeneration.js.map +1 -1
- package/lib/core/transform/generation/captureTransformGeneration.mjs +10 -2
- package/lib/core/transform/generation/captureTransformGeneration.mjs.map +1 -1
- package/lib/core/transform/generation/selectPersistentHostInputs.js +2 -1
- package/lib/core/transform/generation/selectPersistentHostInputs.js.map +1 -1
- package/lib/core/transform/generation/selectPersistentHostInputs.mjs +2 -1
- package/lib/core/transform/generation/selectPersistentHostInputs.mjs.map +1 -1
- package/lib/core/transform/inputs/nativeInputPredicateState.js.map +1 -1
- package/lib/core/transform/inputs/nativeInputPredicateState.mjs.map +1 -1
- package/lib/core/transform/tracker/createHostInputMutationTracker.d.cts +7 -1
- package/lib/core/transform/tracker/createHostInputMutationTracker.d.mts +7 -1
- package/lib/core/transform/tracker/createHostInputMutationTracker.d.ts +7 -1
- package/lib/core/transform/tracker/createHostInputMutationTracker.js +8 -2
- package/lib/core/transform/tracker/createHostInputMutationTracker.js.map +1 -1
- package/lib/core/transform/tracker/createHostInputMutationTracker.mjs +8 -2
- package/lib/core/transform/tracker/createHostInputMutationTracker.mjs.map +1 -1
- package/lib/core/transform/tracker/createProjectMutationTracker.d.cts +6 -4
- package/lib/core/transform/tracker/createProjectMutationTracker.d.mts +6 -4
- package/lib/core/transform/tracker/createProjectMutationTracker.d.ts +6 -4
- package/lib/core/transform/tracker/createProjectMutationTracker.js +29 -6
- package/lib/core/transform/tracker/createProjectMutationTracker.js.map +1 -1
- package/lib/core/transform/tracker/createProjectMutationTracker.mjs +29 -6
- package/lib/core/transform/tracker/createProjectMutationTracker.mjs.map +1 -1
- package/lib/core/transform/transformTtsc.js +5 -1
- package/lib/core/transform/transformTtsc.js.map +1 -1
- package/lib/core/transform/transformTtsc.mjs +5 -1
- package/lib/core/transform/transformTtsc.mjs.map +1 -1
- package/lib/core/transform/watch/TtscWatchInputBaseline.d.cts +2 -1
- package/lib/core/transform/watch/TtscWatchInputBaseline.d.mts +2 -1
- package/lib/core/transform/watch/TtscWatchInputBaseline.d.ts +2 -1
- package/lib/core/transform/watch/isWatchInputKeyBaseline.js.map +1 -1
- package/lib/core/transform/watch/isWatchInputKeyBaseline.mjs.map +1 -1
- package/lib/core/transform/watch/notifyProjectRecord.d.cts +3 -4
- package/lib/core/transform/watch/notifyProjectRecord.d.mts +3 -4
- package/lib/core/transform/watch/notifyProjectRecord.d.ts +3 -4
- package/lib/core/transform/watch/notifyProjectRecord.js +5 -4
- package/lib/core/transform/watch/notifyProjectRecord.js.map +1 -1
- package/lib/core/transform/watch/notifyProjectRecord.mjs +5 -4
- package/lib/core/transform/watch/notifyProjectRecord.mjs.map +1 -1
- package/lib/core/transform/watch/recordedDependencyWitnesses.d.cts +30 -0
- package/lib/core/transform/watch/recordedDependencyWitnesses.d.mts +30 -0
- package/lib/core/transform/watch/recordedDependencyWitnesses.d.ts +30 -0
- package/lib/core/transform/watch/recordedDependencyWitnesses.js +51 -0
- package/lib/core/transform/watch/recordedDependencyWitnesses.js.map +1 -0
- package/lib/core/transform/watch/recordedDependencyWitnesses.mjs +49 -0
- package/lib/core/transform/watch/recordedDependencyWitnesses.mjs.map +1 -0
- package/lib/core/transform/watch/watchInputEvidenceMatchesBaseline.d.cts +1 -2
- package/lib/core/transform/watch/watchInputEvidenceMatchesBaseline.d.mts +1 -2
- package/lib/core/transform/watch/watchInputEvidenceMatchesBaseline.d.ts +1 -2
- package/lib/core/transform/watch/watchInputEvidenceMatchesBaseline.js +1 -2
- package/lib/core/transform/watch/watchInputEvidenceMatchesBaseline.js.map +1 -1
- package/lib/core/transform/watch/watchInputEvidenceMatchesBaseline.mjs +1 -2
- package/lib/core/transform/watch/watchInputEvidenceMatchesBaseline.mjs.map +1 -1
- package/lib/core/tsconfig/TsconfigReadTransaction.d.cts +11 -8
- package/lib/core/tsconfig/TsconfigReadTransaction.d.mts +11 -8
- package/lib/core/tsconfig/TsconfigReadTransaction.d.ts +11 -8
- package/lib/core/tsconfig/TsconfigReadTransaction.js +11 -8
- package/lib/core/tsconfig/TsconfigReadTransaction.js.map +1 -1
- package/lib/core/tsconfig/TsconfigReadTransaction.mjs +11 -8
- package/lib/core/tsconfig/TsconfigReadTransaction.mjs.map +1 -1
- package/lib/core/tsconfig/findDeclaredCompilerOption.d.cts +3 -2
- package/lib/core/tsconfig/findDeclaredCompilerOption.d.mts +3 -2
- package/lib/core/tsconfig/findDeclaredCompilerOption.d.ts +3 -2
- package/lib/core/tsconfig/findDeclaredCompilerOption.js +3 -2
- package/lib/core/tsconfig/findDeclaredCompilerOption.js.map +1 -1
- package/lib/core/tsconfig/findDeclaredCompilerOption.mjs +3 -2
- package/lib/core/tsconfig/findDeclaredCompilerOption.mjs.map +1 -1
- package/lib/core/tsconfig/findDeclaredFileSpecs.d.cts +3 -2
- package/lib/core/tsconfig/findDeclaredFileSpecs.d.mts +3 -2
- package/lib/core/tsconfig/findDeclaredFileSpecs.d.ts +3 -2
- package/lib/core/tsconfig/findDeclaredFileSpecs.js +3 -2
- package/lib/core/tsconfig/findDeclaredFileSpecs.js.map +1 -1
- package/lib/core/tsconfig/findDeclaredFileSpecs.mjs +3 -2
- package/lib/core/tsconfig/findDeclaredFileSpecs.mjs.map +1 -1
- package/lib/core/tsconfig/findDeclaredPaths.d.cts +3 -3
- package/lib/core/tsconfig/findDeclaredPaths.d.mts +3 -3
- package/lib/core/tsconfig/findDeclaredPaths.d.ts +3 -3
- package/lib/core/tsconfig/findDeclaredPaths.js +2 -2
- package/lib/core/tsconfig/findDeclaredPaths.mjs +2 -2
- package/lib/core/tsconfig/findDeclaredValue.d.cts +2 -1
- package/lib/core/tsconfig/findDeclaredValue.d.mts +2 -1
- package/lib/core/tsconfig/findDeclaredValue.d.ts +2 -1
- package/lib/core/tsconfig/findDeclaredValue.js +2 -1
- package/lib/core/tsconfig/findDeclaredValue.js.map +1 -1
- package/lib/core/tsconfig/findDeclaredValue.mjs +2 -1
- package/lib/core/tsconfig/findDeclaredValue.mjs.map +1 -1
- package/lib/core/tsconfig/readEffectiveTsconfigTemplateCompilerOptions.js +1 -1
- package/lib/core/tsconfig/readEffectiveTsconfigTemplateCompilerOptions.mjs +1 -1
- package/lib/core/tsconfig/readEffectiveTsconfigTemplateFileSpecs.d.cts +2 -2
- package/lib/core/tsconfig/readEffectiveTsconfigTemplateFileSpecs.d.mts +2 -2
- package/lib/core/tsconfig/readEffectiveTsconfigTemplateFileSpecs.d.ts +2 -2
- package/lib/core/tsconfig/readEffectiveTsconfigTemplateFileSpecs.js +2 -2
- package/lib/core/tsconfig/readEffectiveTsconfigTemplateFileSpecs.mjs +2 -2
- package/lib/core/tsconfig/readProjectMembershipPolicy.d.cts +3 -3
- package/lib/core/tsconfig/readProjectMembershipPolicy.d.mts +3 -3
- package/lib/core/tsconfig/readProjectMembershipPolicy.d.ts +3 -3
- package/lib/core/tsconfig/readProjectMembershipPolicy.js +4 -4
- package/lib/core/tsconfig/readProjectMembershipPolicy.mjs +4 -4
- package/package.json +4 -4
- package/src/core/bridge/TtscProjectRecord.ts +9 -0
- package/src/core/bridge/readProjectRecordFile.ts +5 -1
- package/src/core/observer/WatchScope.ts +3 -3
- package/src/core/observer/createInputObserver.ts +7 -8
- package/src/core/transform/envelope/generationCaseSensitivity.ts +46 -0
- package/src/core/transform/envelope/selectExternalInputPaths.ts +5 -1
- package/src/core/transform/envelope/selectNotifiableAbsentInputs.ts +5 -1
- package/src/core/transform/filesystem/createHostPathIdentityContext.ts +9 -1
- package/src/core/transform/generation/captureTransformGeneration.ts +10 -0
- package/src/core/transform/generation/selectPersistentHostInputs.ts +5 -1
- package/src/core/transform/inputs/nativeInputPredicateState.ts +1 -3
- package/src/core/transform/tracker/createHostInputMutationTracker.ts +10 -1
- package/src/core/transform/tracker/createProjectMutationTracker.ts +34 -6
- package/src/core/transform/transformTtsc.ts +5 -1
- package/src/core/transform/watch/TtscWatchInputBaseline.ts +2 -1
- package/src/core/transform/watch/isWatchInputKeyBaseline.ts +4 -2
- package/src/core/transform/watch/notifyProjectRecord.ts +5 -4
- package/src/core/transform/watch/recordedDependencyWitnesses.ts +50 -0
- package/src/core/transform/watch/watchInputEvidenceMatchesBaseline.ts +1 -2
- package/src/core/tsconfig/TsconfigReadTransaction.ts +11 -8
- package/src/core/tsconfig/findDeclaredCompilerOption.ts +3 -2
- package/src/core/tsconfig/findDeclaredFileSpecs.ts +3 -2
- package/src/core/tsconfig/findDeclaredPaths.ts +3 -3
- package/src/core/tsconfig/findDeclaredValue.ts +2 -1
- package/src/core/tsconfig/readEffectiveTsconfigTemplateCompilerOptions.ts +1 -1
- package/src/core/tsconfig/readEffectiveTsconfigTemplateFileSpecs.ts +2 -2
- package/src/core/tsconfig/readProjectMembershipPolicy.ts +4 -4
|
@@ -8,6 +8,7 @@ import { relativeToProject } from "../filesystem/relativeToProject";
|
|
|
8
8
|
import { isTransformScratchInput } from "../tsconfig/isTransformScratchInput";
|
|
9
9
|
import { envelopeDerivation } from "./envelopeDerivation";
|
|
10
10
|
import { envelopeGraphIndexes } from "./envelopeGraphIndexes";
|
|
11
|
+
import { generationCaseSensitivity } from "./generationCaseSensitivity";
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* The generation's resolution candidates recorded as not files, so its
|
|
@@ -72,7 +73,10 @@ export function selectNotifiableAbsentInputs(props: {
|
|
|
72
73
|
if (graph === undefined) {
|
|
73
74
|
return empty;
|
|
74
75
|
}
|
|
75
|
-
const identities = createHostPathIdentityContext(
|
|
76
|
+
const identities = createHostPathIdentityContext(
|
|
77
|
+
props.filesystem,
|
|
78
|
+
generationCaseSensitivity(props),
|
|
79
|
+
);
|
|
76
80
|
const graphState = envelopeDerivation({
|
|
77
81
|
projectRoot: props.projectRoot,
|
|
78
82
|
result: props.result,
|
|
@@ -29,6 +29,8 @@ import type { TtscTransformFilesystemOperations } from "./TtscTransformFilesyste
|
|
|
29
29
|
* The returned context memoizes path, realpath and case observations for
|
|
30
30
|
* repeated questions within one filesystem transaction. Callers must create
|
|
31
31
|
* a new context when later filesystem changes can invalidate those observations.
|
|
32
|
+
* A caller capturing one generation can hand in that generation's case answers,
|
|
33
|
+
* so its contexts do not each ask the filesystem again (samchon/ttsc#1742).
|
|
32
34
|
* @evidence contracts/performance.md#bound-retention-and-release-resources
|
|
33
35
|
* Ownership of the context and its maps transfers to the caller. Retained
|
|
34
36
|
* entries grow with queried paths and ancestors and have no internal eviction;
|
|
@@ -36,9 +38,15 @@ import type { TtscTransformFilesystemOperations } from "./TtscTransformFilesyste
|
|
|
36
38
|
*/
|
|
37
39
|
export function createHostPathIdentityContext(
|
|
38
40
|
filesystem: TtscTransformFilesystemOperations = DEFAULT_FILESYSTEM_OPERATIONS,
|
|
41
|
+
/**
|
|
42
|
+
* Case answers this context shares with the others of its unit of work,
|
|
43
|
+
* observed through the same `filesystem`; omitted, the context asks for
|
|
44
|
+
* itself.
|
|
45
|
+
*/
|
|
46
|
+
caseSensitive: TtscTransformFilesystemOperations["caseSensitive"] = filesystem.caseSensitive,
|
|
39
47
|
): FilesystemPathIdentityContext {
|
|
40
48
|
return createFilesystemPathIdentityContext({
|
|
41
|
-
caseSensitive
|
|
49
|
+
caseSensitive,
|
|
42
50
|
lstat: filesystem.lstat,
|
|
43
51
|
platform: filesystem.platform,
|
|
44
52
|
readdir: (directory) =>
|
|
@@ -12,6 +12,7 @@ import { TRANSFORM_RESULT_MEMBERSHIP } from "../cache/TRANSFORM_RESULT_MEMBERSHI
|
|
|
12
12
|
import type { TtscCachedProjectTransform } from "../cache/TtscCachedProjectTransform";
|
|
13
13
|
import { refreshFilesystemClockReference } from "../clock/refreshFilesystemClockReference";
|
|
14
14
|
import { reportDivergentDelivery } from "../diagnostics/reportDivergentDelivery";
|
|
15
|
+
import { generationCaseSensitivity } from "../envelope/generationCaseSensitivity";
|
|
15
16
|
import { selectDeclaredProjectInputKeys } from "../envelope/selectDeclaredProjectInputKeys";
|
|
16
17
|
import { selectExternalInputPaths } from "../envelope/selectExternalInputPaths";
|
|
17
18
|
import { selectNotifiableAbsentInputs } from "../envelope/selectNotifiableAbsentInputs";
|
|
@@ -457,6 +458,13 @@ export async function captureTransformGeneration(props: {
|
|
|
457
458
|
clockReferenceDirectory ?? scratchDirectory,
|
|
458
459
|
props.filesystem,
|
|
459
460
|
);
|
|
461
|
+
// Every context capturing this generation below shares the generation's
|
|
462
|
+
// directory case answers, rather than each asking again (samchon/ttsc#1742).
|
|
463
|
+
const generationCase = generationCaseSensitivity({
|
|
464
|
+
filesystem: props.filesystem,
|
|
465
|
+
projectRoot,
|
|
466
|
+
result,
|
|
467
|
+
});
|
|
460
468
|
const persistentHostInputs = selectPersistentHostInputs({
|
|
461
469
|
filesystem: props.filesystem,
|
|
462
470
|
projectRoot,
|
|
@@ -518,6 +526,7 @@ export async function captureTransformGeneration(props: {
|
|
|
518
526
|
projectRoot,
|
|
519
527
|
result,
|
|
520
528
|
}),
|
|
529
|
+
generationCase,
|
|
521
530
|
)
|
|
522
531
|
: undefined;
|
|
523
532
|
compileTrace?.("bridge-tracker-lifecycle", {
|
|
@@ -566,6 +575,7 @@ export async function captureTransformGeneration(props: {
|
|
|
566
575
|
.filter((input) => !absentCandidates.has(input))
|
|
567
576
|
.map((input) => [path.resolve(input), "presence" as const]),
|
|
568
577
|
),
|
|
578
|
+
generationCase,
|
|
569
579
|
)
|
|
570
580
|
: undefined;
|
|
571
581
|
compileTrace?.("bridge-tracker-lifecycle", {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ITtscCompilerTransformation } from "ttsc";
|
|
2
2
|
|
|
3
|
+
import { generationCaseSensitivity } from "../envelope/generationCaseSensitivity";
|
|
3
4
|
import { selectListedFiles } from "../envelope/selectListedFiles";
|
|
4
5
|
import type { TtscTransformFilesystemOperations } from "../filesystem/TtscTransformFilesystemOperations";
|
|
5
6
|
import { createHostPathIdentityContext } from "../filesystem/createHostPathIdentityContext";
|
|
@@ -43,7 +44,10 @@ export function selectPersistentHostInputs(props: {
|
|
|
43
44
|
props.temporaryTsconfig === undefined
|
|
44
45
|
)
|
|
45
46
|
return inputs;
|
|
46
|
-
const identities = createHostPathIdentityContext(
|
|
47
|
+
const identities = createHostPathIdentityContext(
|
|
48
|
+
props.filesystem,
|
|
49
|
+
generationCaseSensitivity(props),
|
|
50
|
+
);
|
|
47
51
|
const temporary =
|
|
48
52
|
props.temporaryTsconfig === undefined
|
|
49
53
|
? undefined
|
|
@@ -69,9 +69,7 @@ export function nativeInputPredicateState(
|
|
|
69
69
|
} else if (kind === "optional-file") {
|
|
70
70
|
try {
|
|
71
71
|
digest = filesystem.stat(file).isFile()
|
|
72
|
-
? hash(
|
|
73
|
-
Buffer.concat([Buffer.from("file\0"), readBytes()]),
|
|
74
|
-
)
|
|
72
|
+
? hash(Buffer.concat([Buffer.from("file\0"), readBytes()]))
|
|
75
73
|
: hash("missing\0");
|
|
76
74
|
} catch (error) {
|
|
77
75
|
if (!missing(error)) return undefined;
|
|
@@ -114,12 +114,21 @@ export async function createHostInputMutationTracker(
|
|
|
114
114
|
* filesystem.
|
|
115
115
|
*/
|
|
116
116
|
scopes?: ReadonlyMap<string, TtscTrackedInputScope>,
|
|
117
|
+
/**
|
|
118
|
+
* The case answers of the generation this tracker watches, for its baseline
|
|
119
|
+
* (`generationCaseSensitivity`); omitted, the baseline observes for itself.
|
|
120
|
+
* An event's re-check always observes afresh.
|
|
121
|
+
*/
|
|
122
|
+
caseSensitive?: TtscTransformFilesystemOperations["caseSensitive"],
|
|
117
123
|
): Promise<TtscProjectMutationTracker> {
|
|
118
124
|
const paths =
|
|
119
125
|
(filesystem.platform ?? process.platform) === "win32"
|
|
120
126
|
? path.win32
|
|
121
127
|
: path.posix;
|
|
122
|
-
const identities = createHostPathIdentityContext(
|
|
128
|
+
const identities = createHostPathIdentityContext(
|
|
129
|
+
filesystem,
|
|
130
|
+
caseSensitive ?? filesystem.caseSensitive,
|
|
131
|
+
);
|
|
123
132
|
// The project root in both of its spellings: an input the compiler reported
|
|
124
133
|
// physically is the project's as much as one spelled as the project was
|
|
125
134
|
// named, and the root's observer is opened once, under the name.
|
|
@@ -38,10 +38,12 @@ import { watchLocationIdentity } from "./watchLocationIdentity";
|
|
|
38
38
|
* directory excluded in both lexical and native spellings. Unknown, missing and
|
|
39
39
|
* linked ancestry remains conservative. Membership rejection withdraws
|
|
40
40
|
* notification authority except below such a proven excluded directory, so a
|
|
41
|
-
* recursive backend's writes to a cache or output tree cost no proof
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
41
|
+
* recursive backend's writes to a cache or output tree cost no proof, nor does
|
|
42
|
+
* an edit to an existing unlinked file whose every name the program cannot
|
|
43
|
+
* admit (samchon/ttsc#1737). Named events also compare current native identity
|
|
44
|
+
* and case policy with the retained identity transaction. Retargeting withdraws
|
|
45
|
+
* notification authority without changing the meaning of earlier recorded event
|
|
46
|
+
* spellings.
|
|
45
47
|
*
|
|
46
48
|
* @evidence contracts/common.md#principled-implementation
|
|
47
49
|
* The project walk and membership policy own structural relevance; content
|
|
@@ -193,6 +195,26 @@ export async function createProjectMutationTracker(
|
|
|
193
195
|
}
|
|
194
196
|
return excluded;
|
|
195
197
|
};
|
|
198
|
+
// Whether an event names an existing file no spelling can make a program
|
|
199
|
+
// member: a regular file with no second hard link, whose own and physical
|
|
200
|
+
// names are both names the program cannot admit. A directory alias can move
|
|
201
|
+
// a file into the program but cannot rename it, and a removed name, a link
|
|
202
|
+
// or a directory stays conservative.
|
|
203
|
+
const existingNonProgramFile = (changed: string): boolean => {
|
|
204
|
+
try {
|
|
205
|
+
const stats = filesystem.lstat(changed);
|
|
206
|
+
if (!stats.isFile() || stats.nlink > 1n) return false;
|
|
207
|
+
return (
|
|
208
|
+
!isPossibleProgramFileName(paths.basename(changed), policy) &&
|
|
209
|
+
!isPossibleProgramFileName(
|
|
210
|
+
paths.basename(filesystem.realpath(changed)),
|
|
211
|
+
policy,
|
|
212
|
+
)
|
|
213
|
+
);
|
|
214
|
+
} catch {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
196
218
|
const reportsMembership = (location: string, filename: string): boolean => {
|
|
197
219
|
const changed = paths.join(location, filename);
|
|
198
220
|
const current = createHostPathIdentityContext(filesystem);
|
|
@@ -221,8 +243,14 @@ export async function createProjectMutationTracker(
|
|
|
221
243
|
// except below a directory the walk provably excludes. A recursive backend
|
|
222
244
|
// (macOS, Windows) hears every write under the root, a cache or an output
|
|
223
245
|
// directory among them, and withdrawing authority for each sent every later
|
|
224
|
-
// delivery to the whole-snapshot proof.
|
|
225
|
-
|
|
246
|
+
// delivery to the whole-snapshot proof. An existing file whose every name
|
|
247
|
+
// the program cannot admit is no member either, a stylesheet or an asset
|
|
248
|
+
// edited in a source directory among them, on every backend.
|
|
249
|
+
if (
|
|
250
|
+
!membership &&
|
|
251
|
+
!excludedFromWalk(changed, true) &&
|
|
252
|
+
!existingNonProgramFile(changed)
|
|
253
|
+
)
|
|
226
254
|
tracker.unverified = true;
|
|
227
255
|
return membership;
|
|
228
256
|
};
|
|
@@ -33,6 +33,7 @@ import type { TtscTransformHooks } from "./watch/TtscTransformHooks";
|
|
|
33
33
|
import type { TtscWatchSelection } from "./watch/TtscWatchSelection";
|
|
34
34
|
import { notifyRejectedGenerationInputs } from "./watch/notifyRejectedGenerationInputs";
|
|
35
35
|
import { prepareProjectRecordDirectories } from "./watch/prepareProjectRecordDirectories";
|
|
36
|
+
import { recordedDependencyWitnesses } from "./watch/recordedDependencyWitnesses";
|
|
36
37
|
|
|
37
38
|
/**
|
|
38
39
|
* Apply the ttsc plugin transform to a single source file.
|
|
@@ -282,10 +283,13 @@ export async function transformTtsc(
|
|
|
282
283
|
cache === undefined
|
|
283
284
|
? undefined
|
|
284
285
|
: TRANSFORM_CACHE_CASE_POLICIES.get(cache)?.get(key),
|
|
286
|
+
// A cache without a list of its own takes the names the project's
|
|
287
|
+
// record carries from an earlier process (samchon/ttsc#1743).
|
|
285
288
|
witnessedDependencies:
|
|
286
289
|
cache === undefined
|
|
287
290
|
? undefined
|
|
288
|
-
: TRANSFORM_CACHE_DEPENDENCY_WITNESSES.get(cache)?.get(key)
|
|
291
|
+
: (TRANSFORM_CACHE_DEPENDENCY_WITNESSES.get(cache)?.get(key) ??
|
|
292
|
+
recordedDependencyWitnesses(hooks?.project, tsconfig)),
|
|
289
293
|
});
|
|
290
294
|
cache?.set(key, transformed);
|
|
291
295
|
}
|
|
@@ -23,7 +23,8 @@ import type { TtscWatchInputFileBaseline } from "./TtscWatchInputFileBaseline";
|
|
|
23
23
|
export interface TtscWatchInputBaseline extends TtscWatchInputFileBaseline {
|
|
24
24
|
/**
|
|
25
25
|
* Current version-one native codec facts, captured only for requested kinds.
|
|
26
|
-
* These observations do not certify a producer's identityStable flag or
|
|
26
|
+
* These observations do not certify a producer's identityStable flag or
|
|
27
|
+
* scope.
|
|
27
28
|
*/
|
|
28
29
|
nativePredicates?: Partial<
|
|
29
30
|
Record<
|
|
@@ -115,9 +115,11 @@ function isNativePredicateBaselines(value: unknown): boolean {
|
|
|
115
115
|
stableStringify(Object.keys(state).sort()) !==
|
|
116
116
|
stableStringify(["digest", "realpath"]) ||
|
|
117
117
|
!isContentHash(state.digest) ||
|
|
118
|
-
!(
|
|
118
|
+
!(
|
|
119
|
+
state.realpath === null ||
|
|
119
120
|
(typeof state.realpath === "string" &&
|
|
120
|
-
isAbsoluteFilesystemPath(state.realpath))
|
|
121
|
+
isAbsoluteFilesystemPath(state.realpath))
|
|
122
|
+
)
|
|
121
123
|
) {
|
|
122
124
|
return false;
|
|
123
125
|
}
|
|
@@ -73,10 +73,9 @@ const HANDED = new WeakMap<
|
|
|
73
73
|
* loses acceptance and enters persistence again without rereading generation
|
|
74
74
|
* inputs. Hosts and bridge readers own current byte proof, including concurrent
|
|
75
75
|
* changes and unreadable/torn bytes; availability here cannot exclude removal
|
|
76
|
-
* after the check. A host that keeps no
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* (`TtscProjectRegistration.digest`).
|
|
76
|
+
* after the check. A host that keeps no snapshot of the file, Rollup's cache,
|
|
77
|
+
* is handed the digest of the bytes written for the generation to compare
|
|
78
|
+
* against instead (`TtscProjectRegistration.digest`).
|
|
80
79
|
*
|
|
81
80
|
* A record lives below the host's tool directory, or, when that cannot be
|
|
82
81
|
* written, below the fallback the host accepts (`fallbackToolDirectory`,
|
|
@@ -226,7 +225,9 @@ function recordOf(
|
|
|
226
225
|
cached: TtscCachedProjectTransform,
|
|
227
226
|
inputs: readonly TtscWatchInput[],
|
|
228
227
|
): TtscProjectRecord {
|
|
228
|
+
const dependencies = cached.externalDependencyInputs ?? [];
|
|
229
229
|
const record: TtscProjectRecord = {
|
|
230
|
+
...(dependencies.length === 0 ? {} : { dependencies }),
|
|
230
231
|
inputs: {},
|
|
231
232
|
membership:
|
|
232
233
|
cached.projectDirectories === undefined
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { projectRecordFile } from "../../bridge/projectRecordFile";
|
|
2
|
+
import { readProjectRecordFile } from "../../bridge/readProjectRecordFile";
|
|
3
|
+
import type { TtscTransformHooks } from "./TtscTransformHooks";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The dependency-only paths the project record of `tsconfig` carries
|
|
7
|
+
* (`TtscProjectRecord.dependencies`), for a transform cache that has no witness
|
|
8
|
+
* list of its own yet.
|
|
9
|
+
*
|
|
10
|
+
* A compile learns a plugin-reported dependency path only from its own
|
|
11
|
+
* envelope, and one it had no witness for compiles again
|
|
12
|
+
* (`onlyLearnedCompileFacts`). A transform cache keeps the paths in memory
|
|
13
|
+
* (`TRANSFORM_CACHE_DEPENDENCY_WITNESSES`), so every new cache, a dev-server
|
|
14
|
+
* start or a build process, compiled such a project twice (samchon/ttsc#1743).
|
|
15
|
+
* The record the previous process wrote names them. They only say what to read:
|
|
16
|
+
* the capture still witnesses each path afresh, a path the compile no longer
|
|
17
|
+
* reports costs one read, and one the record does not name is retried as
|
|
18
|
+
* before.
|
|
19
|
+
*
|
|
20
|
+
* @param project The host's record directories, when it keeps records.
|
|
21
|
+
* @param tsconfig The project's tsconfig, as the adapter names it.
|
|
22
|
+
* @returns The record's paths, or `undefined` when no readable record names
|
|
23
|
+
* any.
|
|
24
|
+
* @evidence contracts/common.md#principled-implementation The record is the host's persisted project state, written from a completed generation; its paths are hints that the capture re-witnesses, never certified state.
|
|
25
|
+
* @evidence contracts/common.md#clear-and-simple-design One reader selects the first readable record of the host's directories, in the order the writer tries them.
|
|
26
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts No witness or digest is taken from the record; an unreadable or absent record supplies nothing.
|
|
27
|
+
* @evidence contracts/common.md#meaningful-documentation Native paragraphs explain the doubled first compile, the hint semantics and the absent cases.
|
|
28
|
+
* @evidence contracts/portability.md#os-neutral-implementation Record paths come from the host's own directories through `projectRecordFile`.
|
|
29
|
+
* @evidence contracts/performance.md#efficient-algorithms At most two record reads and JSON parses, only when a cache has no witness list for the key.
|
|
30
|
+
* @evidence contracts/performance.md#reuse-equivalent-work A new process reuses the dependency names the last generation's record holds instead of compiling once to learn them.
|
|
31
|
+
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The returned list belongs to the caller; nothing is retained here.
|
|
32
|
+
*/
|
|
33
|
+
export function recordedDependencyWitnesses(
|
|
34
|
+
project: TtscTransformHooks["project"],
|
|
35
|
+
tsconfig: string,
|
|
36
|
+
): readonly string[] | undefined {
|
|
37
|
+
if (project === undefined) return undefined;
|
|
38
|
+
for (const directory of [
|
|
39
|
+
project.toolDirectory,
|
|
40
|
+
...(project.fallbackToolDirectory === undefined
|
|
41
|
+
? []
|
|
42
|
+
: [project.fallbackToolDirectory]),
|
|
43
|
+
]) {
|
|
44
|
+
const record = readProjectRecordFile(
|
|
45
|
+
projectRecordFile(directory, tsconfig),
|
|
46
|
+
);
|
|
47
|
+
if (record !== undefined) return record.dependencies;
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
@@ -10,8 +10,7 @@ import { isWatchInputKeyBaseline } from "./isWatchInputKeyBaseline";
|
|
|
10
10
|
*
|
|
11
11
|
* A codec matches only the facts the baseline actually captured. Native,
|
|
12
12
|
* listing and plugin-tree observations require their optional payloads;
|
|
13
|
-
* membership is a
|
|
14
|
-
* separate project walk and cannot match one path's baseline.
|
|
13
|
+
* membership is a separate project walk and cannot match one path's baseline.
|
|
15
14
|
*
|
|
16
15
|
* @evidence contracts/common.md#principled-implementation Identity and every recorded codec fact must agree with a validated baseline; native predicates additionally require a supported version, stable producer identity, matching raw digest and physical target. Narrow discovery facts and absent optional native/listing/tree payloads cannot establish broader observations.
|
|
17
16
|
* @evidence contracts/common.md#clear-and-simple-design Codec branches reuse the strict baseline guard and native realpath comparator, with one private refinement exposing the broader carrier.
|
|
@@ -7,14 +7,16 @@ import { resolveExtendsConfig } from "./resolveExtendsConfig";
|
|
|
7
7
|
import { resolveRealPath } from "./resolveRealPath";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Share config observations and contextual selections within one synchronous
|
|
10
|
+
* Share config observations and contextual selections within one synchronous
|
|
11
|
+
* read.
|
|
11
12
|
*
|
|
12
13
|
* Lexical paths own parsing and relative extends resolution. Physical paths
|
|
13
14
|
* only guard ancestry cycles. A completed selection can be borrowed when the
|
|
14
15
|
* current ancestors intersect its encountered physical identities exactly as
|
|
15
16
|
* they did originally; otherwise a different cycle cut requires evaluation.
|
|
16
17
|
* Ordered source observations travel with a completed selection, including
|
|
17
|
-
* unresolved file candidates, so reuse preserves the caller's invalidation
|
|
18
|
+
* unresolved file candidates, so reuse preserves the caller's invalidation
|
|
19
|
+
* inputs.
|
|
18
20
|
*
|
|
19
21
|
* Create a new transaction for each independent freshness observation. This
|
|
20
22
|
* owner neither validates reuse across reads nor supplies compiler diagnostics.
|
|
@@ -94,12 +96,13 @@ export class TsconfigReadTransaction {
|
|
|
94
96
|
/**
|
|
95
97
|
* Select one declaration, preserving its lexical directory and observations.
|
|
96
98
|
*
|
|
97
|
-
* An undefined own selection inherits. Null masks inheritance without
|
|
98
|
-
* a value, as an invalid own file list does; a parent ignores that
|
|
99
|
-
* First queries search later bases first; last queries visit
|
|
100
|
-
* The caller's physical ancestor set is copied once and
|
|
101
|
-
* Selectors must preserve the parsed inputs and give the same
|
|
102
|
-
* the same source; query reuse does not repeat their
|
|
99
|
+
* An undefined own selection inherits. Null masks inheritance without
|
|
100
|
+
* supplying a value, as an invalid own file list does; a parent ignores that
|
|
101
|
+
* empty result. First queries search later bases first; last queries visit
|
|
102
|
+
* all bases forward. The caller's physical ancestor set is copied once and
|
|
103
|
+
* never mutated. Selectors must preserve the parsed inputs and give the same
|
|
104
|
+
* declaration for the same source; query reuse does not repeat their
|
|
105
|
+
* incidental effects.
|
|
103
106
|
*
|
|
104
107
|
* @evidence contracts/common.md#principled-implementation A completed answer is reusable only when its encountered physical identities have the same intersection with current ancestry. That preserves every observed cycle decision, including cuts; own declarations and first/last traversal retain lexical origins and key-specific precedence.
|
|
105
108
|
* @evidence contracts/common.md#clear-and-simple-design A query-local visitor owns selection and contextual completed answers; transaction nodes separately share lexical source, identity and edge observations across keys.
|
|
@@ -6,8 +6,9 @@ import { findDeclaredValue } from "./findDeclaredValue";
|
|
|
6
6
|
*
|
|
7
7
|
* Own key presence is significant even for null or undefined values; the caller
|
|
8
8
|
* decides whether the selected option value is usable. An optional
|
|
9
|
-
* decoded-source map or graph transaction belongs to one caller read;
|
|
10
|
-
* option searches retain their selectors and physical ancestry
|
|
9
|
+
* decoded-source map or graph transaction belongs to one caller read;
|
|
10
|
+
* independent option searches retain their selectors and physical ancestry
|
|
11
|
+
* contexts.
|
|
11
12
|
*
|
|
12
13
|
* @evidence contracts/common.md#principled-implementation
|
|
13
14
|
* A wrapper preserves key presence through the generic selector, so the own
|
|
@@ -13,8 +13,9 @@ import { TsconfigReadTransaction } from "./TsconfigReadTransaction";
|
|
|
13
13
|
* anchored at the named declaring config, including independent link aliases.
|
|
14
14
|
*
|
|
15
15
|
* @returns The list and its directory, undefined when no array is selected, or
|
|
16
|
-
* null when the root config cannot be read as an object. A supplied
|
|
17
|
-
* belongs to this freshness observation; later reads require a
|
|
16
|
+
* null when the root config cannot be read as an object. A supplied
|
|
17
|
+
* transaction belongs to this freshness observation; later reads require a
|
|
18
|
+
* fresh owner.
|
|
18
19
|
* @evidence contracts/common.md#principled-implementation
|
|
19
20
|
* Own invalid values stop inheritance at that node. Forward inherited
|
|
20
21
|
* traversal keeps the last array and ignores empty selections, preserving
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TsconfigReadTransaction } from "./TsconfigReadTransaction";
|
|
2
1
|
import type { IDeclaredPaths } from "./IDeclaredPaths";
|
|
2
|
+
import { TsconfigReadTransaction } from "./TsconfigReadTransaction";
|
|
3
3
|
import { findDeclaredValue } from "./findDeclaredValue";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -7,8 +7,8 @@ import { findDeclaredValue } from "./findDeclaredValue";
|
|
|
7
7
|
* rooted at `tsconfig`. The own config wins over its bases; within an `extends`
|
|
8
8
|
* array, later entries win over earlier ones. `seen` breaks circular chains;
|
|
9
9
|
* the compiler reports the actual config error. Optional decoded sources or
|
|
10
|
-
* graph observations share only within the caller's current read; physical
|
|
11
|
-
* guards remain branch-local.
|
|
10
|
+
* graph observations share only within the caller's current read; physical
|
|
11
|
+
* cycle guards remain branch-local.
|
|
12
12
|
*
|
|
13
13
|
* @evidence contracts/common.md#principled-implementation
|
|
14
14
|
* The selector accepts a non-array paths record and the shared value reader
|
|
@@ -7,7 +7,8 @@ import { TsconfigReadTransaction } from "./TsconfigReadTransaction";
|
|
|
7
7
|
* remain anchored at the named config; physical identity only cuts branch
|
|
8
8
|
* cycles. Independent aliases can therefore resolve different relative bases.
|
|
9
9
|
* Missing or malformed configs remain best-effort absence; the compiler owns
|
|
10
|
-
* configuration diagnostics. Unresolved file candidates remain observed
|
|
10
|
+
* configuration diagnostics. Unresolved file candidates remain observed
|
|
11
|
+
* inputs.
|
|
11
12
|
*
|
|
12
13
|
* A supplied transaction shares source, identity and edge observations across
|
|
13
14
|
* keys. A decoded-source map remains supported for callers that own that map;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
|
|
3
|
-
import { TsconfigReadTransaction } from "./TsconfigReadTransaction";
|
|
4
3
|
import { CONFIG_DIR_TEMPLATE_LIST_OPTIONS } from "./CONFIG_DIR_TEMPLATE_LIST_OPTIONS";
|
|
5
4
|
import { CONFIG_DIR_TEMPLATE_SCALAR_OPTIONS } from "./CONFIG_DIR_TEMPLATE_SCALAR_OPTIONS";
|
|
5
|
+
import { TsconfigReadTransaction } from "./TsconfigReadTransaction";
|
|
6
6
|
import { absolutizePathsTarget } from "./absolutizePathsTarget";
|
|
7
7
|
import { findDeclaredCompilerOption } from "./findDeclaredCompilerOption";
|
|
8
8
|
import { findDeclaredPaths } from "./findDeclaredPaths";
|
|
@@ -15,8 +15,8 @@ const CONFIG_DIR_TEMPLATE_FILE_SPECS = ["exclude", "files", "include"] as const;
|
|
|
15
15
|
* Lists use the compiler's last-inherited-array rule: a later base declaring
|
|
16
16
|
* null cannot erase an earlier array. Invalid elements are preserved so this
|
|
17
17
|
* overlay does not hide the compiler's configuration diagnostics. The three
|
|
18
|
-
* list searches share graph observations only within this call; a later call
|
|
19
|
-
* current bytes in a fresh transaction.
|
|
18
|
+
* list searches share graph observations only within this call; a later call
|
|
19
|
+
* reads current bytes in a fresh transaction.
|
|
20
20
|
*
|
|
21
21
|
* @param configDir The directory `${configDir}` stands for, as
|
|
22
22
|
* `readEffectiveTsconfigTemplateCompilerOptions` takes it.
|
|
@@ -2,9 +2,9 @@ import path from "node:path";
|
|
|
2
2
|
|
|
3
3
|
import { TYPESCRIPT_TRANSFORM_EXTENSIONS } from "../source/TYPESCRIPT_TRANSFORM_EXTENSIONS";
|
|
4
4
|
import type { ITtscProjectMembershipPolicy } from "./ITtscProjectMembershipPolicy";
|
|
5
|
-
import { TsconfigReadTransaction } from "./TsconfigReadTransaction";
|
|
6
5
|
import { JAVASCRIPT_INPUT_EXTENSIONS } from "./JAVASCRIPT_INPUT_EXTENSIONS";
|
|
7
6
|
import { OUTPUT_DIRECTORY_OPTIONS } from "./OUTPUT_DIRECTORY_OPTIONS";
|
|
7
|
+
import { TsconfigReadTransaction } from "./TsconfigReadTransaction";
|
|
8
8
|
import { absolutizePathsTarget } from "./absolutizePathsTarget";
|
|
9
9
|
import { findDeclaredFileSpecs } from "./findDeclaredFileSpecs";
|
|
10
10
|
import { findDeclaredValue } from "./findDeclaredValue";
|
|
@@ -40,9 +40,9 @@ const DEFAULT_INCLUDE_SPEC = "**/*";
|
|
|
40
40
|
* refuses to guess in the direction that loses correctness.
|
|
41
41
|
*
|
|
42
42
|
* Source, identity and extends observations share this transaction. Completed
|
|
43
|
-
* selections, including absence, require matching physical ancestry
|
|
44
|
-
* Later calls start fresh, so unchanged metadata cannot conceal
|
|
45
|
-
* text or resolution.
|
|
43
|
+
* selections, including absence, require matching physical ancestry
|
|
44
|
+
* intersections. Later calls start fresh, so unchanged metadata cannot conceal
|
|
45
|
+
* changed source text or resolution.
|
|
46
46
|
*
|
|
47
47
|
* @evidence contracts/common.md#principled-implementation
|
|
48
48
|
* Config-derived root specs, allowed extensions and exclusion provenance
|