@ttsc/unplugin 0.19.0 → 0.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -302,9 +302,13 @@ const options: TtscUnpluginOptions = {
302
302
  - `compilerOptions`: temporary override layered on the selected project config.
303
303
  - `plugins`: direct `ttsc` plugin list override, or `false` to disable plugins.
304
304
 
305
- ### Watch Mode and HMR
305
+ ### Cache and Watch Invalidation
306
306
 
307
- Transform plugins may report, per file, the source files they consulted (the transform envelope's `dependencies` field, see the [plugin protocol](https://ttsc.dev/docs/development/concepts/protocol#transform)). The adapter registers each reported path with the bundler via `addWatchFile`, so editing a type that only a generated validator depends on invalidates the module in watch mode even though the bundler erased the type-only import from its graph.
307
+ The transform host reports the program's reference graph (the transform envelope's `graph` section: per-file direct resolved references with type-only edges included, global-scope files, and the tsconfig `extends` chain — see the [plugin protocol](https://ttsc.dev/docs/development/concepts/protocol#transform)). Per transformed file, the adapter registers the graph's reachability closure, the globals, and the configs with the bundler via `addWatchFile`, so editing a type that only a generated validator depends on invalidates the module in watch mode, in webpack's filesystem cache, and in Turbopack's `fileDependencies` — even though the bundler erased the type-only import from its own graph.
308
+
309
+ 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. 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.
310
+
311
+ The transform cache itself validates against the same input set: every file under the project root plus the graph-reported inputs outside it (`node_modules` declarations, monorepo sibling sources, out-of-root `extends` ancestry). Hosts that keep one cache for the process lifetime instead of per build (Metro workers, the Turbopack loader, Bun) therefore recompile when any of those inputs changes, not only in-project ones.
308
312
 
309
313
  ## Sponsors
310
314
 
package/lib/api.js CHANGED
@@ -8,7 +8,10 @@ var options = require('./core/options.js');
8
8
 
9
9
  exports.sourceFilePattern = index.sourceFilePattern;
10
10
  exports.unplugin = index.default;
11
+ exports.collectExternalInputHashes = transform.collectExternalInputHashes;
12
+ exports.collectProjectInputHashes = transform.collectProjectInputHashes;
11
13
  exports.createTtscTransformCache = transform.createTtscTransformCache;
14
+ exports.isProjectWalkPath = transform.isProjectWalkPath;
12
15
  exports.transformTtsc = transform.transformTtsc;
13
16
  exports.resolveOptions = options.resolveOptions;
14
17
  //# sourceMappingURL=api.js.map
package/lib/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"api.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;"}
package/lib/api.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  export { sourceFilePattern, default as unplugin } from './core/index.mjs';
2
- export { createTtscTransformCache, transformTtsc } from './core/transform.mjs';
2
+ export { collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, transformTtsc } from './core/transform.mjs';
3
3
  export { resolveOptions } from './core/options.mjs';
4
4
  //# sourceMappingURL=api.mjs.map
@@ -1,7 +1,7 @@
1
1
  import type { UnpluginInstance } from "unplugin";
2
2
  import type { TtscUnpluginOptions } from "./options";
3
3
  import { resolveOptions } from "./options";
4
- import { createTtscTransformCache, transformTtsc } from "./transform";
4
+ import { collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, transformTtsc } from "./transform";
5
5
  /**
6
6
  * Matches any TypeScript or JavaScript source extension (.ts, .tsx, .mts, .cts,
7
7
  * etc.). Shared with the Bun adapter (`bun.ts`) so the filter is defined once
@@ -11,5 +11,5 @@ export declare const sourceFilePattern: RegExp;
11
11
  declare const unplugin: UnpluginInstance<TtscUnpluginOptions | undefined, false>;
12
12
  export type { TtscUnpluginCompilerOptionsJson, TtscUnpluginOptions, } from "./options";
13
13
  export type { TtscTransformHooks } from "./transform";
14
- export { createTtscTransformCache, resolveOptions, transformTtsc, unplugin };
14
+ export { collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, resolveOptions, transformTtsc, unplugin, };
15
15
  export default unplugin;
package/lib/core/index.js CHANGED
@@ -55,11 +55,22 @@ const unpluginFactory = (rawOptions = {}) => {
55
55
  return undefined;
56
56
  }
57
57
  return transform.transformTtsc(file, source, options$1, aliases, transformCache, {
58
- // Register plugin-reported dependencies (the transform envelope's
59
- // `dependencies` lists) so type-only inputs invalidate this module
60
- // in watch mode; bundlers erase type-only imports from their own
61
- // module graph and would otherwise serve stale generated code.
58
+ // Register the derived watch inputs (plugin-reported `dependencies`
59
+ // unioned with the host-owned reference graph) so type-only inputs
60
+ // invalidate this module in watch mode and persistent caches;
61
+ // bundlers erase type-only imports from their own module graph and
62
+ // would otherwise serve stale generated code.
62
63
  addWatchFile: (watched) => this.addWatchFile(watched),
64
+ // A module the plugin declared volatile depends on non-file inputs,
65
+ // which no file-dependency snapshot can represent; mark it
66
+ // uncacheable where the bundler exposes that control.
67
+ markVolatile: () => {
68
+ const native = this.getNativeBuildContext?.();
69
+ if (native?.framework === "webpack" ||
70
+ native?.framework === "rspack") {
71
+ native.loaderContext?.cacheable?.(false);
72
+ }
73
+ },
63
74
  });
64
75
  },
65
76
  };
@@ -80,7 +91,10 @@ function isTransformTarget(id) {
80
91
  }
81
92
 
82
93
  exports.resolveOptions = options.resolveOptions;
94
+ exports.collectExternalInputHashes = transform.collectExternalInputHashes;
95
+ exports.collectProjectInputHashes = transform.collectProjectInputHashes;
83
96
  exports.createTtscTransformCache = transform.createTtscTransformCache;
97
+ exports.isProjectWalkPath = transform.isProjectWalkPath;
84
98
  exports.transformTtsc = transform.transformTtsc;
85
99
  exports.default = unplugin;
86
100
  exports.sourceFilePattern = sourceFilePattern;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":["options","resolveOptions","createTtscTransformCache","stripQuery","transformTtsc","createUnplugin","isDeclarationFile"],"mappings":";;;;;;;;AAYA,MAAM,IAAI,GAAG,eAAe;AAC5B;;;;AAIG;AACI,MAAM,iBAAiB,GAAG;AACjC;AACA,MAAM,kBAAkB,GAAG,oCAAoC;AAC/D;;;AAGG;AACH,MAAM,oBAAoB,GAAG,IAAI;AAEjC;;;;;;;;;AASG;AACH,MAAM,eAAe,GAGjB,CAAC,UAAU,GAAG,EAAE,KAAI;AACtB,IAAA,MAAMA,SAAO,GAAGC,sBAAc,CAAC,UAAU,CAAC;AAC1C,IAAA,MAAM,cAAc,GAAGC,kCAAwB,EAAE;AACjD,IAAA,IAAI,OAAgB;IAEpB,OAAO;QACL,IAAI;AACJ,QAAA,OAAO,EAAE,KAAK;AAEd,QAAA,IAAI,EAAE;AACJ,YAAA,cAAc,CAAC,MAAM,EAAA;AACnB,gBAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK;YAChC,CAAC;AACF,SAAA;QAED,UAAU,GAAA;YACR,cAAc,CAAC,KAAK,EAAE;QACxB,CAAC;AAED,QAAA,gBAAgB,CAAC,EAAE,EAAA;AACjB,YAAA,MAAM,IAAI,GAAGC,oBAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,OAAO,iBAAiB,CAAC,IAAI,CAAC;QAChC,CAAC;AAED,QAAA,MAAM,SAAS,CAAC,MAAM,EAAE,EAAE,EAAA;AACxB,YAAA,MAAM,IAAI,GAAGA,oBAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE;AAC5B,gBAAA,OAAO,SAAS;YAClB;YACA,OAAOC,uBAAa,CAAC,IAAI,EAAE,MAAM,EAAEJ,SAAO,EAAE,OAAO,EAAE,cAAc,EAAE;;;;;gBAKnE,YAAY,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;AACtD,aAAA,CAAC;QACJ,CAAC;KACF;AACH,CAAC;AAED,MAAM,QAAQ,GACZK,yBAAc,CAAC,eAAe;AAWhC;;;;;;AAMG;AACH,SAAS,iBAAiB,CAAC,EAAU,EAAA;AACnC,IAAA,QACE,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,QAAA,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,CAACC,2BAAiB,CAAC,EAAE,CAAC;AACtB,QAAA,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;AAEhC;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":["options","resolveOptions","createTtscTransformCache","stripQuery","transformTtsc","createUnplugin","isDeclarationFile"],"mappings":";;;;;;;;AAeA,MAAM,IAAI,GAAG,eAAe;AAC5B;;;;AAIG;AACI,MAAM,iBAAiB,GAAG;AACjC;AACA,MAAM,kBAAkB,GAAG,oCAAoC;AAC/D;;;AAGG;AACH,MAAM,oBAAoB,GAAG,IAAI;AAEjC;;;;;;;;;AASG;AACH,MAAM,eAAe,GAGjB,CAAC,UAAU,GAAG,EAAE,KAAI;AACtB,IAAA,MAAMA,SAAO,GAAGC,sBAAc,CAAC,UAAU,CAAC;AAC1C,IAAA,MAAM,cAAc,GAAGC,kCAAwB,EAAE;AACjD,IAAA,IAAI,OAAgB;IAEpB,OAAO;QACL,IAAI;AACJ,QAAA,OAAO,EAAE,KAAK;AAEd,QAAA,IAAI,EAAE;AACJ,YAAA,cAAc,CAAC,MAAM,EAAA;AACnB,gBAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK;YAChC,CAAC;AACF,SAAA;QAED,UAAU,GAAA;YACR,cAAc,CAAC,KAAK,EAAE;QACxB,CAAC;AAED,QAAA,gBAAgB,CAAC,EAAE,EAAA;AACjB,YAAA,MAAM,IAAI,GAAGC,oBAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,OAAO,iBAAiB,CAAC,IAAI,CAAC;QAChC,CAAC;AAED,QAAA,MAAM,SAAS,CAAC,MAAM,EAAE,EAAE,EAAA;AACxB,YAAA,MAAM,IAAI,GAAGA,oBAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE;AAC5B,gBAAA,OAAO,SAAS;YAClB;YACA,OAAOC,uBAAa,CAAC,IAAI,EAAE,MAAM,EAAEJ,SAAO,EAAE,OAAO,EAAE,cAAc,EAAE;;;;;;gBAMnE,YAAY,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;;;;gBAIrD,YAAY,EAAE,MAAK;AACjB,oBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,IAAI;AAC7C,oBAAA,IACE,MAAM,EAAE,SAAS,KAAK,SAAS;AAC/B,wBAAA,MAAM,EAAE,SAAS,KAAK,QAAQ,EAC9B;wBACA,MAAM,CAAC,aAAa,EAAE,SAAS,GAAG,KAAK,CAAC;oBAC1C;gBACF,CAAC;AACF,aAAA,CAAC;QACJ,CAAC;KACF;AACH,CAAC;AAED,MAAM,QAAQ,GACZK,yBAAc,CAAC,eAAe;AAmBhC;;;;;;AAMG;AACH,SAAS,iBAAiB,CAAC,EAAU,EAAA;AACnC,IAAA,QACE,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,QAAA,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,CAACC,2BAAiB,CAAC,EAAE,CAAC;AACtB,QAAA,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;AAEhC;;;;;;;;;;;;"}
@@ -1,6 +1,7 @@
1
1
  import { createUnplugin } from 'unplugin';
2
2
  import { resolveOptions } from './options.mjs';
3
3
  import { stripQuery, transformTtsc, isDeclarationFile, createTtscTransformCache } from './transform.mjs';
4
+ export { collectExternalInputHashes, collectProjectInputHashes, isProjectWalkPath } from './transform.mjs';
4
5
 
5
6
  const name = "ttsc-unplugin";
6
7
  /**
@@ -51,11 +52,22 @@ const unpluginFactory = (rawOptions = {}) => {
51
52
  return undefined;
52
53
  }
53
54
  return transformTtsc(file, source, options, aliases, transformCache, {
54
- // Register plugin-reported dependencies (the transform envelope's
55
- // `dependencies` lists) so type-only inputs invalidate this module
56
- // in watch mode; bundlers erase type-only imports from their own
57
- // module graph and would otherwise serve stale generated code.
55
+ // Register the derived watch inputs (plugin-reported `dependencies`
56
+ // unioned with the host-owned reference graph) so type-only inputs
57
+ // invalidate this module in watch mode and persistent caches;
58
+ // bundlers erase type-only imports from their own module graph and
59
+ // would otherwise serve stale generated code.
58
60
  addWatchFile: (watched) => this.addWatchFile(watched),
61
+ // A module the plugin declared volatile depends on non-file inputs,
62
+ // which no file-dependency snapshot can represent; mark it
63
+ // uncacheable where the bundler exposes that control.
64
+ markVolatile: () => {
65
+ const native = this.getNativeBuildContext?.();
66
+ if (native?.framework === "webpack" ||
67
+ native?.framework === "rspack") {
68
+ native.loaderContext?.cacheable?.(false);
69
+ }
70
+ },
59
71
  });
60
72
  },
61
73
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAYA,MAAM,IAAI,GAAG,eAAe;AAC5B;;;;AAIG;AACI,MAAM,iBAAiB,GAAG;AACjC;AACA,MAAM,kBAAkB,GAAG,oCAAoC;AAC/D;;;AAGG;AACH,MAAM,oBAAoB,GAAG,IAAI;AAEjC;;;;;;;;;AASG;AACH,MAAM,eAAe,GAGjB,CAAC,UAAU,GAAG,EAAE,KAAI;AACtB,IAAA,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC;AAC1C,IAAA,MAAM,cAAc,GAAG,wBAAwB,EAAE;AACjD,IAAA,IAAI,OAAgB;IAEpB,OAAO;QACL,IAAI;AACJ,QAAA,OAAO,EAAE,KAAK;AAEd,QAAA,IAAI,EAAE;AACJ,YAAA,cAAc,CAAC,MAAM,EAAA;AACnB,gBAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK;YAChC,CAAC;AACF,SAAA;QAED,UAAU,GAAA;YACR,cAAc,CAAC,KAAK,EAAE;QACxB,CAAC;AAED,QAAA,gBAAgB,CAAC,EAAE,EAAA;AACjB,YAAA,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,OAAO,iBAAiB,CAAC,IAAI,CAAC;QAChC,CAAC;AAED,QAAA,MAAM,SAAS,CAAC,MAAM,EAAE,EAAE,EAAA;AACxB,YAAA,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE;AAC5B,gBAAA,OAAO,SAAS;YAClB;YACA,OAAO,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE;;;;;gBAKnE,YAAY,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;AACtD,aAAA,CAAC;QACJ,CAAC;KACF;AACH,CAAC;AAED,MAAM,QAAQ,GACZ,cAAc,CAAC,eAAe;AAWhC;;;;;;AAMG;AACH,SAAS,iBAAiB,CAAC,EAAU,EAAA;AACnC,IAAA,QACE,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,QAAA,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,CAAC,iBAAiB,CAAC,EAAE,CAAC;AACtB,QAAA,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;AAEhC;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;AAeA,MAAM,IAAI,GAAG,eAAe;AAC5B;;;;AAIG;AACI,MAAM,iBAAiB,GAAG;AACjC;AACA,MAAM,kBAAkB,GAAG,oCAAoC;AAC/D;;;AAGG;AACH,MAAM,oBAAoB,GAAG,IAAI;AAEjC;;;;;;;;;AASG;AACH,MAAM,eAAe,GAGjB,CAAC,UAAU,GAAG,EAAE,KAAI;AACtB,IAAA,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC;AAC1C,IAAA,MAAM,cAAc,GAAG,wBAAwB,EAAE;AACjD,IAAA,IAAI,OAAgB;IAEpB,OAAO;QACL,IAAI;AACJ,QAAA,OAAO,EAAE,KAAK;AAEd,QAAA,IAAI,EAAE;AACJ,YAAA,cAAc,CAAC,MAAM,EAAA;AACnB,gBAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK;YAChC,CAAC;AACF,SAAA;QAED,UAAU,GAAA;YACR,cAAc,CAAC,KAAK,EAAE;QACxB,CAAC;AAED,QAAA,gBAAgB,CAAC,EAAE,EAAA;AACjB,YAAA,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,OAAO,iBAAiB,CAAC,IAAI,CAAC;QAChC,CAAC;AAED,QAAA,MAAM,SAAS,CAAC,MAAM,EAAE,EAAE,EAAA;AACxB,YAAA,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE;AAC5B,gBAAA,OAAO,SAAS;YAClB;YACA,OAAO,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE;;;;;;gBAMnE,YAAY,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;;;;gBAIrD,YAAY,EAAE,MAAK;AACjB,oBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,IAAI;AAC7C,oBAAA,IACE,MAAM,EAAE,SAAS,KAAK,SAAS;AAC/B,wBAAA,MAAM,EAAE,SAAS,KAAK,QAAQ,EAC9B;wBACA,MAAM,CAAC,aAAa,EAAE,SAAS,GAAG,KAAK,CAAC;oBAC1C;gBACF,CAAC;AACF,aAAA,CAAC;QACJ,CAAC;KACF;AACH,CAAC;AAED,MAAM,QAAQ,GACZ,cAAc,CAAC,eAAe;AAmBhC;;;;;;AAMG;AACH,SAAS,iBAAiB,CAAC,EAAU,EAAA;AACnC,IAAA,QACE,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,QAAA,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,CAAC,iBAAiB,CAAC,EAAE,CAAC;AACtB,QAAA,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;AAEhC;;;;"}
@@ -32,6 +32,20 @@ export interface TtscTransformAlias {
32
32
  * miss on every module.
33
33
  */
34
34
  export interface TtscCachedProjectTransform {
35
+ /**
36
+ * SHA-256 hash of every input the compiler reported outside the project walk
37
+ * (keyed by absolute path), captured at the time of the transform.
38
+ *
39
+ * The project walk cannot see files outside the project root or under ignored
40
+ * directories (`node_modules` declarations, monorepo sibling sources,
41
+ * out-of-root tsconfig `extends` ancestry), yet the host-owned reference
42
+ * graph proves they are transform inputs. Long-lived hosts that never clear
43
+ * the cache between builds (Metro workers, the Turbopack loader, Bun) would
44
+ * otherwise replay a project transform computed against a stale out-of-walk
45
+ * input for the whole process lifetime; per-build hosts clear the cache on
46
+ * `buildStart` and never replay across edits.
47
+ */
48
+ externalInputHashes?: Record<string, string>;
35
49
  /**
36
50
  * SHA-256 hash of each project-relative input path at the time of the
37
51
  * transform.
@@ -41,6 +55,15 @@ export interface TtscCachedProjectTransform {
41
55
  projectRoot: string;
42
56
  /** Raw compiler output returned by {@link TtscCompiler.transform}. */
43
57
  result: ITtscCompilerTransformation;
58
+ /**
59
+ * Absolute path of the generated temp-dir tsconfig this compile ran against,
60
+ * when an alias/compiler-options overlay required one. The compiler reports
61
+ * it in the envelope's `graph.configs` chain, but it is disposed right after
62
+ * the compile, so registering it as a watch input would invalidate every
63
+ * bundler cache snapshot on the next build; watch derivation must skip
64
+ * exactly this path.
65
+ */
66
+ temporaryTsconfig?: string;
44
67
  }
45
68
  /**
46
69
  * Keyed by a stable JSON string that encodes the tsconfig path, compiler
@@ -58,12 +81,25 @@ export declare function createTtscTransformCache(): TtscTransformCache;
58
81
  */
59
82
  export interface TtscTransformHooks {
60
83
  /**
61
- * Invoked once per absolute dependency path the plugin reported for the
62
- * transformed file (`dependencies` in the transform envelope). Adapters
63
- * forward this to the bundler's `addWatchFile` so type-only inputs
64
- * participate in HMR invalidation.
84
+ * Invoked once per absolute watch-input path derived for the transformed file
85
+ * `F`: the plugin-reported `dependencies[F]` list unioned with the host-owned
86
+ * reference graph's contribution the reachability closure of `graph.edges`
87
+ * from `F`, the `graph.globals` files, and the `graph.configs` chain — or,
88
+ * for a file the envelope declared `dependenciesComplete`, only
89
+ * `dependencies[F]` and the universal `graph.configs` chain. Adapters forward
90
+ * this to the bundler's `addWatchFile` so type-only inputs participate in
91
+ * watch-mode and persistent-cache invalidation. See {@link selectWatchInputs}
92
+ * for the exact derivation.
65
93
  */
66
94
  addWatchFile?: (file: string) => void;
95
+ /**
96
+ * Invoked when the plugin declared the transformed file volatile (the
97
+ * envelope's `volatile` list): its output depends on non-file inputs that no
98
+ * file-dependency snapshot can represent. Adapters should mark the module
99
+ * uncacheable where the bundler exposes that control (e.g. a webpack loader
100
+ * context's `cacheable(false)`).
101
+ */
102
+ markVolatile?: () => void;
67
103
  }
68
104
  /**
69
105
  * Apply the ttsc plugin transform to a single source file.
@@ -110,3 +146,27 @@ export declare function isDeclarationFile(id: string): boolean;
110
146
  * unnecessary module update and preserves the original source map.
111
147
  */
112
148
  export declare function createTransformResult(source: string, code: string): TtscTransformResult | undefined;
149
+ /**
150
+ * Hash every input file under `projectRoot` (the same walk universe
151
+ * {@link matchesCachedSource} validates against), keyed by project-relative
152
+ * slash path. Exported so hosts without a per-build boundary (`@ttsc/metro`)
153
+ * can fold the identical input universe into their own cache fingerprints.
154
+ */
155
+ export declare function collectProjectInputHashes(projectRoot: string): Record<string, string>;
156
+ /**
157
+ * Report whether an absolute `file` belongs to the project walk universe of
158
+ * `root`: it lies under `root` and no segment of the relative path (including
159
+ * the basename) is an ignored directory name. The predicate mirrors
160
+ * {@link listProjectInputFiles} exactly, so "walk-visible" here means "hashed by
161
+ * {@link collectProjectInputHashes}". Anything else is an out-of-walk input that
162
+ * only the reference graph can prove relevant.
163
+ */
164
+ export declare function isProjectWalkPath(root: string, file: string): boolean;
165
+ /**
166
+ * Hash a list of absolute out-of-walk input paths: content SHA-256 for a
167
+ * readable file, a stable `missing` marker otherwise. The marker is state, not
168
+ * an error — a recorded input disappearing (or reappearing) must change the
169
+ * comparison exactly like a content edit. Exported so `@ttsc/metro` can re-hash
170
+ * its recorded snapshot with identical semantics at cache-key time.
171
+ */
172
+ export declare function collectExternalInputHashes(paths: readonly string[]): Record<string, string>;