@ttsc/unplugin 0.28.1 → 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.
Files changed (49) hide show
  1. package/README.md +3 -1
  2. package/lib/api.d.cts +8 -0
  3. package/lib/api.d.mts +8 -0
  4. package/lib/bun-register.d.cts +25 -0
  5. package/lib/bun-register.d.mts +25 -0
  6. package/lib/bun.d.cts +95 -0
  7. package/lib/bun.d.mts +95 -0
  8. package/lib/core/index.d.cts +23 -0
  9. package/lib/core/index.d.mts +23 -0
  10. package/lib/core/index.js +18 -1
  11. package/lib/core/index.js.map +1 -1
  12. package/lib/core/index.mjs +19 -2
  13. package/lib/core/index.mjs.map +1 -1
  14. package/lib/core/options.d.cts +54 -0
  15. package/lib/core/options.d.mts +54 -0
  16. package/lib/core/transform.d.cts +433 -0
  17. package/lib/core/transform.d.mts +433 -0
  18. package/lib/core/transform.d.ts +23 -4
  19. package/lib/core/transform.js +715 -117
  20. package/lib/core/transform.js.map +1 -1
  21. package/lib/core/transform.mjs +715 -117
  22. package/lib/core/transform.mjs.map +1 -1
  23. package/lib/core/tsconfigPaths.d.cts +29 -0
  24. package/lib/core/tsconfigPaths.d.mts +29 -0
  25. package/lib/core/viteServe.d.cts +81 -0
  26. package/lib/core/viteServe.d.mts +81 -0
  27. package/lib/esbuild.d.cts +3 -0
  28. package/lib/esbuild.d.mts +3 -0
  29. package/lib/farm.d.cts +3 -0
  30. package/lib/farm.d.mts +3 -0
  31. package/lib/index.d.cts +12 -0
  32. package/lib/index.d.mts +12 -0
  33. package/lib/next.d.cts +37 -0
  34. package/lib/next.d.mts +37 -0
  35. package/lib/rolldown.d.cts +3 -0
  36. package/lib/rolldown.d.mts +3 -0
  37. package/lib/rollup.d.cts +3 -0
  38. package/lib/rollup.d.mts +3 -0
  39. package/lib/rspack.d.cts +3 -0
  40. package/lib/rspack.d.mts +3 -0
  41. package/lib/turbopack.d.cts +58 -0
  42. package/lib/turbopack.d.mts +58 -0
  43. package/lib/vite.d.cts +3 -0
  44. package/lib/vite.d.mts +3 -0
  45. package/lib/webpack.d.cts +3 -0
  46. package/lib/webpack.d.mts +3 -0
  47. package/package.json +122 -17
  48. package/src/core/index.ts +18 -1
  49. package/src/core/transform.ts +1014 -139
@@ -0,0 +1,433 @@
1
+ import fs from "node:fs";
2
+ import type { ITtscCompilerTransformation } from "ttsc";
3
+ import { type FilesystemPathIdentityContext, type FilesystemPathIdentityOperations } from "ttsc/path-identity";
4
+ import type { TransformResult } from "unplugin";
5
+ import type { ResolvedTtscUnpluginOptions } from "./options.cjs";
6
+ /**
7
+ * The normalised transform result type that this module produces.
8
+ *
9
+ * Excludes the shorthand `string`, `null`, and `undefined` variants of
10
+ * unplugin's `TransformResult` so callers always receive an object or
11
+ * `undefined`.
12
+ */
13
+ export type TtscTransformResult = Exclude<TransformResult, string | null | undefined>;
14
+ /**
15
+ * Normalised alias entry used when building the `paths` overlay for the
16
+ * generated tsconfig. Derived from either a Vite array alias or a webpack/
17
+ * Rspack object alias.
18
+ */
19
+ export interface TtscTransformAlias {
20
+ /** The alias key (module specifier prefix). */
21
+ find: string;
22
+ /** Absolute or cwd-relative path that the alias points to. */
23
+ replacement: string;
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
+ /** 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;
38
+ close: () => void;
39
+ /**
40
+ * Absolute spellings whose creation, change or removal this tracker would
41
+ * report, when it watches exact names rather than whole directories.
42
+ *
43
+ * A validation that finds an input here needs no filesystem call of its own:
44
+ * the tracker is the evidence, and every path that leaves this set falls back
45
+ * to being proven by hand. Empty for a tracker that watches directories as a
46
+ * whole, which cannot answer for one name.
47
+ */
48
+ covered?: ReadonlySet<string>;
49
+ /**
50
+ * Wait until every event this tracker's watcher has already dispatched has
51
+ * been applied to it.
52
+ *
53
+ * An in-process watcher drains on the next macrotask turn, because its
54
+ * callbacks are already queued on this loop. A watcher living in the Windows
55
+ * broker drains by round-trip instead: the child replies after its own turn,
56
+ * and IPC preserves order, so the reply cannot overtake an event the child
57
+ * had already sent (samchon/ttsc#1272).
58
+ */
59
+ drain?: () => Promise<void>;
60
+ failed: boolean;
61
+ membershipChanged: boolean;
62
+ settle?: Promise<void>;
63
+ }
64
+ /**
65
+ * A single entry in the project transform cache.
66
+ *
67
+ * Stores the full compiler result together with SHA-256 hashes of every project
68
+ * input file. In a cache with an explicit build lifecycle, the first delivery
69
+ * of each compiled module compares its supplied source with the generation
70
+ * snapshot in constant time. Later graph-bearing deliveries validate only the
71
+ * requested file's derived inputs plus exact host descriptor/config inputs;
72
+ * graph-free envelopes retain complete-snapshot validation.
73
+ */
74
+ export interface TtscCachedProjectTransform {
75
+ /**
76
+ * SHA-256 hash of every input the compiler reported outside the project walk
77
+ * (keyed by filesystem identity), captured at the time of the transform.
78
+ *
79
+ * The project walk cannot see files outside the project root or under ignored
80
+ * directories (`node_modules` declarations, monorepo sibling sources,
81
+ * out-of-root tsconfig `extends` ancestry), yet the host-owned reference
82
+ * graph proves they are transform inputs. Long-lived hosts that never clear
83
+ * the cache between builds (Metro workers and the Turbopack loader) would
84
+ * otherwise replay a project transform computed against a stale out-of-walk
85
+ * input for the whole process lifetime; per-build hosts clear the cache on
86
+ * `buildStart` and never replay across edits.
87
+ */
88
+ externalInputHashes?: Record<string, string>;
89
+ /**
90
+ * Compiler-time physical identities for graph-owned entries in
91
+ * {@link externalInputHashes}. Dependency-only paths have no generation
92
+ * realpath protocol and therefore omit this evidence.
93
+ */
94
+ externalInputRealpaths?: Record<string, string | null>;
95
+ /**
96
+ * Original absolute spellings of {@link externalInputHashes} inputs. These
97
+ * stay separate from their identity keys so validation reads the paths the
98
+ * compiler reported rather than a normalized replacement spelling.
99
+ */
100
+ externalInputPaths?: string[];
101
+ /**
102
+ * Metadata signature of each out-of-walk input, captured around the read that
103
+ * proved its {@link externalInputHashes} entry and recorded only once the
104
+ * observed filesystem's clock provably left the stamp's tick
105
+ * ({@link stampSeparable}). An input whose signature still holds carries the
106
+ * recorded content, so revalidation may skip the read.
107
+ *
108
+ * Keyed by lexical spelling rather than by physical identity, for the reason
109
+ * {@link TtscHostInputValidation} states: a symlink or junction spelling and
110
+ * its selected target deliberately share one identity but have different
111
+ * metadata, so an identity key would let the two overwrite each other's
112
+ * signature and force both to be re-read on every delivery.
113
+ */
114
+ externalInputSignatures?: Record<string, string>;
115
+ /**
116
+ * SHA-256 hash of each project-relative input path at the time of the
117
+ * transform.
118
+ */
119
+ inputHashes: Record<string, string>;
120
+ /**
121
+ * Metadata signature of each {@link inputHashes} entry whose hash was proven
122
+ * against an unracing read of the file on disk, in a tick the observed
123
+ * filesystem's clock had provably left ({@link stampSeparable}).
124
+ *
125
+ * The generation's own current file is absent at capture: its recorded hash
126
+ * comes from the bundler's in-memory source, so the walk that produced it
127
+ * compared nothing. A later delivery of a sibling does compare that file's
128
+ * disk bytes against the recorded hash, and may record a signature then.
129
+ */
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>;
138
+ /** Metadata snapshot of every directory in the stable generation walk. */
139
+ projectDirectories?: TtscProjectDirectorySnapshot[];
140
+ /** Live notification state for universal host-input changes. */
141
+ hostInputMutationTracker?: TtscProjectMutationTracker;
142
+ /**
143
+ * Live notification state for the generation's absent resolution candidates
144
+ * and the directories that carry them.
145
+ *
146
+ * Separate from the universal-input tracker because it listens for a
147
+ * different thing. Every event that can make an absent candidate present is a
148
+ * rename — the file appearing, a component of the path being created,
149
+ * replaced, or retargeted — so a change event on one of these names is never
150
+ * evidence this tracker exists to collect. What it is, on a backend that
151
+ * reports a write below a directory as a change to that directory's own entry
152
+ * (Windows does), is a dev server's steady traffic: listening for every event
153
+ * would replace the generation each time a bundler wrote inside
154
+ * `node_modules`. The filter therefore drops noise without dropping proof.
155
+ * The one appearance it cannot see is a Windows junction retargeted in place
156
+ * through `FSCTL_SET_REPARSE_POINT`, which no mainstream tool does; every
157
+ * package manager replaces the entry instead, which is a rename.
158
+ */
159
+ candidateMutationTracker?: TtscProjectMutationTracker;
160
+ /**
161
+ * Universal descriptor/config inputs proven once at generation time, then by
162
+ * metadata.
163
+ *
164
+ * Recorded state of the generation, like the input hashes and the directory
165
+ * snapshot beside it, rather than state derived from the envelope: an entry
166
+ * carries the manifest that proved it, so nothing can present one
167
+ * generation's recorded inputs under another envelope's proof.
168
+ */
169
+ hostInputValidation?: TtscHostInputValidation;
170
+ /** Live notification state for file/directory creation, deletion, and rename. */
171
+ projectMutationTracker?: TtscProjectMutationTracker;
172
+ /**
173
+ * Whether the generation-time project walk observed every directory and file
174
+ * it attempted to snapshot. An incomplete walk may never authorize narrow
175
+ * validation; a later complete walk must be allowed to replace it.
176
+ */
177
+ projectSnapshotComplete?: boolean;
178
+ /** Absolute path to the directory that owns the tsconfig. */
179
+ projectRoot: string;
180
+ /** Raw compiler output returned by {@link TtscCompiler.transform}. */
181
+ result: ITtscCompilerTransformation;
182
+ /**
183
+ * Files already delivered from this generation, keyed by filesystem identity.
184
+ * Build-scoped caches use this to skip persistent validation only for a
185
+ * module's first delivery inside the current build.
186
+ */
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;
194
+ /**
195
+ * Absolute path of the generated temp-dir tsconfig this compile ran against,
196
+ * when an alias/compiler-options overlay required one. The compiler reports
197
+ * it in the envelope's `graph.configs` chain, but it is disposed right after
198
+ * the compile, so registering it as a watch input would invalidate every
199
+ * bundler cache snapshot on the next build; watch derivation must skip this
200
+ * path. {@link scratchDirectory} owns the wider disposable-input bound.
201
+ */
202
+ temporaryTsconfig?: string;
203
+ }
204
+ /**
205
+ * Keyed by a stable JSON string that encodes the tsconfig path, compiler
206
+ * options overlay, plugin list, and alias paths. The value is a `Promise` so
207
+ * concurrent transforms for the same project share a single in-flight
208
+ * compilation rather than spawning multiple `TtscCompiler` instances.
209
+ */
210
+ export type TtscTransformCache = Map<string, Promise<TtscCachedProjectTransform>>;
211
+ /** Cache-owned synchronous filesystem reads used by transform validation. */
212
+ export interface TtscTransformFilesystemOperations {
213
+ /** Override the case policy when the observed filesystem is not the host. */
214
+ caseSensitive?: FilesystemPathIdentityOperations["caseSensitive"];
215
+ /** Test whether a validation or resolution candidate currently exists. */
216
+ exists(location: string): boolean;
217
+ /** Read link metadata without following a symbolic link. */
218
+ lstat(location: string): fs.BigIntStats;
219
+ /** Read bytes used by project, graph, and host-input fingerprints. */
220
+ readFile(location: string): Buffer;
221
+ /** Enumerate one project or missing-input proof directory. */
222
+ readdir(location: string): fs.Dirent[];
223
+ /** Resolve one lexical path to its current physical target. */
224
+ realpath(location: string): string;
225
+ /** Read ordinary metadata for file-kind and missing-path checks. */
226
+ stat(location: string): fs.Stats;
227
+ /** Read nanosecond metadata for stable file and directory signatures. */
228
+ statBigInt(location: string): fs.BigIntStats;
229
+ /** Override path parsing when the observed filesystem is not the host. */
230
+ platform?: NodeJS.Platform;
231
+ /**
232
+ * Open one directory's change notification, or throw when the observed
233
+ * filesystem cannot provide one.
234
+ *
235
+ * Left undefined, generations watch the host filesystem: `fs.watch` on POSIX
236
+ * and an isolated broker process on Windows. An embedder observing another
237
+ * filesystem supplies its own; a generation whose watch cannot be opened
238
+ * keeps validating from recorded state instead of losing its cache.
239
+ *
240
+ * Supplying one replaces the Windows broker as well, so an embedder that
241
+ * wraps Node's own `fs.watch` there gives up the isolation that contains the
242
+ * native abort Node's Windows fs-event backend can raise when a watched
243
+ * temporary tree is deleted.
244
+ */
245
+ watch?(directory: string, listener: (eventType: string, filename: string | null) => void, onError: () => void): {
246
+ close: () => void;
247
+ };
248
+ }
249
+ /** Normalize one directory entry under the owning filesystem's case policy. */
250
+ export declare function normalizeHostInputName(name: string, caseSensitive: boolean): string;
251
+ /** Create an empty persistent transform cache with isolated filesystem reads. */
252
+ export declare function createTtscTransformCache(operations?: Partial<TtscTransformFilesystemOperations>): TtscTransformCache;
253
+ /**
254
+ * Start a host build, clearing its prior generation and enabling constant-time
255
+ * first delivery for modules compiled during this build.
256
+ *
257
+ * Hosts without a guaranteed build-start callback use persistent validation
258
+ * unless they have another immutable lifecycle. Bun runtime setup, for example,
259
+ * defines one process-scoped module-loading session.
260
+ */
261
+ export declare function beginTtscTransformBuild(cache: TtscTransformCache): void;
262
+ /**
263
+ * Clear a cache and return it to persistent validation mode.
264
+ *
265
+ * This is distinct from {@link beginTtscTransformBuild}: hosts such as Vite's
266
+ * development server may invoke `buildStart` only once for a process that spans
267
+ * many edits, so that callback cannot authorize build-scoped shortcuts.
268
+ */
269
+ export declare function resetTtscTransformCache(cache: TtscTransformCache): void;
270
+ /**
271
+ * What the generation already knows about one derived watch input, handed to
272
+ * the adapter so it does not rederive it per input per delivery.
273
+ *
274
+ * Both facts are generation state: the identity is the memoized
275
+ * {@link pathIdentityKey} of the input, and `missing` is the existence the
276
+ * generation recorded and every cache hit revalidates. An adapter that computes
277
+ * them itself pays a `realpath`, a case-sensitivity directory listing, and an
278
+ * `existsSync` for every input of every delivered module, which is O(modules x
279
+ * inputs) for one build (samchon/ttsc#1246).
280
+ */
281
+ export interface TtscWatchInputEvidence {
282
+ /** Memoized filesystem identity of the input. */
283
+ identity: string;
284
+ /** Whether the generation recorded this input as absent. */
285
+ missing: boolean;
286
+ }
287
+ /**
288
+ * Hooks the bundler adapter passes into {@link transformTtsc} so transform
289
+ * side-channels (plugin-reported dependencies and host resolution candidates)
290
+ * reach the bundler without leaking extra fields on the returned
291
+ * `TransformResult`.
292
+ */
293
+ export interface TtscTransformHooks {
294
+ /**
295
+ * Invoked once per absolute watch-input path derived for the transformed file
296
+ * `F`: the plugin-reported `dependencies[F]` list unioned with the host-owned
297
+ * reference graph's contribution — the reachability closure of `graph.edges`
298
+ * from `F`, the `graph.globals` files, the `graph.configs` chain, and missing
299
+ * higher-priority `graph.candidates` — or, for a file the envelope declared
300
+ * `dependenciesComplete`, only `dependencies[F]`, `graph.candidates`, and the
301
+ * universal `graph.configs` chain. Adapters forward this to the bundler's
302
+ * `addWatchFile` so type-only inputs participate in watch-mode and
303
+ * persistent-cache invalidation. See {@link selectWatchInputs} for the exact
304
+ * derivation.
305
+ */
306
+ addWatchFile?: (file: string, evidence?: TtscWatchInputEvidence) => void;
307
+ /**
308
+ * Invoked when the plugin declared the transformed file volatile (the
309
+ * envelope's `volatile` list): its output depends on non-file inputs that no
310
+ * file-dependency snapshot can represent. Adapters should mark the module
311
+ * uncacheable where the bundler exposes that control (e.g. a webpack loader
312
+ * context's `cacheable(false)`).
313
+ */
314
+ markVolatile?: () => void;
315
+ }
316
+ /**
317
+ * Apply the ttsc plugin transform to a single source file.
318
+ *
319
+ * The function is intentionally project-scoped: it compiles the entire tsconfig
320
+ * project in one shot and extracts the result for `id`. Subsequent calls for
321
+ * sibling files in the same project reuse the cached result as long as none of
322
+ * the project's input files have changed (verified by comparing SHA-256
323
+ * hashes).
324
+ *
325
+ * Returns `undefined` when no transform is needed (declaration files, virtual
326
+ * modules, disabled plugins, or source unchanged after transform).
327
+ *
328
+ * @param id - Bundler module id (may carry a query string or virtual prefix).
329
+ * @param source - Current file content supplied by the bundler.
330
+ * @param options - Resolved plugin options.
331
+ * @param aliases - Raw bundler alias configuration (Vite array or webpack
332
+ * object).
333
+ * @param cache - Optional project cache. Callers with a real `buildStart`
334
+ * boundary declare it through {@link beginTtscTransformBuild}; other hosts
335
+ * retain persistent validation.
336
+ * @param hooks - Optional adapter callbacks; see {@link TtscTransformHooks}.
337
+ * Dependency notifications fire on cache hits too; watch registrations are
338
+ * per build, not per compilation.
339
+ */
340
+ export declare function transformTtsc(id: string, source: string, options: ResolvedTtscUnpluginOptions, aliases?: unknown, cache?: TtscTransformCache, hooks?: TtscTransformHooks): Promise<TtscTransformResult | undefined>;
341
+ interface TtscHostInputValidation {
342
+ /** Lexical input spellings that existed when the generation was captured. */
343
+ readonly entries: Map<string, {
344
+ path: string;
345
+ /**
346
+ * Whether the recorded state of this input came from reading its bytes.
347
+ * An input that existed but could not be read records a missing state, so
348
+ * no signature may stand in for it: its metadata holds still while the
349
+ * bytes behind it appear.
350
+ */
351
+ readable: boolean;
352
+ realpath: string | null;
353
+ /**
354
+ * The signature that may stand in for this entry's content comparison, or
355
+ * `undefined` when none may. A blocker keeps one regardless: it proves a
356
+ * kind and an identity rather than content.
357
+ */
358
+ signature: string | undefined;
359
+ strict?: true;
360
+ }>;
361
+ /**
362
+ * Lexical spellings the manifest accounts for, omitted from the per-module
363
+ * dependency loop below.
364
+ *
365
+ * Spellings, not identities: a symlink and its target share one identity but
366
+ * are two inputs, and skipping the alias because the manifest proved the
367
+ * target would leave the alias's own retarget unvalidated.
368
+ */
369
+ readonly covered: Set<string>;
370
+ /**
371
+ * Missing paths grouped by the nearest directory whose listing proves them
372
+ * absent.
373
+ */
374
+ readonly missing: Map<string, Set<string>>;
375
+ }
376
+ /**
377
+ * Strip a query string or hash fragment from a bundler module id.
378
+ *
379
+ * Vite appends query parameters (e.g. `?raw`, `?url`, `?inline`) to
380
+ * differentiate import variants of the same file. We must strip them before
381
+ * using the id as a file-system path.
382
+ */
383
+ export declare function stripQuery(id: string): string;
384
+ /**
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.
389
+ */
390
+ export declare function isDeclarationFile(id: string): boolean;
391
+ /**
392
+ * Build the unplugin transform result, or `undefined` when the transform
393
+ * produced no changes.
394
+ *
395
+ * Returning `undefined` instead of `{ code: source }` lets the bundler skip the
396
+ * unnecessary module update and preserves the original source map.
397
+ */
398
+ export declare function createTransformResult(source: string, code: string): TtscTransformResult | undefined;
399
+ /**
400
+ * Hash every input file under `projectRoot` (the same walk universe
401
+ * {@link matchesCachedSource} validates against), keyed by project-relative
402
+ * slash path. Exported so hosts without a per-build boundary (`@ttsc/metro`)
403
+ * can fold the identical input universe into their own cache fingerprints.
404
+ */
405
+ export declare function collectProjectInputHashes(projectRoot: string, identities?: FilesystemPathIdentityContext, filesystem?: TtscTransformFilesystemOperations): Record<string, string>;
406
+ /**
407
+ * Report whether an absolute `file` belongs to the project walk universe of
408
+ * `root`: it lies under `root`, every component exists without traversing a
409
+ * symbolic link, the leaf is a regular file, and no segment of the relative
410
+ * path is ignored. The predicate mirrors {@link walkProjectInputs} exactly, so
411
+ * "walk-visible" here means "hashed by {@link collectProjectInputHashes}".
412
+ * Missing paths and files reached through symlinks or Windows junctions are
413
+ * out-of-walk inputs that only the reference graph can prove relevant.
414
+ */
415
+ export declare function isProjectWalkPath(root: string, file: string, _identities?: FilesystemPathIdentityContext, filesystem?: TtscTransformFilesystemOperations): boolean;
416
+ /**
417
+ * Hash a list of absolute out-of-walk input paths: content SHA-256 for a
418
+ * readable file, a stable directory-kind digest for a directory candidate, and
419
+ * a stable `missing` marker otherwise. Keys use filesystem identity so
420
+ * case-only spellings share one snapshot entry, while reads retain the original
421
+ * path supplied by the compiler. The marker is state, not an error — a recorded
422
+ * input disappearing (or reappearing) must change the comparison exactly like a
423
+ * content edit. Exported so `@ttsc/metro` can re-hash its recorded snapshot
424
+ * with identical semantics at cache-key time.
425
+ */
426
+ export declare function collectExternalInputHashes(paths: readonly string[], filesystem?: TtscTransformFilesystemOperations): Record<string, string>;
427
+ /**
428
+ * Build a comparison key for a path without changing the spelling handed to a
429
+ * filesystem or bundler. Windows is case-insensitive; macOS is probed per
430
+ * existing filesystem location so case-sensitive volumes keep distinct paths.
431
+ */
432
+ export declare function pathIdentityKey(file: string, identities?: FilesystemPathIdentityContext): string;
433
+ export {};