@ttsc/metro 0.30.3 → 0.31.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.
Files changed (62) hide show
  1. package/README.md +11 -6
  2. package/lib/core/SnapshotReadOperations.d.ts +119 -0
  3. package/lib/core/SnapshotReadOperations.js +3 -0
  4. package/lib/core/SnapshotReadOperations.js.map +1 -0
  5. package/lib/core/SnapshotReadOperations.mjs +2 -0
  6. package/lib/core/SnapshotReadOperations.mjs.map +1 -0
  7. package/lib/core/TtscMetroOptions.d.ts +119 -0
  8. package/lib/core/TtscMetroOptions.js +3 -0
  9. package/lib/core/TtscMetroOptions.js.map +1 -0
  10. package/lib/core/TtscMetroOptions.mjs +2 -0
  11. package/lib/core/TtscMetroOptions.mjs.map +1 -0
  12. package/lib/core/TtscMetroProjectView.d.ts +64 -0
  13. package/lib/core/TtscMetroProjectView.js +3 -0
  14. package/lib/core/TtscMetroProjectView.js.map +1 -0
  15. package/lib/core/TtscMetroProjectView.mjs +2 -0
  16. package/lib/core/TtscMetroProjectView.mjs.map +1 -0
  17. package/lib/core/UpstreamTransformer.d.ts +127 -0
  18. package/lib/core/UpstreamTransformer.js +3 -0
  19. package/lib/core/UpstreamTransformer.js.map +1 -0
  20. package/lib/core/UpstreamTransformer.mjs +2 -0
  21. package/lib/core/UpstreamTransformer.mjs.map +1 -0
  22. package/lib/core/fingerprint.d.ts +442 -97
  23. package/lib/core/fingerprint.js +838 -83
  24. package/lib/core/fingerprint.js.map +1 -1
  25. package/lib/core/fingerprint.mjs +839 -84
  26. package/lib/core/fingerprint.mjs.map +1 -1
  27. package/lib/core/options.d.ts +81 -58
  28. package/lib/core/options.js +81 -4
  29. package/lib/core/options.js.map +1 -1
  30. package/lib/core/options.mjs +81 -4
  31. package/lib/core/options.mjs.map +1 -1
  32. package/lib/core/remapAstLocations.d.ts +76 -0
  33. package/lib/core/remapAstLocations.js +205 -0
  34. package/lib/core/remapAstLocations.js.map +1 -0
  35. package/lib/core/remapAstLocations.mjs +203 -0
  36. package/lib/core/remapAstLocations.mjs.map +1 -0
  37. package/lib/core/upstream.d.ts +97 -27
  38. package/lib/core/upstream.js +109 -8
  39. package/lib/core/upstream.js.map +1 -1
  40. package/lib/core/upstream.mjs +109 -9
  41. package/lib/core/upstream.mjs.map +1 -1
  42. package/lib/index.d.ts +50 -2
  43. package/lib/index.js +88 -24
  44. package/lib/index.js.map +1 -1
  45. package/lib/index.mjs +89 -25
  46. package/lib/index.mjs.map +1 -1
  47. package/lib/transformer.d.ts +183 -6
  48. package/lib/transformer.js +209 -14
  49. package/lib/transformer.js.map +1 -1
  50. package/lib/transformer.mjs +211 -16
  51. package/lib/transformer.mjs.map +1 -1
  52. package/package.json +7 -18
  53. package/src/core/SnapshotReadOperations.ts +121 -0
  54. package/src/core/TtscMetroOptions.ts +127 -0
  55. package/src/core/TtscMetroProjectView.ts +74 -0
  56. package/src/core/UpstreamTransformer.ts +126 -0
  57. package/src/core/fingerprint.ts +987 -109
  58. package/src/core/options.ts +85 -62
  59. package/src/core/remapAstLocations.ts +219 -0
  60. package/src/core/upstream.ts +110 -26
  61. package/src/index.ts +99 -28
  62. package/src/transformer.ts +214 -17
package/lib/index.mjs CHANGED
@@ -1,9 +1,12 @@
1
- import { readFileSync, realpathSync } from 'node:fs';
1
+ import { openTtscTransformSession } from '@ttsc/unplugin/api';
2
+ import { readFileSync } from 'node:fs';
2
3
  import { createRequire } from 'node:module';
3
4
  import { join, dirname, resolve, basename } from 'node:path';
4
5
  import { fileURLToPath } from 'node:url';
6
+ import { createFilesystemPathIdentityContext } from 'ttsc/path-identity';
5
7
  import { prepareSnapshot } from './core/fingerprint.mjs';
6
8
  import { ENV_KEY, serializeOptions } from './core/options.mjs';
9
+ import { locateProjectUpstreamTransformer } from './core/upstream.mjs';
7
10
 
8
11
  /**
9
12
  * `@ttsc/metro`: Metro (React Native / Expo) adapter for ttsc plugins.
@@ -54,14 +57,65 @@ import { ENV_KEY, serializeOptions } from './core/options.mjs';
54
57
  * `.svg` to the auto-detected Expo default instead, with the build still
55
58
  * succeeding (samchon/ttsc#1321). An explicit `upstreamTransformer` option
56
59
  * still wins, since that is the caller saying it outright.
60
+ *
61
+ * The call also has side effects beyond the returned config, all before Metro
62
+ * forks its workers. It prepares the cache-key snapshot under
63
+ * `<projectRoot>/node_modules/.cache/ttsc-metro` (creating it, merging the
64
+ * previous workers' records into it under a lock, and sweeping stale files),
65
+ * and it opens the shared compile session whose path the workers inherit
66
+ * through the environment. A snapshot that cannot be prepared never fails the
67
+ * call: the run takes a private token that makes its cache key non-reusable.
68
+ *
69
+ * @evidence contracts/common.md#principled-implementation
70
+ * Metro's supported babelTransformerPath boundary installs this adapter by
71
+ * cloning the config. Node project resolution preserves an existing upstream
72
+ * unless explicitly overridden, and realpath/package ownership filters
73
+ * inherited self-selection; explicit upstream choices remain caller-owned.
74
+ * Only the owned option/session environment channels are published before
75
+ * workers start; foreign loaders and methods are not patched.
76
+ *
77
+ * @evidence contracts/common.md#clear-and-simple-design
78
+ * The entry point prepares run ownership and worker transport, then clones
79
+ * the config's transformer field. Separate helpers own upstream inheritance
80
+ * and module identity instead of repeating those policies in workers.
81
+ *
82
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
83
+ * Decision values come from the documented inputs and product protocol
84
+ * rather than expected test answers. No compensating path is introduced to
85
+ * make a known example pass.
86
+ *
87
+ * @evidence contracts/portability.md#os-neutral-implementation
88
+ * Node paths, createRequire and fileURLToPath resolve native paths and module
89
+ * URLs. The shared filesystem-identity resolver handles links and actual
90
+ * directory case capabilities in the recursion guard, instead of folding
91
+ * all names by OS. Worker options use JSON environment inheritance.
92
+ *
93
+ * @evidence contracts/common.md#meaningful-documentation
94
+ * The native JSDoc explains config preservation, upstream precedence, JSON
95
+ * worker transport and preparation side effects. Checked against the
96
+ * documentation skill: separate paragraphs state the contract and why its
97
+ * nonobvious boundary matters; field comments retain their own useful
98
+ * facts.
99
+ *
100
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
101
+ * The compaction lock it takes is released in prepareSnapshot's finally block and the session store is owned by its opener; withTtsc retains no handle itself.
102
+ *
103
+ * @evidenceExclude contracts/performance.md#efficient-algorithms
104
+ * Constant work per call besides the snapshot preparation that prepareSnapshot owns.
105
+ *
106
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
107
+ * Runs once per Metro config load; the snapshot and compile session it opens are what the workers share.
57
108
  */
58
109
  function withTtsc(config, options = {}) {
59
110
  // Prepare the reference-graph snapshot backing the transformer's cache-key
60
111
  // fingerprint (see `core/fingerprint.ts`). This runs in the single Metro
61
- // config process before any worker exists, so it is the race-free moment to
62
- // mint the snapshot epoch and compact the previous run's worker files.
112
+ // config process before its workers exist. The snapshot owner serializes
113
+ // concurrent config processes while compacting the previous worker records.
63
114
  const snapshotRunId = prepareSnapshot(typeof config.projectRoot === "string" ? config.projectRoot : undefined);
64
115
  process.env[ENV_KEY] = serializeOptions(inheritConfiguredTransformer(config, options), snapshotRunId);
116
+ // The workers Metro forks next inherit the session, so the pool compiles
117
+ // each generation once between them (samchon/ttsc#1390).
118
+ openTtscTransformSession();
65
119
  return {
66
120
  ...config,
67
121
  transformer: {
@@ -84,11 +138,24 @@ function withTtsc(config, options = {}) {
84
138
  * and delegate into itself.
85
139
  */
86
140
  function inheritConfiguredTransformer(config, options) {
141
+ // An explicit option is the caller's module, so it resolves from the project
142
+ // as a declared `babelTransformerPath` does; an empty one asks for detection.
143
+ if (options.upstreamTransformer !== undefined &&
144
+ options.upstreamTransformer.length !== 0) {
145
+ return {
146
+ ...options,
147
+ upstreamTransformer: resolveFromProject(options.upstreamTransformer, config),
148
+ };
149
+ }
87
150
  const declared = config.transformer?.babelTransformerPath;
88
- if (options.upstreamTransformer !== undefined ||
89
- typeof declared !== "string" ||
90
- declared.length === 0) {
91
- return options;
151
+ if (typeof declared !== "string" || declared.length === 0) {
152
+ // Automatic detection belongs here too: the candidates are the app's
153
+ // packages, and only this process knows the project to look in. Nothing
154
+ // found leaves the worker's own probe to report it.
155
+ const located = locateProjectUpstreamTransformer((specifier) => projectRequire(config).resolve(specifier));
156
+ return located === undefined
157
+ ? options
158
+ : { ...options, upstreamTransformer: located };
92
159
  }
93
160
  // Resolve before judging. Ownership is a property of the module, not of the
94
161
  // string, and every spelling has to become one absolute path before either
@@ -126,16 +193,20 @@ function inheritConfiguredTransformer(config, options) {
126
193
  * somewhere less legible.
127
194
  */
128
195
  function resolveFromProject(declared, config) {
129
- const base = typeof config.projectRoot === "string" && config.projectRoot.length !== 0
130
- ? config.projectRoot
131
- : process.cwd();
132
196
  try {
133
- return createRequire(join(resolve(base), "package.json")).resolve(declared);
197
+ return projectRequire(config).resolve(declared);
134
198
  }
135
199
  catch {
136
200
  return declared;
137
201
  }
138
202
  }
203
+ /** A `require` rooted in the Metro project, the owner of its transformers. */
204
+ function projectRequire(config) {
205
+ const base = typeof config.projectRoot === "string" && config.projectRoot.length !== 0
206
+ ? config.projectRoot
207
+ : process.cwd();
208
+ return createRequire(join(resolve(base), "package.json"));
209
+ }
139
210
  /**
140
211
  * Whether a `babelTransformerPath` already points at a `@ttsc/metro`
141
212
  * transformer — this copy or any other.
@@ -173,22 +244,15 @@ function isOwnTransformer(declared) {
173
244
  /**
174
245
  * Whether two paths name the same file on disk.
175
246
  *
176
- * Resolved through `realpath` so a symlinked install and its target compare
177
- * equal, and case-folded on Windows, where `D:\` and `d:\` and a differently
178
- * cased base name all address one file.
247
+ * The shared resolver observes physical spelling and directory capabilities
248
+ * within this comparison. Symlinks can identify the same installed file while
249
+ * case-sensitive native names remain distinct.
179
250
  */
180
251
  function sameRealPath(left, right) {
181
- const identity = (file) => {
182
- let resolved = resolve(file);
183
- try {
184
- resolved = realpathSync.native(resolved);
185
- }
186
- catch {
187
- // Not on disk: the resolved spelling is the best identity available.
188
- }
189
- return process.platform === "win32" ? resolved.toLowerCase() : resolved;
190
- };
191
- return identity(left) === identity(right);
252
+ const identities = createFilesystemPathIdentityContext({
253
+ throwOnRealpathError: false,
254
+ });
255
+ return identities.resolve(left).key === identities.resolve(right).key;
192
256
  }
193
257
  /**
194
258
  * Absolute path to the built transformer module Metro will `require`.
package/lib/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ResolvedTtscMetroOptions } from "./core/options";
1
+ import type { ResolvedTtscMetroOptions } from "./core/TtscMetroOptions";
2
2
  /**
3
3
  * Resolve Metro's per-file `filename` to an absolute path.
4
4
  *
@@ -10,6 +10,39 @@ import type { ResolvedTtscMetroOptions } from "./core/options";
10
10
  * monorepos and when Metro is launched from a parent directory. Getting this
11
11
  * wrong makes every file look "outside the project" and silently skips the
12
12
  * plugin pass.
13
+ *
14
+ * @evidence contracts/common.md#principled-implementation
15
+ * Node path.isAbsolute/path.resolve implement Metro's filename contract.
16
+ * Absolute input is retained; relative input is anchored at supplied
17
+ * projectRoot, with cwd only for callers lacking that option.
18
+ *
19
+ * @evidence contracts/common.md#clear-and-simple-design
20
+ * This helper owns the single relative-to-absolute boundary, keeping Metro's
21
+ * original filename separate from the compiler address.
22
+ *
23
+ * @evidenceExclude contracts/performance.md#efficient-algorithms
24
+ * This operation chooses a base and delegates native path resolution;
25
+ * it owns no input collection or processing strategy.
26
+ *
27
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
28
+ * It maps one filename and supplied options without shared computation.
29
+ *
30
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
31
+ * The returned path transfers to its caller; no resource is retained.
32
+ *
33
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
34
+ * This correct owning anchor avoids monorepo misrouting without matching
35
+ * error text or special-casing fixture names.
36
+ *
37
+ * @evidence contracts/portability.md#os-neutral-implementation
38
+ * Node path handles native separators, roots and drive letters. No URLs or
39
+ * shell commands are mixed with filenames and no filesystem is changed.
40
+ *
41
+ * @evidence contracts/common.md#meaningful-documentation
42
+ * The native JSDoc explains the project-relative input, absolute result and
43
+ * cwd fallback reason. Checked against the documentation skill: separate
44
+ * paragraphs state the contract and why its nonobvious boundary matters;
45
+ * field comments retain their own useful facts.
13
46
  */
14
47
  export declare function resolveAbsoluteFilename(filename: string, options?: Record<string, unknown>): string;
15
48
  /**
@@ -19,7 +52,60 @@ export declare function resolveAbsoluteFilename(filename: string, options?: Reco
19
52
  * Expo/React-Native Babel transformer to produce the AST Metro expects. The
20
53
  * upstream call receives Metro's original params (notably the project-relative
21
54
  * `filename`, which Babel expects); only `src` is replaced with the
22
- * ttsc-transformed source.
55
+ * ttsc-transformed source. When the adapter returns a source map for that
56
+ * source, the upstream AST's locations are moved back through it to the
57
+ * author's lines, because Metro maps the AST against the file it read
58
+ * (samchon/ttsc#1392).
59
+ *
60
+ * An explicit `project` option selects its tsconfig. Otherwise the adapter
61
+ * discovers the nearest tsconfig and follows its references to the project
62
+ * admitting the file, using Metro's `projectRoot` or the current working
63
+ * directory to resolve a relative file.
64
+ *
65
+ * @evidence contracts/common.md#principled-implementation
66
+ * Metro's transformer callback composes the shared Unplugin transform core
67
+ * with the selected Babel transformer. One resolved project view is frozen
68
+ * into compilation and recorder inputs. Noneligible or out-of-program files
69
+ * follow the shared core contract; genuine compiler/load failures propagate.
70
+ *
71
+ * @evidence contracts/common.md#clear-and-simple-design
72
+ * The entry point gates delivery, freezes one project view for compilation
73
+ * and recording, then delegates to Babel. Shared core helpers own checking
74
+ * and caching; the adapter owns only Metro transport and AST remapping.
75
+ *
76
+ * @evidence contracts/performance.md#efficient-algorithms
77
+ * Filtering runs before compilation. Eligible deliveries resolve one view
78
+ * and record their inputs in a single batch; compiler and AST traversal
79
+ * costs belong to their delegated owners rather than repeated per input.
80
+ *
81
+ * @evidence contracts/performance.md#reuse-equivalent-work
82
+ * The worker's shared transform cache validates project state on each hit,
83
+ * while the inherited session shares compilation across workers. The same
84
+ * project view and options feed compilation and generation recording; Babel
85
+ * is invoked for the actual delivery and is not memoized by this adapter.
86
+ *
87
+ * @evidence contracts/performance.md#bound-retention-and-release-resources
88
+ * Worker singletons own resolved options, the transform cache and recorder
89
+ * until process termination. The shared core owns cached generations and
90
+ * session storage; the recorder owns its cumulative paths. This entry point
91
+ * exposes no disposal signal from Metro and does not claim a fixed byte bound.
92
+ *
93
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
94
+ * Only the returned AST's owned locations are updated, with no patched
95
+ * loader or test-specific production behavior.
96
+ *
97
+ * @evidence contracts/portability.md#os-neutral-implementation
98
+ * Metro-relative filenames drive substring filters; Node path.resolve
99
+ * produces absolute compiler addresses. The shared core owns native
100
+ * compiler/session access, while Babel retains the original filename.
101
+ * Worker transport is JSON and no shell command is constructed here.
102
+ *
103
+ * @evidence contracts/common.md#meaningful-documentation
104
+ * The native JSDoc explains pass order, original parameter preservation,
105
+ * project selection and AST location mutation. Checked against the
106
+ * documentation skill: separate paragraphs state the contract and why its
107
+ * nonobvious boundary matters; field comments retain their own useful
108
+ * facts.
23
109
  */
24
110
  export declare function transform(params: {
25
111
  src: string;
@@ -48,14 +134,105 @@ export declare function transform(params: {
48
134
  * A change to any fingerprinted input re-keys every transformed file at
49
135
  * project-level granularity, forced by Metro's single static key, replacing the
50
136
  * former manual `--reset-cache` step. Resolving the upstream is deliberately
51
- * non-fatal here: a missing peer must not crash cache-key computation. See the
52
- * README "Caveats" and samchon/ttsc#721.
137
+ * non-fatal here: a missing peer must not crash cache-key computation, but a
138
+ * failed upstream key withdraws reuse with a nonce. See the README "Caveats"
139
+ * and samchon/ttsc#721.
140
+ *
141
+ * @evidence contracts/common.md#principled-implementation
142
+ * Node sha256 combines package identity, stable resolved options, forwarded
143
+ * upstream key and the project fingerprint required by Metro's
144
+ * one-static-key contract. Failed upstream loads or callbacks contribute a
145
+ * nonce; an absent optional callback contributes no additional key.
146
+ * Forwarded compiler and plugin records retain their JSON property order
147
+ * because the compiler or a plugin can give that order semantic meaning.
148
+ * Fingerprint failure disables reuse through a nonce rather
149
+ * than fabricating a proven generation.
150
+ *
151
+ * @evidence contracts/common.md#clear-and-simple-design
152
+ * One hash assembly combines options, upstream contribution and the project
153
+ * fingerprint. The fingerprint owner handles persistence and validity;
154
+ * cacheKeyProjectRoot extracts Metro's argument without duplicating discovery.
155
+ *
156
+ * @evidence contracts/performance.md#efficient-algorithms
157
+ * One static key per Metro run hashes encoded options, the upstream key
158
+ * and one project fingerprint. Key assembly is linear in their string bytes;
159
+ * the fingerprint owner accounts for project scans and config traversal.
160
+ *
161
+ * @evidence contracts/performance.md#reuse-equivalent-work
162
+ * Options, adapter version, upstream key and exact project state contribute
163
+ * to the shared key. Project observation failures withdraw reuse through a
164
+ * nonce. A failing upstream load or key uses a nonce too, preserving the
165
+ * nonfatal keying boundary without pretending its external state is known.
166
+ *
167
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
168
+ * The hash is local to this call. Worker singletons are owned by transform
169
+ * and persisted baseline files by prepareSnapshot, not the hash assembler.
170
+ *
171
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
172
+ * Decision values come from the documented inputs and product protocol
173
+ * rather than expected test answers. No compensating path is introduced to
174
+ * make a known example pass.
175
+ *
176
+ * @evidence contracts/portability.md#os-neutral-implementation
177
+ * Native project roots are interpreted by the fingerprint owner and Node
178
+ * module loading reads package identity. Hash input has deterministic
179
+ * string representation across OSes; filesystem content and identity remain
180
+ * deliberately host-specific.
181
+ *
182
+ * @evidence contracts/common.md#meaningful-documentation
183
+ * The native JSDoc explains one key per run, all contributions,
184
+ * project-wide invalidation and nonfatal upstream key policy. Checked
185
+ * against the documentation skill: separate paragraphs state the contract
186
+ * and why its nonobvious boundary matters; field comments retain their own
187
+ * useful facts.
53
188
  */
54
189
  export declare function getCacheKey(...args: unknown[]): string;
55
190
  /**
56
191
  * Decide whether a file should run through the ttsc pass. Only TypeScript
57
192
  * sources (`.ts`/`.tsx`/`.mts`/`.cts`, excluding every declaration form)
58
- * qualify; `exclude` substrings win over `include`, and an empty `include`
59
- * means "all TypeScript". Exported for unit testing.
193
+ * qualify, and a file below a `node_modules` directory never does, whatever
194
+ * `include` says, because the shared `isTransformTarget` predicate rejects it
195
+ * first. `exclude` substrings win over `include`, and an empty `include` means
196
+ * "all eligible TypeScript". Patterns use the supplied project-relative
197
+ * filename literally; this operation does not normalize separators or
198
+ * filesystem case.
199
+ *
200
+ * @evidence contracts/common.md#principled-implementation
201
+ * The shared isTransformTarget predicate owns supported TypeScript
202
+ * extensions, declaration exclusions, virtual-module and node_modules
203
+ * exclusions. Literal substring filters apply to Metro's project-relative
204
+ * filename, with exclusion taking precedence.
205
+ *
206
+ * @evidence contracts/common.md#clear-and-simple-design
207
+ * This predicate orders extension eligibility, exclusion and inclusion as
208
+ * early returns. Compiler execution remains outside the filtering policy.
209
+ *
210
+ * @evidence contracts/performance.md#efficient-algorithms
211
+ * Extension matching precedes substring scans; exclusion returns early and
212
+ * inclusion stops at its first match. Cost follows pattern count and supplied
213
+ * filename length without allocating a normalized copy for literal matching.
214
+ *
215
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
216
+ * This inexpensive predicate coordinates no shared computation and accepts
217
+ * caller-owned, potentially mutable option arrays.
218
+ *
219
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
220
+ * Filtering retains no caller data and opens no native resource.
221
+ *
222
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
223
+ * This pure decision neither invokes compilation nor mutates options, and
224
+ * has no fixture or test-mode branch.
225
+ *
226
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation
227
+ * This predicate matches TypeScript extensions and caller-supplied literal
228
+ * substrings. It defines no filesystem identity or native path
229
+ * normalization contract.
230
+ *
231
+ * @evidence contracts/common.md#meaningful-documentation
232
+ * The native JSDoc explains eligible extensions, declaration and
233
+ * node_modules exclusion, empty include and exclusion precedence. Checked
234
+ * against the documentation skill: separate paragraphs state the contract
235
+ * and why its nonobvious boundary matters; field comments retain their own
236
+ * useful facts.
60
237
  */
61
238
  export declare function shouldTransform(filename: string, opts: ResolvedTtscMetroOptions): boolean;