@ttsc/unplugin 0.26.1 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -306,13 +306,13 @@ const options: TtscUnpluginOptions = {
306
306
 
307
307
  ### Cache and Watch Invalidation
308
308
 
309
- The transform graph also records module-resolution candidates that would outrank a selected target. The adapter registers candidates for importers in the transformed file's reachability closure, so creating or changing a higher-priority probe invalidates watch and persistent caches without an importer or tsconfig edit.
309
+ The transform graph also records module-resolution candidates that would outrank a selected target, plus the selected lexical spelling when the compiler reports its physical symlink or junction target. The adapter registers candidates for importers in the transformed file's reachability closure, so creating or changing a higher-priority probe or retargeting the selected alias invalidates watch and persistent caches without an importer or tsconfig edit.
310
310
 
311
311
  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.
312
312
 
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. 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.
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 uses the same input set: 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 in that build; a repeated delivery validates the complete snapshots. This avoids one complete project walk per module on an initial build. Bun runtime setup defines one process-scoped loading session. Long-lived hosts without either boundary (Metro workers, the Turbopack loader, and Vite's development server, whose initial `buildStart` spans later HMR edits) validate the complete project and external-input snapshots 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. 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. 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. Envelopes without a graph, an unavailable watcher, or an unstable/incomplete generation retain complete-snapshot validation. Bun runtime setup defines one process-scoped loading session. Long-lived hosts without either boundary (Metro workers, the Turbopack loader, and Vite's development server, whose initial `buildStart` spans later HMR edits) apply the file-specific validation on every generation hit.
316
316
 
317
317
  ## Sponsors
318
318
 
package/lib/bun.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import { isTransformTarget } from './core/index.mjs';
3
- import { beginTtscTransformBuild, transformTtsc, createTtscTransformCache } from './core/transform.mjs';
3
+ import { createTtscTransformCache, beginTtscTransformBuild, transformTtsc } from './core/transform.mjs';
4
4
  import { resolveOptions } from './core/options.mjs';
5
5
 
6
6
  /**
@@ -10,7 +10,7 @@ import { beginTtscTransformBuild, collectExternalInputHashes, collectProjectInpu
10
10
  export declare const sourceFilePattern: RegExp;
11
11
  declare const unplugin: UnpluginInstance<TtscUnpluginOptions | undefined, false>;
12
12
  export type { TtscUnpluginCompilerOptionsJson, TtscUnpluginOptions, } from "./options";
13
- export type { TtscTransformHooks } from "./transform";
13
+ export type { TtscTransformFilesystemOperations, TtscTransformHooks, } from "./transform";
14
14
  export { beginTtscTransformBuild, collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, resetTtscTransformCache, resolveOptions, transformTtsc, unplugin, };
15
15
  export default unplugin;
16
16
  /**
@@ -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 { stripQuery, transformTtsc, beginTtscTransformBuild, isDeclarationFile, resetTtscTransformCache, createTtscTransformCache } from './transform.mjs';
5
+ import { createTtscTransformCache, stripQuery, transformTtsc, beginTtscTransformBuild, isDeclarationFile, resetTtscTransformCache } from './transform.mjs';
6
6
  export { collectExternalInputHashes, collectProjectInputHashes, isProjectWalkPath } from './transform.mjs';
7
7
  import { createViteServeMissingInputWatch } from './viteServe.mjs';
8
8
 
@@ -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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"}
@@ -1,5 +1,6 @@
1
+ import fs from "node:fs";
1
2
  import type { ITtscCompilerTransformation } from "ttsc";
2
- import { type FilesystemPathIdentityContext } from "ttsc/path-identity";
3
+ import { type FilesystemPathIdentityContext, type FilesystemPathIdentityOperations } from "ttsc/path-identity";
3
4
  import type { TransformResult } from "unplugin";
4
5
  import type { ResolvedTtscUnpluginOptions } from "./options";
5
6
  /**
@@ -21,15 +22,29 @@ export interface TtscTransformAlias {
21
22
  /** Absolute or cwd-relative path that the alias points to. */
22
23
  replacement: string;
23
24
  }
25
+ /** One directory's cheap project-membership identity at generation time. */
26
+ interface TtscProjectDirectorySnapshot {
27
+ /** Absolute directory spelling used by the project walk. */
28
+ path: string;
29
+ /** Metadata signature that changes when its immediate membership changes. */
30
+ signature: string;
31
+ }
32
+ /** Generation-scoped directory watchers used to detect membership changes. */
33
+ interface TtscProjectMutationTracker {
34
+ close: () => void;
35
+ failed: boolean;
36
+ membershipChanged: boolean;
37
+ settle?: Promise<void>;
38
+ }
24
39
  /**
25
40
  * A single entry in the project transform cache.
26
41
  *
27
42
  * Stores the full compiler result together with SHA-256 hashes of every project
28
43
  * input file. In a cache with an explicit build lifecycle, the first delivery
29
44
  * of each compiled module compares its supplied source with the generation
30
- * snapshot in constant time; a repeated delivery re-hashes the complete input
31
- * set. Persistent caches without that boundary perform complete validation on
32
- * every hit.
45
+ * snapshot in constant time. Later graph-bearing deliveries validate only the
46
+ * requested file's derived inputs plus exact host descriptor/config inputs;
47
+ * graph-free envelopes retain complete-snapshot validation.
33
48
  */
34
49
  export interface TtscCachedProjectTransform {
35
50
  /**
@@ -46,6 +61,12 @@ export interface TtscCachedProjectTransform {
46
61
  * `buildStart` and never replay across edits.
47
62
  */
48
63
  externalInputHashes?: Record<string, string>;
64
+ /**
65
+ * Compiler-time physical identities for graph-owned entries in
66
+ * {@link externalInputHashes}. Dependency-only paths have no generation
67
+ * realpath protocol and therefore omit this evidence.
68
+ */
69
+ externalInputRealpaths?: Record<string, string | null>;
49
70
  /**
50
71
  * Original absolute spellings of {@link externalInputHashes} inputs. These
51
72
  * stay separate from their identity keys so validation reads the paths the
@@ -57,13 +78,25 @@ export interface TtscCachedProjectTransform {
57
78
  * transform.
58
79
  */
59
80
  inputHashes: Record<string, string>;
81
+ /** Metadata snapshot of every directory in the stable generation walk. */
82
+ projectDirectories?: TtscProjectDirectorySnapshot[];
83
+ /** Live notification state for universal host-input changes. */
84
+ hostInputMutationTracker?: TtscProjectMutationTracker;
85
+ /** Live notification state for file/directory creation, deletion, and rename. */
86
+ projectMutationTracker?: TtscProjectMutationTracker;
87
+ /**
88
+ * Whether the generation-time project walk observed every directory and file
89
+ * it attempted to snapshot. An incomplete walk may never authorize narrow
90
+ * validation; a later complete walk must be allowed to replace it.
91
+ */
92
+ projectSnapshotComplete?: boolean;
60
93
  /** Absolute path to the directory that owns the tsconfig. */
61
94
  projectRoot: string;
62
95
  /** Raw compiler output returned by {@link TtscCompiler.transform}. */
63
96
  result: ITtscCompilerTransformation;
64
97
  /**
65
98
  * Files already delivered from this generation, keyed by filesystem identity.
66
- * Build-scoped caches use this to skip complete validation only for a
99
+ * Build-scoped caches use this to skip persistent validation only for a
67
100
  * module's first delivery inside the current build.
68
101
  */
69
102
  servedFiles?: Set<string>;
@@ -84,8 +117,31 @@ export interface TtscCachedProjectTransform {
84
117
  * compilation rather than spawning multiple `TtscCompiler` instances.
85
118
  */
86
119
  export type TtscTransformCache = Map<string, Promise<TtscCachedProjectTransform>>;
87
- /** Create an empty persistent transform cache. */
88
- export declare function createTtscTransformCache(): TtscTransformCache;
120
+ /** Cache-owned synchronous filesystem reads used by transform validation. */
121
+ export interface TtscTransformFilesystemOperations {
122
+ /** Override the case policy when the observed filesystem is not the host. */
123
+ caseSensitive?: FilesystemPathIdentityOperations["caseSensitive"];
124
+ /** Test whether a validation or resolution candidate currently exists. */
125
+ exists(location: string): boolean;
126
+ /** Read link metadata without following a symbolic link. */
127
+ lstat(location: string): fs.BigIntStats;
128
+ /** Read bytes used by project, graph, and host-input fingerprints. */
129
+ readFile(location: string): Buffer;
130
+ /** Enumerate one project or missing-input proof directory. */
131
+ readdir(location: string): fs.Dirent[];
132
+ /** Resolve one lexical path to its current physical target. */
133
+ realpath(location: string): string;
134
+ /** Read ordinary metadata for file-kind and missing-path checks. */
135
+ stat(location: string): fs.Stats;
136
+ /** Read nanosecond metadata for stable file and directory signatures. */
137
+ statBigInt(location: string): fs.BigIntStats;
138
+ /** Override path parsing when the observed filesystem is not the host. */
139
+ platform?: NodeJS.Platform;
140
+ }
141
+ /** Normalize one directory entry under the owning filesystem's case policy. */
142
+ export declare function normalizeHostInputName(name: string, caseSensitive: boolean): string;
143
+ /** Create an empty persistent transform cache with isolated filesystem reads. */
144
+ export declare function createTtscTransformCache(operations?: Partial<TtscTransformFilesystemOperations>): TtscTransformCache;
89
145
  /**
90
146
  * Start a host build, clearing its prior generation and enabling constant-time
91
147
  * first delivery for modules compiled during this build.
@@ -184,30 +240,32 @@ export declare function createTransformResult(source: string, code: string): Tts
184
240
  * slash path. Exported so hosts without a per-build boundary (`@ttsc/metro`)
185
241
  * can fold the identical input universe into their own cache fingerprints.
186
242
  */
187
- export declare function collectProjectInputHashes(projectRoot: string, identities?: FilesystemPathIdentityContext): Record<string, string>;
243
+ export declare function collectProjectInputHashes(projectRoot: string, identities?: FilesystemPathIdentityContext, filesystem?: TtscTransformFilesystemOperations): Record<string, string>;
188
244
  /**
189
245
  * Report whether an absolute `file` belongs to the project walk universe of
190
246
  * `root`: it lies under `root`, every component exists without traversing a
191
247
  * symbolic link, the leaf is a regular file, and no segment of the relative
192
- * path is ignored. The predicate mirrors {@link listProjectInputFiles} exactly,
193
- * so "walk-visible" here means "hashed by {@link collectProjectInputHashes}".
248
+ * path is ignored. The predicate mirrors {@link walkProjectInputs} exactly, so
249
+ * "walk-visible" here means "hashed by {@link collectProjectInputHashes}".
194
250
  * Missing paths and files reached through symlinks or Windows junctions are
195
251
  * out-of-walk inputs that only the reference graph can prove relevant.
196
252
  */
197
- export declare function isProjectWalkPath(root: string, file: string, identities?: FilesystemPathIdentityContext): boolean;
253
+ export declare function isProjectWalkPath(root: string, file: string, _identities?: FilesystemPathIdentityContext, filesystem?: TtscTransformFilesystemOperations): boolean;
198
254
  /**
199
255
  * Hash a list of absolute out-of-walk input paths: content SHA-256 for a
200
- * readable file, a stable `missing` marker otherwise. Keys use filesystem
201
- * identity so case-only spellings share one snapshot entry, while reads retain
202
- * the original path supplied by the compiler. The marker is state, not an error
203
- * a recorded input disappearing (or reappearing) must change the comparison
204
- * exactly like a content edit. Exported so `@ttsc/metro` can re-hash its
205
- * recorded snapshot with identical semantics at cache-key time.
256
+ * readable file, a stable directory-kind digest for a directory candidate, and
257
+ * a stable `missing` marker otherwise. Keys use filesystem identity so
258
+ * case-only spellings share one snapshot entry, while reads retain the original
259
+ * path supplied by the compiler. The marker is state, not an error — a recorded
260
+ * input disappearing (or reappearing) must change the comparison exactly like a
261
+ * content edit. Exported so `@ttsc/metro` can re-hash its recorded snapshot
262
+ * with identical semantics at cache-key time.
206
263
  */
207
- export declare function collectExternalInputHashes(paths: readonly string[]): Record<string, string>;
264
+ export declare function collectExternalInputHashes(paths: readonly string[], filesystem?: TtscTransformFilesystemOperations): Record<string, string>;
208
265
  /**
209
266
  * Build a comparison key for a path without changing the spelling handed to a
210
267
  * filesystem or bundler. Windows is case-insensitive; macOS is probed per
211
268
  * existing filesystem location so case-sensitive volumes keep distinct paths.
212
269
  */
213
270
  export declare function pathIdentityKey(file: string, identities?: FilesystemPathIdentityContext): string;
271
+ export {};