@ttsc/unplugin 0.28.2 → 0.28.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -312,7 +312,9 @@ The transform host reports the program's reference graph (the transform envelope
312
312
 
313
313
  Transform plugins may additionally report, per file, the source files they consulted (the envelope's `dependencies` field); the adapter registers those as watch files too, union semantics. A plugin that declares such a list [complete](https://ttsc.dev/docs/development/concepts/protocol#dependency-completeness) for a file narrows the registration instead: only its own list plus the tsconfig chain, so files the transform never consulted stop invalidating it. The JavaScript host also reports the descriptor's loaded CommonJS graph, every package manifest inspected by auto-discovery, and plugin-declared `hostInputs`. First-party plugins use that last field for implicit config discovery and evaluated config dependencies. These remain universal without turning arbitrary project assets into configuration. Files a plugin declares `volatile` (output depending on non-file inputs such as environment or time) bypass the adapter's transform cache and are marked uncacheable where the bundler exposes that control.
314
314
 
315
- The transform cache snapshots every regular file reached by the non-following project walk plus graph-reported inputs outside that walk (`node_modules` declarations, monorepo sibling sources, files reached through symlinks or Windows junctions, and out-of-root `extends` ancestry). One whole-project compile already contains every module's output. Adapters with a guaranteed build boundary clear the previous generation there, then check only the supplied source on each module's first delivery from a complete generation in that build. An incomplete generation never takes that shortcut. Later deliveries of a graph-bearing generation validate that file's reference closure, globals, configs, resolution candidates, plugin dependencies, and exact host inputs. Every input a generation has already proven carries the nanosecond metadata signature captured around the read that proved it, so a later delivery that finds the signature unchanged reuses that proof instead of re-reading the bytes; any signature change falls back to the full content comparison. A signature is recorded only for a read nothing raced, only for an input whose recorded state came from bytes that were read, since the metadata of a path nothing could read holds still while the bytes behind it appear, and only once the observed filesystem's own clock has provably left the tick that minted the input's modification stamp. A filesystem stamps writes once per clock tick, so a same-length rewrite landing inside the recorded stamp's tick would leave the signature unchanged; until some stamp the same filesystem minted later separates that tick, the content comparison keeps running, and the signature is re-earned the moment it can be. The reference instants come from the filesystem itself, never from the process clock: every stamp the adapter observes raises a floor kept per reporting device, and the adapter also stamps a probe in its own scratch directory (the way git separates racily-clean index entries with the index file's own timestamp) to cover a tree whose files were all written inside one tick. The probe counts only when the scratch volume is the inputs' volume, so on a split-volume layout the observed stamps carry the rule alone; an input they cannot separate is re-read rather than trusted. Both sides of every comparison are therefore stamps of equal granularity minted by one clock, so a filesystem clock running behind the host changes nothing. The floor is a maximum over stamps it merely observed, so what defeats it is a stamp that was set into the future rather than minted, such as a stamp-preserving extraction or copy from a machine whose clock ran ahead. A restored past stamp is harmless, since it never raises the floor. A clock that jumps backwards strands the floor above the present the same way, which is a different hazard from a clock running at a constant offset: an offset moves both stamps being compared and changes nothing, while a jump moves only the present. No stamp-based freshness proof survives either one. Sibling modules therefore share one proof of the closure and the globals rather than repeating it per module. Generation-scoped directory notifications detect new, removed, or renamed project inputs without repeating a directory-stat pass per module; Windows isolates those notifications so deletion of a watched temporary tree cannot crash the host. An absent resolution candidate is the one input a metadata signature cannot stand for, since a path that is not there has no metadata to compare. The generation therefore registers those names with a watcher of their own, along with the directory components of the spelling that lead to them, down to the project's own root, and a delivery reads the notification instead of re-probing each candidate. That makes the notification the sole positive evidence for this one input class, which is why the registration reaches past the candidate itself: a watcher opened on a path that traverses a link follows it, so retargeting the link would otherwise move the answer without disturbing what is watched, and a package link inside `node_modules` is exactly that. It stops at the project root, and a candidate whose spelling leaves the project subtree before reaching it is not claimed at all: above that line the components are the machine's own layout rather than the project's, which nobody retargets and which changes for reasons no generation should hear about. It listens for renames alone, since every event that can change a candidate's answer is one — the file appearing, a component being created, replaced or retargeted — while the directories carrying them have their attributes moved by anything written below. A candidate whose watch could not be opened, whose watcher has since failed, or that belongs to a set spanning more directories than the generation will watch, is probed exactly as before: a host that runs out of watch descriptors would fail the tracker outright, which costs every delivery a whole-project comparison rather than one probe. What none of that covers is a filesystem that accepts a watch and then reports nothing, which some network mounts do; that is the same assumption the project-membership proof beside it already rests on, though a wider one here: the project walk skips `node_modules`, so a candidate under it was never covered by that proof and kept a notification-independent probe until now. A project on such a mount should be treated as one where notifications do not work rather than one where they merely have not fired. The barrier that lets a synchronous edit reach those watchers before a delivery reads their verdict is the watcher's own acknowledgement rather than a fixed wait: an in-process watcher answers on the next turn of the loop its callbacks are queued on, and the Windows broker answers by an ordered round-trip, so a delivery waits for the crossing instead of guessing at it. The project is snapshotted before and after compilation, while every graph member carries the compiler filesystem's content and physical-identity proof; only a complete generation that still matches both may authorize narrow reuse. This also rejects an in-project or external A→B→A change whose restored post-compile bytes would otherwise hide the transient state used by the compiler. `dependenciesComplete` narrows file inputs by the same contract as watch registration, and a project reaches it without a type-driven plugin: ttsc's own transform lanes print syntactically, so the host declares every file complete when no plugin can contribute to it, and the first-party `@ttsc/banner` and `@ttsc/strip` declare their own contribution the same way. Such a delivery validates the universal inputs and the file itself instead of its reference closure. A narrowed file's diagnostics narrow with it: an edit to a file the declaration dropped no longer re-runs the compile, so a type error introduced there surfaces at the next compile the build runs for another reason rather than at the edit. Run the compiler's own check beside the bundler when you want it at the edit. Envelopes without a graph, and generations whose watchers could not be opened or have since failed, retain complete-snapshot validation: losing a notification is the absence of a membership proof rather than evidence of a change, so such a generation keeps validating against its own recorded state (the directory snapshot, the input hashes, and the universal descriptor inputs whose every rejection is evidence of a change rather than an inability to prove one) instead of being discarded. A reported membership event is evidence, and still replaces the generation. Only an unstable or incomplete generation is refused outright. Bun runtime setup defines one process-scoped loading session. A dev server started without a watcher takes the build-scoped lifecycle instead of persistent validation. `server.watch: null` leaves the session no channel through which a file change could ever reach it, so what per-delivery validation buys there is incoherence rather than freshness: modules delivered before an edit and after it would come from two different compilations of one program. Each module's first delivery in such a session is therefore settled against the generation the session started from, exactly as under a build, while a module the session already delivered keeps revalidating on its next request. Long-lived hosts without either boundary (Metro workers, the Turbopack loader, and a watching Vite development server, whose initial `buildStart` spans later HMR edits) apply the file-specific validation on every generation hit.
315
+ The transform cache snapshots every regular file reached by the non-following project walk plus graph-reported inputs outside that walk (`node_modules` declarations, monorepo sibling sources, files reached through symlinks or Windows junctions, and out-of-root `extends` ancestry). One whole-project compile already contains every module's output. Adapters with a guaranteed build boundary clear the previous generation there, then check only the supplied source on each module's first delivery from a complete generation in that build. An incomplete generation never takes that shortcut. Later deliveries of a graph-bearing generation validate that file's reference closure, globals, configs, resolution candidates, plugin dependencies, and exact host inputs. Every input a generation has already proven carries the nanosecond metadata signature captured around the read that proved it, so a later delivery that finds the signature unchanged reuses that proof instead of re-reading the bytes; any signature change falls back to the full content comparison. A signature is recorded only for a read nothing raced, only for an input whose recorded state came from bytes that were read, since the metadata of a path nothing could read holds still while the bytes behind it appear, and only once the observed filesystem's own clock has provably left the tick that minted the input's modification stamp. A filesystem stamps writes once per clock tick, so a same-length rewrite landing inside the recorded stamp's tick would leave the signature unchanged; until some stamp the same filesystem minted later separates that tick, the content comparison keeps running, and the signature is re-earned the moment it can be. The reference instants come from the filesystem itself, never from the process clock: every stamp the adapter observes raises a floor kept per reporting device, and the adapter also stamps a probe in its own scratch directory (the way git separates racily-clean index entries with the index file's own timestamp) to cover a tree whose files were all written inside one tick. The probe counts only when the scratch volume is the inputs' volume, so on a split-volume layout the observed stamps carry the rule alone; an input they cannot separate is re-read rather than trusted. Both sides of every comparison are therefore stamps of equal granularity minted by one clock, so a filesystem clock running behind the host changes nothing. The floor is a maximum over stamps it merely observed, so what defeats it is a stamp that was set into the future rather than minted, such as a stamp-preserving extraction or copy from a machine whose clock ran ahead. A restored past stamp is harmless, since it never raises the floor. A clock that jumps backwards strands the floor above the present the same way, which is a different hazard from a clock running at a constant offset: an offset moves both stamps being compared and changes nothing, while a jump moves only the present. No stamp-based freshness proof survives either one. Sibling modules therefore share one proof of the closure and the globals rather than repeating it per module. Generation-scoped directory notifications detect new, removed, or renamed project inputs without repeating a directory-stat pass per module; Windows isolates those notifications so deletion of a watched temporary tree cannot crash the host. An absent resolution candidate is the one input a metadata signature cannot stand for, since a path that is not there has no metadata to compare. The generation therefore registers those names with a watcher of their own, along with the directory components of the spelling that lead to them, down to the project's own root, and a delivery reads the notification instead of re-probing each candidate. That makes the notification the sole positive evidence for this one input class, which is why the registration reaches past the candidate itself: a watcher opened on a path that traverses a link follows it, so retargeting the link would otherwise move the answer without disturbing what is watched, and a package link inside `node_modules` is exactly that. It stops at the project root, and a candidate whose spelling leaves the project subtree before reaching it is not claimed at all: above that line the components are the machine's own layout rather than the project's, which nobody retargets and which changes for reasons no generation should hear about. It listens for renames alone, since every event that can change a candidate's answer is one — the file appearing, a component being created, replaced or retargeted — while the directories carrying them have their attributes moved by anything written below. A candidate whose watch could not be opened, whose watcher has since failed, or that belongs to a set spanning more directories than the generation will watch, is probed exactly as before: a host that runs out of watch descriptors would fail the tracker outright, which costs every delivery a whole-project comparison rather than one probe. What none of that covers is a filesystem that accepts a watch and then reports nothing, which some network mounts do; that is the same assumption the project-membership proof beside it already rests on, though a wider one here: the project walk skips `node_modules`, so a candidate under it was never covered by that proof and kept a notification-independent probe until now. A project on such a mount should be treated as one where notifications do not work rather than one where they merely have not fired. The barrier that lets a synchronous edit reach those watchers before a delivery reads their verdict is the watcher's own acknowledgement rather than a fixed wait: an in-process watcher answers on the next turn of the loop its callbacks are queued on, and the Windows broker answers by an ordered round-trip, so a delivery waits for the crossing instead of guessing at it. The project is snapshotted before and after compilation, while every graph member carries the compiler filesystem's content and physical-identity proof; only a complete generation that still matches both may authorize narrow reuse. This also rejects an in-project or external A→B→A change whose restored post-compile bytes would otherwise hide the transient state used by the compiler. `dependenciesComplete` narrows file inputs by the same contract as watch registration, and a project reaches it without a type-driven plugin: ttsc's own transform lanes print syntactically, so the host declares every file complete when no plugin can contribute to it, and the first-party `@ttsc/banner` and `@ttsc/strip` declare their own contribution the same way. Such a delivery validates the universal inputs and the file itself instead of its reference closure. A narrowed file's diagnostics narrow with it: an edit to a file the declaration dropped no longer re-runs the compile, so a type error introduced there surfaces at the next compile the build runs for another reason rather than at the edit. Run the compiler's own check beside the bundler when you want it at the edit. Envelopes without a graph, and generations whose watchers could not be opened or have since failed, retain complete-snapshot validation: losing a notification is the absence of a membership proof rather than evidence of a change, so such a generation keeps validating against its own recorded state (the directory snapshot, the input hashes, and the universal descriptor inputs whose every rejection is evidence of a change rather than an inability to prove one) instead of being discarded. A reported membership event is evidence, and still replaces the generation. For a caching host, an unstable or incomplete attempt is never published: all waiters share one bounded stabilization retry inside the same generation. A stable retry alone resolves and is reused; a second unprovable attempt rejects the shared generation with bounded path-and-proof witnesses. That terminal verdict stays cached while its project, external, and host-input fingerprints remain unchanged, so later request waves pay only the confirmation probes and the compile count is independent of module count. An input change or an explicit cache lifecycle reset permits a new generation. One-shot calls without a cache retain their single compile. Bun runtime setup defines one process-scoped loading session. A dev server started without a watcher takes the build-scoped lifecycle instead of persistent validation. `server.watch: null` leaves the session no channel through which a file change could ever reach it, so what per-delivery validation buys there is incoherence rather than freshness: modules delivered before an edit and after it would come from two different compilations of one program. Each module's first delivery in such a session is therefore settled against the generation the session started from, exactly as under a build, while a module the session already delivered keeps revalidating on its next request. Long-lived hosts without either boundary (Metro workers, the Turbopack loader, and a watching Vite development server, whose initial `buildStart` spans later HMR edits) apply the file-specific validation on every generation hit.
316
+
317
+ Transform source outputs outside the project walk are kept in that external snapshot too. A non-declaration output is reusable only when the graph carries its compiler-time content and physical-identity proof; a post-compile disk read cannot prove which bytes produced the output. Its source hash then lets sibling module requests validate the same generation without adding arbitrary output keys to the project-file universe.
316
318
 
317
319
  ## Sponsors
318
320
 
package/lib/core/index.js CHANGED
@@ -42,6 +42,12 @@ const unpluginFactory = (rawOptions = {}) => {
42
42
  let aliases;
43
43
  let viteCommand;
44
44
  let viteWatching = true;
45
+ // A restart can start the replacement plugin container before closing the
46
+ // old one, and Vite calls buildEnd even for a container that never started.
47
+ // Track the stable per-container PluginContext identity so that unstarted
48
+ // old containers cannot dispose a replacement's freshly initialized cache.
49
+ const viteBuildOwners = new WeakSet();
50
+ let viteBuildLifecycles = 0;
45
51
  return {
46
52
  name,
47
53
  enforce: "pre",
@@ -74,12 +80,23 @@ const unpluginFactory = (rawOptions = {}) => {
74
80
  missingInputs.attach(server);
75
81
  },
76
82
  // Vite calls buildEnd when the dev server (or build) closes; drop every
77
- // poller so a stopped server leaks no watch state.
83
+ // poller and, once the last overlapping container has closed, every
84
+ // generation-owned filesystem tracker as well.
78
85
  buildEnd() {
79
86
  missingInputs.dispose();
87
+ if (viteBuildOwners.delete(this)) {
88
+ viteBuildLifecycles -= 1;
89
+ }
90
+ if (viteBuildLifecycles === 0) {
91
+ transform.resetTtscTransformCache(transformCache);
92
+ }
80
93
  },
81
94
  },
82
95
  buildStart() {
96
+ if (viteCommand !== undefined && !viteBuildOwners.has(this)) {
97
+ viteBuildOwners.add(this);
98
+ viteBuildLifecycles += 1;
99
+ }
83
100
  // Persistent validation exists for a session that spans edits it can
84
101
  // observe, and a dev server told to open no watcher is not one:
85
102
  // `server.watch: null` leaves Vite with no change channel at all, so no
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":["options","resolveOptions","createTtscTransformCache","createViteServeMissingInputWatch","resetTtscTransformCache","beginTtscTransformBuild","stripQuery","transformTtsc","createUnplugin","isDeclarationFile"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":["options","resolveOptions","createTtscTransformCache","createViteServeMissingInputWatch","resetTtscTransformCache","beginTtscTransformBuild","stripQuery","transformTtsc","createUnplugin","isDeclarationFile"],"mappings":"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"}
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { createUnplugin } from 'unplugin';
4
4
  import { resolveOptions } from './options.mjs';
5
- import { createTtscTransformCache, stripQuery, transformTtsc, beginTtscTransformBuild, isDeclarationFile, resetTtscTransformCache } from './transform.mjs';
5
+ import { createTtscTransformCache, stripQuery, transformTtsc, beginTtscTransformBuild, resetTtscTransformCache, isDeclarationFile } from './transform.mjs';
6
6
  export { collectExternalInputHashes, collectProjectInputHashes, isProjectWalkPath } from './transform.mjs';
7
7
  import { createViteServeMissingInputWatch } from './viteServe.mjs';
8
8
 
@@ -39,6 +39,12 @@ const unpluginFactory = (rawOptions = {}) => {
39
39
  let aliases;
40
40
  let viteCommand;
41
41
  let viteWatching = true;
42
+ // A restart can start the replacement plugin container before closing the
43
+ // old one, and Vite calls buildEnd even for a container that never started.
44
+ // Track the stable per-container PluginContext identity so that unstarted
45
+ // old containers cannot dispose a replacement's freshly initialized cache.
46
+ const viteBuildOwners = new WeakSet();
47
+ let viteBuildLifecycles = 0;
42
48
  return {
43
49
  name,
44
50
  enforce: "pre",
@@ -71,12 +77,23 @@ const unpluginFactory = (rawOptions = {}) => {
71
77
  missingInputs.attach(server);
72
78
  },
73
79
  // Vite calls buildEnd when the dev server (or build) closes; drop every
74
- // poller so a stopped server leaks no watch state.
80
+ // poller and, once the last overlapping container has closed, every
81
+ // generation-owned filesystem tracker as well.
75
82
  buildEnd() {
76
83
  missingInputs.dispose();
84
+ if (viteBuildOwners.delete(this)) {
85
+ viteBuildLifecycles -= 1;
86
+ }
87
+ if (viteBuildLifecycles === 0) {
88
+ resetTtscTransformCache(transformCache);
89
+ }
77
90
  },
78
91
  },
79
92
  buildStart() {
93
+ if (viteCommand !== undefined && !viteBuildOwners.has(this)) {
94
+ viteBuildOwners.add(this);
95
+ viteBuildLifecycles += 1;
96
+ }
80
97
  // Persistent validation exists for a session that spans edits it can
81
98
  // observe, and a dev server told to open no watcher is not one:
82
99
  // `server.watch: null` leaves Vite with no change channel at all, so no
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -31,6 +31,10 @@ interface TtscProjectDirectorySnapshot {
31
31
  }
32
32
  /** Generation-scoped directory watchers used to detect membership changes. */
33
33
  interface TtscProjectMutationTracker {
34
+ /** Absolute paths named by generation-time mutation events. */
35
+ changes: Set<string>;
36
+ /** Whether additional event paths were discarded after the witness bound. */
37
+ changesOmitted: boolean;
34
38
  close: () => void;
35
39
  /**
36
40
  * Absolute spellings whose creation, change or removal this tracker would
@@ -124,6 +128,13 @@ export interface TtscCachedProjectTransform {
124
128
  * disk bytes against the recorded hash, and may record a signature then.
125
129
  */
126
130
  inputSignatures?: Record<string, string>;
131
+ /**
132
+ * Raw source hash of every readable key in the transform output, keyed by
133
+ * filesystem identity. Unlike {@link inputHashes}, this includes source
134
+ * outputs outside the project walk without adding arbitrary output keys to
135
+ * the complete project snapshot.
136
+ */
137
+ sourceHashes?: Record<string, string>;
127
138
  /** Metadata snapshot of every directory in the stable generation walk. */
128
139
  projectDirectories?: TtscProjectDirectorySnapshot[];
129
140
  /** Live notification state for universal host-input changes. */
@@ -174,13 +185,19 @@ export interface TtscCachedProjectTransform {
174
185
  * module's first delivery inside the current build.
175
186
  */
176
187
  servedFiles?: Set<string>;
188
+ /**
189
+ * Absolute path of the adapter-owned scratch directory used for this
190
+ * generation. It is disposed after compilation, so none of its compiler,
191
+ * resolver, or plugin artifacts can be a persistent cache or watch input.
192
+ */
193
+ scratchDirectory?: string;
177
194
  /**
178
195
  * Absolute path of the generated temp-dir tsconfig this compile ran against,
179
196
  * when an alias/compiler-options overlay required one. The compiler reports
180
197
  * it in the envelope's `graph.configs` chain, but it is disposed right after
181
198
  * the compile, so registering it as a watch input would invalidate every
182
- * bundler cache snapshot on the next build; watch derivation must skip
183
- * exactly this path.
199
+ * bundler cache snapshot on the next build; watch derivation must skip this
200
+ * path. {@link scratchDirectory} owns the wider disposable-input bound.
184
201
  */
185
202
  temporaryTsconfig?: string;
186
203
  }
@@ -365,8 +382,10 @@ interface TtscHostInputValidation {
365
382
  */
366
383
  export declare function stripQuery(id: string): string;
367
384
  /**
368
- * Returns `true` for TypeScript declaration files (`.d.ts`, `.d.mts`,
369
- * `.d.cts`).
385
+ * Returns `true` for every declaration-file spelling TypeScript-Go accepts.
386
+ * Besides the standard `.d.ts`, `.d.mts`, and `.d.cts` forms, TypeScript-Go
387
+ * treats an arbitrary-extension source such as `styles.d.css.ts` as a
388
+ * declaration file too.
370
389
  */
371
390
  export declare function isDeclarationFile(id: string): boolean;
372
391
  /**
@@ -31,6 +31,10 @@ interface TtscProjectDirectorySnapshot {
31
31
  }
32
32
  /** Generation-scoped directory watchers used to detect membership changes. */
33
33
  interface TtscProjectMutationTracker {
34
+ /** Absolute paths named by generation-time mutation events. */
35
+ changes: Set<string>;
36
+ /** Whether additional event paths were discarded after the witness bound. */
37
+ changesOmitted: boolean;
34
38
  close: () => void;
35
39
  /**
36
40
  * Absolute spellings whose creation, change or removal this tracker would
@@ -124,6 +128,13 @@ export interface TtscCachedProjectTransform {
124
128
  * disk bytes against the recorded hash, and may record a signature then.
125
129
  */
126
130
  inputSignatures?: Record<string, string>;
131
+ /**
132
+ * Raw source hash of every readable key in the transform output, keyed by
133
+ * filesystem identity. Unlike {@link inputHashes}, this includes source
134
+ * outputs outside the project walk without adding arbitrary output keys to
135
+ * the complete project snapshot.
136
+ */
137
+ sourceHashes?: Record<string, string>;
127
138
  /** Metadata snapshot of every directory in the stable generation walk. */
128
139
  projectDirectories?: TtscProjectDirectorySnapshot[];
129
140
  /** Live notification state for universal host-input changes. */
@@ -174,13 +185,19 @@ export interface TtscCachedProjectTransform {
174
185
  * module's first delivery inside the current build.
175
186
  */
176
187
  servedFiles?: Set<string>;
188
+ /**
189
+ * Absolute path of the adapter-owned scratch directory used for this
190
+ * generation. It is disposed after compilation, so none of its compiler,
191
+ * resolver, or plugin artifacts can be a persistent cache or watch input.
192
+ */
193
+ scratchDirectory?: string;
177
194
  /**
178
195
  * Absolute path of the generated temp-dir tsconfig this compile ran against,
179
196
  * when an alias/compiler-options overlay required one. The compiler reports
180
197
  * it in the envelope's `graph.configs` chain, but it is disposed right after
181
198
  * the compile, so registering it as a watch input would invalidate every
182
- * bundler cache snapshot on the next build; watch derivation must skip
183
- * exactly this path.
199
+ * bundler cache snapshot on the next build; watch derivation must skip this
200
+ * path. {@link scratchDirectory} owns the wider disposable-input bound.
184
201
  */
185
202
  temporaryTsconfig?: string;
186
203
  }
@@ -365,8 +382,10 @@ interface TtscHostInputValidation {
365
382
  */
366
383
  export declare function stripQuery(id: string): string;
367
384
  /**
368
- * Returns `true` for TypeScript declaration files (`.d.ts`, `.d.mts`,
369
- * `.d.cts`).
385
+ * Returns `true` for every declaration-file spelling TypeScript-Go accepts.
386
+ * Besides the standard `.d.ts`, `.d.mts`, and `.d.cts` forms, TypeScript-Go
387
+ * treats an arbitrary-extension source such as `styles.d.css.ts` as a
388
+ * declaration file too.
370
389
  */
371
390
  export declare function isDeclarationFile(id: string): boolean;
372
391
  /**
@@ -31,6 +31,10 @@ interface TtscProjectDirectorySnapshot {
31
31
  }
32
32
  /** Generation-scoped directory watchers used to detect membership changes. */
33
33
  interface TtscProjectMutationTracker {
34
+ /** Absolute paths named by generation-time mutation events. */
35
+ changes: Set<string>;
36
+ /** Whether additional event paths were discarded after the witness bound. */
37
+ changesOmitted: boolean;
34
38
  close: () => void;
35
39
  /**
36
40
  * Absolute spellings whose creation, change or removal this tracker would
@@ -124,6 +128,13 @@ export interface TtscCachedProjectTransform {
124
128
  * disk bytes against the recorded hash, and may record a signature then.
125
129
  */
126
130
  inputSignatures?: Record<string, string>;
131
+ /**
132
+ * Raw source hash of every readable key in the transform output, keyed by
133
+ * filesystem identity. Unlike {@link inputHashes}, this includes source
134
+ * outputs outside the project walk without adding arbitrary output keys to
135
+ * the complete project snapshot.
136
+ */
137
+ sourceHashes?: Record<string, string>;
127
138
  /** Metadata snapshot of every directory in the stable generation walk. */
128
139
  projectDirectories?: TtscProjectDirectorySnapshot[];
129
140
  /** Live notification state for universal host-input changes. */
@@ -174,13 +185,19 @@ export interface TtscCachedProjectTransform {
174
185
  * module's first delivery inside the current build.
175
186
  */
176
187
  servedFiles?: Set<string>;
188
+ /**
189
+ * Absolute path of the adapter-owned scratch directory used for this
190
+ * generation. It is disposed after compilation, so none of its compiler,
191
+ * resolver, or plugin artifacts can be a persistent cache or watch input.
192
+ */
193
+ scratchDirectory?: string;
177
194
  /**
178
195
  * Absolute path of the generated temp-dir tsconfig this compile ran against,
179
196
  * when an alias/compiler-options overlay required one. The compiler reports
180
197
  * it in the envelope's `graph.configs` chain, but it is disposed right after
181
198
  * the compile, so registering it as a watch input would invalidate every
182
- * bundler cache snapshot on the next build; watch derivation must skip
183
- * exactly this path.
199
+ * bundler cache snapshot on the next build; watch derivation must skip this
200
+ * path. {@link scratchDirectory} owns the wider disposable-input bound.
184
201
  */
185
202
  temporaryTsconfig?: string;
186
203
  }
@@ -365,8 +382,10 @@ interface TtscHostInputValidation {
365
382
  */
366
383
  export declare function stripQuery(id: string): string;
367
384
  /**
368
- * Returns `true` for TypeScript declaration files (`.d.ts`, `.d.mts`,
369
- * `.d.cts`).
385
+ * Returns `true` for every declaration-file spelling TypeScript-Go accepts.
386
+ * Besides the standard `.d.ts`, `.d.mts`, and `.d.cts` forms, TypeScript-Go
387
+ * treats an arbitrary-extension source such as `styles.d.css.ts` as a
388
+ * declaration file too.
370
389
  */
371
390
  export declare function isDeclarationFile(id: string): boolean;
372
391
  /**