@ttsc/unplugin 0.31.5 → 0.32.1
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/options/ResolvedTtscUnpluginOptions.d.cts +2 -0
- package/lib/core/options/ResolvedTtscUnpluginOptions.d.mts +2 -0
- package/lib/core/options/ResolvedTtscUnpluginOptions.d.ts +2 -0
- package/lib/core/options/TtscUnpluginOptions.d.cts +12 -2
- package/lib/core/options/TtscUnpluginOptions.d.mts +12 -2
- package/lib/core/options/TtscUnpluginOptions.d.ts +12 -2
- package/lib/core/options/resolveOptions.d.cts +4 -3
- package/lib/core/options/resolveOptions.d.mts +4 -3
- package/lib/core/options/resolveOptions.d.ts +4 -3
- package/lib/core/options/resolveOptions.js +5 -3
- package/lib/core/options/resolveOptions.js.map +1 -1
- package/lib/core/options/resolveOptions.mjs +5 -3
- package/lib/core/options/resolveOptions.mjs.map +1 -1
- package/lib/core/transform/TtscPrecompilation.d.cts +52 -0
- package/lib/core/transform/TtscPrecompilation.d.mts +52 -0
- package/lib/core/transform/TtscPrecompilation.d.ts +52 -0
- package/lib/core/transform/TtscPrecompilation.js +101 -0
- package/lib/core/transform/TtscPrecompilation.js.map +1 -0
- package/lib/core/transform/TtscPrecompilation.mjs +101 -0
- package/lib/core/transform/TtscPrecompilation.mjs.map +1 -0
- package/lib/core/transform/cache/selectCachedGenerationAction.d.cts +2 -0
- package/lib/core/transform/cache/selectCachedGenerationAction.d.mts +2 -0
- package/lib/core/transform/cache/selectCachedGenerationAction.d.ts +2 -0
- package/lib/core/transform/cache/selectCachedGenerationAction.js +1 -1
- package/lib/core/transform/cache/selectCachedGenerationAction.js.map +1 -1
- package/lib/core/transform/cache/selectCachedGenerationAction.mjs +1 -1
- package/lib/core/transform/cache/selectCachedGenerationAction.mjs.map +1 -1
- package/lib/core/transform/cache/withdrawTtscTransformGenerations.js +2 -0
- package/lib/core/transform/cache/withdrawTtscTransformGenerations.js.map +1 -1
- package/lib/core/transform/cache/withdrawTtscTransformGenerations.mjs +2 -0
- package/lib/core/transform/cache/withdrawTtscTransformGenerations.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.d.cts +2 -0
- package/lib/core/transform/generation/captureTransformGeneration.d.mts +2 -0
- package/lib/core/transform/generation/captureTransformGeneration.d.ts +2 -0
- package/lib/core/transform/generation/captureTransformGeneration.js +17 -4
- package/lib/core/transform/generation/captureTransformGeneration.js.map +1 -1
- package/lib/core/transform/generation/captureTransformGeneration.mjs +17 -4
- 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/generation/transformProject.d.cts +2 -0
- package/lib/core/transform/generation/transformProject.d.mts +2 -0
- package/lib/core/transform/generation/transformProject.d.ts +2 -0
- package/lib/core/transform/generation/transformProject.js.map +1 -1
- package/lib/core/transform/generation/transformProject.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.d.cts +8 -24
- package/lib/core/transform/transformTtsc.d.mts +8 -24
- package/lib/core/transform/transformTtsc.d.ts +8 -24
- package/lib/core/transform/transformTtsc.js +56 -32
- package/lib/core/transform/transformTtsc.js.map +1 -1
- package/lib/core/transform/transformTtsc.mjs +56 -32
- package/lib/core/transform/transformTtsc.mjs.map +1 -1
- package/lib/core/transform/validation/captureUniversalHostInputValidation.d.cts +1 -1
- package/lib/core/transform/validation/captureUniversalHostInputValidation.d.mts +1 -1
- package/lib/core/transform/validation/captureUniversalHostInputValidation.d.ts +1 -1
- package/lib/core/transform/validation/captureUniversalHostInputValidation.js +12 -4
- package/lib/core/transform/validation/captureUniversalHostInputValidation.js.map +1 -1
- package/lib/core/transform/validation/captureUniversalHostInputValidation.mjs +12 -4
- package/lib/core/transform/validation/captureUniversalHostInputValidation.mjs.map +1 -1
- package/lib/core/transform/validation/matchesCachedSource.d.cts +9 -2
- package/lib/core/transform/validation/matchesCachedSource.d.mts +9 -2
- package/lib/core/transform/validation/matchesCachedSource.d.ts +9 -2
- package/lib/core/transform/validation/matchesCachedSource.js +11 -3
- package/lib/core/transform/validation/matchesCachedSource.js.map +1 -1
- package/lib/core/transform/validation/matchesCachedSource.mjs +11 -3
- package/lib/core/transform/validation/matchesCachedSource.mjs.map +1 -1
- package/lib/core/transform/watch/TtscTransformHooks.d.cts +9 -0
- package/lib/core/transform/watch/TtscTransformHooks.d.mts +9 -0
- package/lib/core/transform/watch/TtscTransformHooks.d.ts +9 -0
- 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/lib/core/unplugin.js +14 -0
- package/lib/core/unplugin.js.map +1 -1
- package/lib/core/unplugin.mjs +14 -0
- package/lib/core/unplugin.mjs.map +1 -1
- package/lib/core/vite/installViteDependencyScanPlugins.d.cts +46 -0
- package/lib/core/vite/installViteDependencyScanPlugins.d.mts +46 -0
- package/lib/core/vite/installViteDependencyScanPlugins.d.ts +46 -0
- package/lib/core/vite/installViteDependencyScanPlugins.js +186 -0
- package/lib/core/vite/installViteDependencyScanPlugins.js.map +1 -0
- package/lib/core/vite/installViteDependencyScanPlugins.mjs +184 -0
- package/lib/core/vite/installViteDependencyScanPlugins.mjs.map +1 -0
- package/package.json +5 -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/options/ResolvedTtscUnpluginOptions.ts +3 -0
- package/src/core/options/TtscUnpluginOptions.ts +13 -2
- package/src/core/options/resolveOptions.ts +6 -3
- package/src/core/transform/TtscPrecompilation.ts +103 -0
- package/src/core/transform/cache/selectCachedGenerationAction.ts +3 -0
- package/src/core/transform/cache/withdrawTtscTransformGenerations.ts +2 -0
- 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 +22 -2
- package/src/core/transform/generation/selectPersistentHostInputs.ts +5 -1
- package/src/core/transform/generation/transformProject.ts +3 -0
- 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 +86 -37
- package/src/core/transform/validation/captureUniversalHostInputValidation.ts +12 -4
- package/src/core/transform/validation/matchesCachedSource.ts +9 -2
- package/src/core/transform/watch/TtscTransformHooks.ts +10 -0
- 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
- package/src/core/unplugin.ts +32 -0
- package/src/core/vite/installViteDependencyScanPlugins.ts +219 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
|
|
3
3
|
import type { ResolvedTtscUnpluginOptions } from "../options/ResolvedTtscUnpluginOptions";
|
|
4
|
+
import { TtscPrecompilation } from "./TtscPrecompilation";
|
|
4
5
|
import type { TtscTransformResult } from "./TtscTransformResult";
|
|
5
6
|
import { createAliasPaths } from "./alias/createAliasPaths";
|
|
6
7
|
import { TERMINAL_TRANSFORM_GENERATIONS } from "./cache/TERMINAL_TRANSFORM_GENERATIONS";
|
|
@@ -33,6 +34,7 @@ import type { TtscTransformHooks } from "./watch/TtscTransformHooks";
|
|
|
33
34
|
import type { TtscWatchSelection } from "./watch/TtscWatchSelection";
|
|
34
35
|
import { notifyRejectedGenerationInputs } from "./watch/notifyRejectedGenerationInputs";
|
|
35
36
|
import { prepareProjectRecordDirectories } from "./watch/prepareProjectRecordDirectories";
|
|
37
|
+
import { recordedDependencyWitnesses } from "./watch/recordedDependencyWitnesses";
|
|
36
38
|
|
|
37
39
|
/**
|
|
38
40
|
* Apply the ttsc plugin transform to a single source file.
|
|
@@ -67,38 +69,40 @@ import { prepareProjectRecordDirectories } from "./watch/prepareProjectRecordDir
|
|
|
67
69
|
* @param hooks - Optional adapter callbacks; see {@link TtscTransformHooks}.
|
|
68
70
|
* Dependency notifications fire on cache hits too; watch registrations are
|
|
69
71
|
* per build, not per compilation.
|
|
70
|
-
* @evidence contracts/common.md#principled-implementation Project selection and generation-qualified
|
|
71
|
-
* @evidence contracts/common.md#clear-and-simple-design One
|
|
72
|
-
* @evidence contracts/common.md#prohibited-implementation-shortcuts Wrapper modules cannot poison source baselines
|
|
73
|
-
* @evidence contracts/common.md#meaningful-documentation Native paragraphs and argument tags explain project scope, no-transform outcomes, cache epochs and per-build
|
|
74
|
-
* @evidence contracts/performance.md#efficient-algorithms
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* In-flight/valid completed reuse avoids compilation, not those checks or
|
|
79
|
-
* output/map/notification/record work. Capture misses pay whole native compile
|
|
80
|
-
* and input populations. The common proof owner skips redundant environment
|
|
81
|
-
* preparation for proven first deliveries and shares synchronous native proof
|
|
82
|
-
* queries; persistent/repeated delivery establishes fresh authority. Concurrent supersession can repeat the outer loop
|
|
83
|
-
* without a delivery-level retry/time bound here.
|
|
84
|
-
* @evidence contracts/performance.md#reuse-equivalent-work Cache identity covers config/options/plugins/aliases; current generations, pass-qualified terminal verdicts and in-flight Promises are shared only while their source and dependency proof remains valid.
|
|
85
|
-
* @evidence contracts/performance.md#bound-retention-and-release-resources
|
|
86
|
-
* Optional cache state retains current generation Promises/results and
|
|
87
|
-
* per-key dependency/case facts without a byte/key cap here. Native tasks
|
|
88
|
-
* belong to compiler/capture owners; uncached captures retain no notification
|
|
89
|
-
* or persistent clock probe. Fresh-only delivery releases capture resources,
|
|
90
|
-
* retaining only an explicitly admitted local pass result; rejected or failed
|
|
91
|
-
* incomplete handoff detaches its generation. Eviction/disposal attempt independent resource release
|
|
92
|
-
* and native failures need not close every handle or remove every probe.
|
|
93
|
-
* @evidence contracts/portability.md#os-neutral-implementation Native module paths and project coordinates use supported path/filesystem abstractions, while actual case policy and watcher capability come from generation proof rather than OS-name assumptions.
|
|
72
|
+
* @evidence contracts/common.md#principled-implementation Project selection and generation-qualified admission preserve compiler disk authority; preparation shares selection, keys, capture and input proofs with delivery, while host effects and first-delivery permission remain exclusive to actual delivery. Fresh-only success still requires an explicit nonwatching lifecycle, coherent project declaration and supported host-cache withdrawal because incomplete observation cannot establish watch invalidation.
|
|
73
|
+
* @evidence contracts/common.md#clear-and-simple-design One coordinator mode shares project selection, admission, compilation and output selection between preparation and delivery; dedicated owners retain proof and lifetime internals, and delivery alone performs host notification.
|
|
74
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Wrapper modules cannot poison source baselines. Preparation skips handoff rather than postcompile proof, and superseded preparation stops without reviving withdrawn generations. Incomplete local results share only explicitly nonwatching first deliveries in their exact pass; unknown/watching lifecycles or unsupported withdrawal reject and evict without invented persistent records or dependency closure.
|
|
75
|
+
* @evidence contracts/common.md#meaningful-documentation Native paragraphs and argument tags explain project scope, no-transform outcomes, cache epochs and per-build notifications; coordinator prose identifies delivery-only effects and postpreparation admission, with maintained invalidation reference context.
|
|
76
|
+
* @evidence contracts/performance.md#efficient-algorithms Selection and keys pay ancestor/config/alias/option/path-text work. Each iteration may prepare toolchains, settle notifications and replay source/project/external/universal proofs; reuse avoids compilation rather than those checks or output/map/notification/record work. Misses pay native compilation and input populations. Proven first deliveries skip redundant environment preparation and share synchronous proof queries; repeated delivery establishes fresh authority. Startup schedules explicit entries concurrently and skips delivery output/map/registration work. Supersession can repeat the outer loop without a retry or time bound.
|
|
77
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Config/options/plugins/aliases key the ordinary project Promise shared by preparation, simultaneous loads and sibling entries; completed generations, pass-qualified terminal verdicts and in-flight work remain reusable only under current source and dependency proof.
|
|
78
|
+
* @evidence contracts/performance.md#bound-retention-and-release-resources Optional cache state retains generation Promises/results and per-key dependency/case facts without a byte/key cap. Native tasks belong to compiler/capture owners; uncached captures retain no notification or persistent clock probe. Fresh-only delivery releases capture resources while retaining an admitted local pass result; failed or rejected incomplete handoff detaches its generation. Superseded preparation preserves the new owner, and withdrawal schedules disposal of its pending fulfilled result. Eviction/disposal attempt independent release; native failure need not close every handle or remove every probe.
|
|
79
|
+
* @evidence contracts/portability.md#os-neutral-implementation Preparation and delivery use the same native project selection, path identity and cache-owned filesystem boundaries, with exact startup entry paths. Generation proof supplies case and watcher policy rather than OS-name assumptions.
|
|
94
80
|
*/
|
|
95
|
-
export
|
|
81
|
+
export function transformTtsc(
|
|
96
82
|
id: string,
|
|
97
83
|
source: string,
|
|
98
84
|
options: ResolvedTtscUnpluginOptions,
|
|
99
85
|
aliases?: unknown,
|
|
100
86
|
cache?: TtscTransformCache,
|
|
101
87
|
hooks?: TtscTransformHooks,
|
|
88
|
+
): Promise<TtscTransformResult | undefined> {
|
|
89
|
+
return runTransformTtsc(id, source, options, aliases, cache, hooks, false);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Coordinate capture and actual delivery through the same project cache.
|
|
94
|
+
* Preparation stops before handoff: it cannot mark a module served, publish a
|
|
95
|
+
* host record, acknowledge volatility or emit module diagnostics. A prepared
|
|
96
|
+
* generation must still pass ordinary admission when the host requests it.
|
|
97
|
+
*/
|
|
98
|
+
async function runTransformTtsc(
|
|
99
|
+
id: string,
|
|
100
|
+
source: string,
|
|
101
|
+
options: ResolvedTtscUnpluginOptions,
|
|
102
|
+
aliases: unknown,
|
|
103
|
+
cache: TtscTransformCache | undefined,
|
|
104
|
+
hooks: TtscTransformHooks | undefined,
|
|
105
|
+
preparing: boolean,
|
|
102
106
|
): Promise<TtscTransformResult | undefined> {
|
|
103
107
|
const filesystem = transformFilesystem(cache);
|
|
104
108
|
const exact = hooks?.exactPath === true;
|
|
@@ -125,7 +129,10 @@ export async function transformTtsc(
|
|
|
125
129
|
// Writing the delivered record must not create a new member of that proof.
|
|
126
130
|
prepareProjectRecordDirectories(hooks?.project);
|
|
127
131
|
|
|
128
|
-
const selection =
|
|
132
|
+
const selection =
|
|
133
|
+
hooks?.projectSelection === undefined
|
|
134
|
+
? resolveProjectSelection(file, options.project, filesystem)
|
|
135
|
+
: { tsconfig: path.resolve(hooks.projectSelection), consulted: [] };
|
|
129
136
|
const tsconfig = selection.tsconfig;
|
|
130
137
|
const selectedProjectRoot = path.resolve(
|
|
131
138
|
options.projectRoot ?? path.dirname(tsconfig),
|
|
@@ -142,6 +149,19 @@ export async function transformTtsc(
|
|
|
142
149
|
tsconfig,
|
|
143
150
|
};
|
|
144
151
|
const aliasPaths = createAliasPaths(aliases);
|
|
152
|
+
if (!preparing && cache !== undefined) {
|
|
153
|
+
TtscPrecompilation.start(cache, options, aliasPaths, (entry, text) =>
|
|
154
|
+
runTransformTtsc(
|
|
155
|
+
entry,
|
|
156
|
+
text,
|
|
157
|
+
options,
|
|
158
|
+
aliases,
|
|
159
|
+
cache,
|
|
160
|
+
{ ...hooks, exactPath: true, projectSelection: undefined },
|
|
161
|
+
true,
|
|
162
|
+
),
|
|
163
|
+
);
|
|
164
|
+
}
|
|
145
165
|
const key = createTransformCacheKey({
|
|
146
166
|
aliasPaths,
|
|
147
167
|
compilerOptions: options.compilerOptions,
|
|
@@ -168,7 +188,10 @@ export async function transformTtsc(
|
|
|
168
188
|
undefined,
|
|
169
189
|
terminal.validation.cached.projectRoot,
|
|
170
190
|
);
|
|
171
|
-
if (cache?.get(key) !== transformed)
|
|
191
|
+
if (cache?.get(key) !== transformed) {
|
|
192
|
+
if (preparing) return undefined;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
172
195
|
}
|
|
173
196
|
// A terminal verdict is an answer about one observed environment, not an
|
|
174
197
|
// invitation for every later module to repeat the whole compile.
|
|
@@ -179,7 +202,13 @@ export async function transformTtsc(
|
|
|
179
202
|
filesystem,
|
|
180
203
|
})
|
|
181
204
|
) {
|
|
182
|
-
|
|
205
|
+
if (!preparing)
|
|
206
|
+
notifyRejectedGenerationInputs(
|
|
207
|
+
hooks,
|
|
208
|
+
terminal,
|
|
209
|
+
file,
|
|
210
|
+
watchSelection,
|
|
211
|
+
);
|
|
183
212
|
throw terminal;
|
|
184
213
|
}
|
|
185
214
|
evictGeneration(cache, key, transformed);
|
|
@@ -192,12 +221,13 @@ export async function transformTtsc(
|
|
|
192
221
|
if (transformed !== undefined) {
|
|
193
222
|
const cached = await awaitOrEvict(cache, key, transformed).catch(
|
|
194
223
|
(rejection: unknown) => {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
224
|
+
if (!preparing)
|
|
225
|
+
notifyRejectedGenerationInputs(
|
|
226
|
+
hooks,
|
|
227
|
+
rejection,
|
|
228
|
+
file,
|
|
229
|
+
watchSelection,
|
|
230
|
+
);
|
|
201
231
|
throw rejection;
|
|
202
232
|
},
|
|
203
233
|
);
|
|
@@ -205,6 +235,7 @@ export async function transformTtsc(
|
|
|
205
235
|
// While this caller awaited the old Promise, another caller may have
|
|
206
236
|
// invalidated it and installed a newer authoritative generation.
|
|
207
237
|
if (cache?.get(key) !== transformed) {
|
|
238
|
+
if (preparing) return undefined;
|
|
208
239
|
continue;
|
|
209
240
|
}
|
|
210
241
|
// A generation captured while native notifications were trusted keeps
|
|
@@ -217,11 +248,15 @@ export async function transformTtsc(
|
|
|
217
248
|
if (epoch === undefined) {
|
|
218
249
|
await settleProjectMutationEvents(cached);
|
|
219
250
|
if (cache?.get(key) !== transformed) {
|
|
251
|
+
if (preparing) return undefined;
|
|
220
252
|
continue;
|
|
221
253
|
}
|
|
222
254
|
}
|
|
223
255
|
await TtscGenerationProof.prepare(cached, file, epoch);
|
|
224
|
-
if (cache?.get(key) !== transformed)
|
|
256
|
+
if (cache?.get(key) !== transformed) {
|
|
257
|
+
if (preparing) return undefined;
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
225
260
|
// No await between this observation and synchronous admission.
|
|
226
261
|
const proof = TtscGenerationProof.create(cached, file, epoch);
|
|
227
262
|
const action = selectCachedGenerationAction({
|
|
@@ -233,11 +268,13 @@ export async function transformTtsc(
|
|
|
233
268
|
generation: transformed,
|
|
234
269
|
key,
|
|
235
270
|
source,
|
|
271
|
+
reportDivergence: !preparing,
|
|
236
272
|
});
|
|
237
273
|
if (action === "retry") {
|
|
238
274
|
continue;
|
|
239
275
|
}
|
|
240
276
|
if (action === "serve") {
|
|
277
|
+
if (preparing) return undefined;
|
|
241
278
|
return deliverCachedTransform({
|
|
242
279
|
cache,
|
|
243
280
|
cached,
|
|
@@ -260,6 +297,7 @@ export async function transformTtsc(
|
|
|
260
297
|
projectRoot: selectedProjectRoot,
|
|
261
298
|
currentFile: file,
|
|
262
299
|
currentSource: source,
|
|
300
|
+
reportDivergence: !preparing,
|
|
263
301
|
// Stamp the pass this compile was started for, not the one it happens
|
|
264
302
|
// to finish in: a boundary crossed mid-compile leaves the generation
|
|
265
303
|
// belonging to the earlier pass, so the next pass re-proves it.
|
|
@@ -282,21 +320,31 @@ export async function transformTtsc(
|
|
|
282
320
|
cache === undefined
|
|
283
321
|
? undefined
|
|
284
322
|
: TRANSFORM_CACHE_CASE_POLICIES.get(cache)?.get(key),
|
|
323
|
+
// A cache without a list of its own takes the names the project's
|
|
324
|
+
// record carries from an earlier process (samchon/ttsc#1743).
|
|
285
325
|
witnessedDependencies:
|
|
286
326
|
cache === undefined
|
|
287
327
|
? undefined
|
|
288
|
-
: TRANSFORM_CACHE_DEPENDENCY_WITNESSES.get(cache)?.get(key)
|
|
328
|
+
: (TRANSFORM_CACHE_DEPENDENCY_WITNESSES.get(cache)?.get(key) ??
|
|
329
|
+
recordedDependencyWitnesses(hooks?.project, tsconfig)),
|
|
289
330
|
});
|
|
290
331
|
cache?.set(key, transformed);
|
|
291
332
|
}
|
|
292
333
|
const generation = transformed;
|
|
293
334
|
const cached = await awaitOrEvict(cache, key, generation).catch(
|
|
294
335
|
(rejection: unknown) => {
|
|
295
|
-
|
|
336
|
+
if (!preparing)
|
|
337
|
+
notifyRejectedGenerationInputs(
|
|
338
|
+
hooks,
|
|
339
|
+
rejection,
|
|
340
|
+
file,
|
|
341
|
+
watchSelection,
|
|
342
|
+
);
|
|
296
343
|
throw rejection;
|
|
297
344
|
},
|
|
298
345
|
);
|
|
299
346
|
if (cache !== undefined && cache.get(key) !== generation) {
|
|
347
|
+
if (preparing) return undefined;
|
|
300
348
|
continue;
|
|
301
349
|
}
|
|
302
350
|
if (cache !== undefined) {
|
|
@@ -316,6 +364,7 @@ export async function transformTtsc(
|
|
|
316
364
|
policies.set(key, reported);
|
|
317
365
|
}
|
|
318
366
|
}
|
|
367
|
+
if (preparing) return undefined;
|
|
319
368
|
return deliverCachedTransform({
|
|
320
369
|
cache,
|
|
321
370
|
cached,
|
|
@@ -42,7 +42,7 @@ import { matchesRecordedInput } from "./matchesRecordedInput";
|
|
|
42
42
|
* @evidence contracts/common.md#meaningful-documentation Native prose explains failed admission and successful generation attachment; inline comments justify readable-state, blocker and tree distinctions.
|
|
43
43
|
* @evidence contracts/portability.md#os-neutral-implementation The generation's filesystem view qualifies metadata and exact native absence. Grouped candidates retain original spelling because directory case policy alone does not define Unicode or short-name equivalence; their joined path follows that view's platform dialect. Physical targets and aliases remain distinct from content identity, and native plugin environment authority is not established by arbitrary filesystem injection.
|
|
44
44
|
* @evidence contracts/performance.md#bound-retention-and-release-resources The generation retains manifest entries, lexical coverage, raw missing candidates and tree environments proportional to admitted inputs and their path/state text, without a total byte cap or native handle here. Failed attempt records are call-local and diagnostic witness counts are bounded by their owner; replacing or releasing the generation ends manifest ownership.
|
|
45
|
-
* @evidence contracts/performance.md#efficient-algorithms Input selection materializes the union of producer lists/proof keys and scans U universal inputs and T plugin source trees. Comparisons include content bytes, physical identity/ancestor/case queries, paired metadata and exact candidate stat; source proof includes tree population/bytes and environment validation. These delegated costs and temporary input/manifest populations are not constant-time map insertion work.
|
|
45
|
+
* @evidence contracts/performance.md#efficient-algorithms Input selection materializes the union of producer lists/proof keys and scans U universal inputs and T plugin source trees. Async-owned environments share one synchronous batch, qualifying common SDK paths once across plugin directories. Comparisons include content bytes, physical identity/ancestor/case queries, paired metadata and exact candidate stat; source proof includes tree population/bytes and environment validation. These delegated costs and temporary input/manifest populations are not constant-time map insertion work.
|
|
46
46
|
* @evidence contracts/performance.md#reuse-equivalent-work This shared generation manifest records exactly qualified lexical spellings, separable signatures and tree environments for later validators; changed proof requires new admission.
|
|
47
47
|
*/
|
|
48
48
|
export function captureUniversalHostInputValidation(
|
|
@@ -295,13 +295,21 @@ export function captureUniversalHostInputValidation(
|
|
|
295
295
|
// A plugin binary keyed on a source other than the disk's now, whether it
|
|
296
296
|
// was built here or adopted from another worker, is output for a state
|
|
297
297
|
// already gone (samchon/ttsc#1487).
|
|
298
|
-
|
|
298
|
+
const sources = selectPluginSourceInputs(cached.result);
|
|
299
|
+
const prepared = usesPreparedPluginBuildEnvironments(cached.result);
|
|
300
|
+
// Plugin directories commonly share the thousands-file Go SDK. Qualify it
|
|
301
|
+
// once for this synchronous proof, not once per directory (#1764). The map
|
|
302
|
+
// must stay inside this call: an await or later delivery needs fresh native
|
|
303
|
+
// authority, even when source watchers heard no change (#1712, #1516).
|
|
304
|
+
const environments = prepared
|
|
305
|
+
? PluginBuildEnvironmentReadings.cachedAll(sources.keys())
|
|
306
|
+
: undefined;
|
|
307
|
+
for (const [directory, digest] of sources) {
|
|
299
308
|
// The environment is recorded as read before the proof, so it is never a
|
|
300
309
|
// reading the proof did not see; one that moved meanwhile only makes the
|
|
301
310
|
// next delivery prove the tree again.
|
|
302
|
-
const prepared = usesPreparedPluginBuildEnvironments(cached.result);
|
|
303
311
|
const environment = prepared
|
|
304
|
-
?
|
|
312
|
+
? environments!.get(directory)
|
|
305
313
|
: processPluginBuildEnvironment(directory, false, cached.projectRoot);
|
|
306
314
|
if (
|
|
307
315
|
environment === undefined ||
|
|
@@ -37,7 +37,9 @@ import { notificationsProveProgramUnchanged } from "./notificationsProveProgramU
|
|
|
37
37
|
* rejects this generation for the delivery; its caller chooses replacement or
|
|
38
38
|
* capture. Delivered text that differs while the disk still holds the bytes the
|
|
39
39
|
* generation compiled is not one: it is reported and served, since the compile
|
|
40
|
-
* read the disk (samchon/ttsc#1394).
|
|
40
|
+
* read the disk (samchon/ttsc#1394). Preparation performs the same comparison
|
|
41
|
+
* without reporting a host rewrite, because its native source read is not a
|
|
42
|
+
* delivered module.
|
|
41
43
|
*
|
|
42
44
|
* Its place in the adapter's invalidation model, and the units beside it, are
|
|
43
45
|
* mapped in the maintainer page
|
|
@@ -73,6 +75,11 @@ export function matchesCachedSource(
|
|
|
73
75
|
/** Current host pass, or undefined for persistent input validation. */
|
|
74
76
|
epoch: number | undefined,
|
|
75
77
|
proof?: TtscGenerationProof.Transaction,
|
|
78
|
+
/**
|
|
79
|
+
* Preparation compares the same native bytes without reporting a host
|
|
80
|
+
* rewrite.
|
|
81
|
+
*/
|
|
82
|
+
reportDivergence = true,
|
|
76
83
|
): boolean {
|
|
77
84
|
if (!nativeInputPredicatesHold(cached, proof)) return false;
|
|
78
85
|
const pass = TtscGenerationProof.sharesPass(cached, file, epoch);
|
|
@@ -133,7 +140,7 @@ export function matchesCachedSource(
|
|
|
133
140
|
) {
|
|
134
141
|
return false;
|
|
135
142
|
}
|
|
136
|
-
reportDivergentDelivery(cached, file);
|
|
143
|
+
if (reportDivergence) reportDivergentDelivery(cached, file);
|
|
137
144
|
}
|
|
138
145
|
if (pass) return true;
|
|
139
146
|
if (epoch !== undefined && cached.projectSnapshotComplete === true) {
|
|
@@ -30,6 +30,16 @@ import type { TtscWatchInputEvidence } from "./TtscWatchInputEvidence";
|
|
|
30
30
|
* state at runtime.
|
|
31
31
|
*/
|
|
32
32
|
export interface TtscTransformHooks {
|
|
33
|
+
/**
|
|
34
|
+
* Native config already selected by the host for this delivered module.
|
|
35
|
+
*
|
|
36
|
+
* A host that freezes routing and its discovery inputs in one transaction
|
|
37
|
+
* supplies that config here and retains those inputs in its watch channel.
|
|
38
|
+
* Startup entries select their own projects from the user's
|
|
39
|
+
* `options.project`, independently of another module's discovered route.
|
|
40
|
+
*/
|
|
41
|
+
projectSelection?: string;
|
|
42
|
+
|
|
33
43
|
/**
|
|
34
44
|
* Invoked once per absolute watch-input path derived for the transformed file
|
|
35
45
|
* `F`: the plugin-reported `dependencies[F]` list unioned with the host-owned
|
|
@@ -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
|
package/src/core/unplugin.ts
CHANGED
|
@@ -42,6 +42,7 @@ import type { TtscProjectRegistration } from "./transform/watch/TtscProjectRegis
|
|
|
42
42
|
import { createViteBuildLifecycle } from "./vite/createViteBuildLifecycle";
|
|
43
43
|
import { createViteServeInputWatch } from "./vite/createViteServeInputWatch";
|
|
44
44
|
import { createViteServeWatchHooks } from "./vite/createViteServeWatchHooks";
|
|
45
|
+
import { installViteDependencyScanPlugins } from "./vite/installViteDependencyScanPlugins";
|
|
45
46
|
import { TTSC_SOURCE_MAP_STASH } from "./webpack/TTSC_SOURCE_MAP_STASH";
|
|
46
47
|
import { registerTtscSourceMapLoader } from "./webpack/registerTtscSourceMapLoader";
|
|
47
48
|
import { reportCompiledProjectRecords } from "./webpack/reportCompiledProjectRecords";
|
|
@@ -253,6 +254,37 @@ const unpluginFactory: UnpluginFactory<
|
|
|
253
254
|
transformCache,
|
|
254
255
|
hostDeclaresPolling(process.env, viteLifecycle.usePolling),
|
|
255
256
|
);
|
|
257
|
+
installViteDependencyScanPlugins(
|
|
258
|
+
config,
|
|
259
|
+
isTransformTarget,
|
|
260
|
+
(source, file) => {
|
|
261
|
+
const startedAt = viteLifecycle.watching
|
|
262
|
+
? serveInputs.begin()
|
|
263
|
+
: undefined;
|
|
264
|
+
return transformTtsc(
|
|
265
|
+
file,
|
|
266
|
+
source,
|
|
267
|
+
options,
|
|
268
|
+
aliases,
|
|
269
|
+
transformCache,
|
|
270
|
+
{
|
|
271
|
+
exactPath: true,
|
|
272
|
+
watching: viteLifecycle.watching,
|
|
273
|
+
...createViteServeWatchHooks(
|
|
274
|
+
"serve",
|
|
275
|
+
viteLifecycle.watching,
|
|
276
|
+
serveInputs,
|
|
277
|
+
file,
|
|
278
|
+
startedAt,
|
|
279
|
+
),
|
|
280
|
+
},
|
|
281
|
+
);
|
|
282
|
+
},
|
|
283
|
+
(this?.meta as { rolldownVersion?: string } | undefined)
|
|
284
|
+
?.rolldownVersion === undefined
|
|
285
|
+
? "esbuild"
|
|
286
|
+
: "rolldown",
|
|
287
|
+
);
|
|
256
288
|
},
|
|
257
289
|
// Compiler dependencies belong to the filesystem watch graph. Vite's
|
|
258
290
|
// transform-context addWatchFile also inserts runtime imports, so none
|