@ttsc/metro 0.30.4 → 0.31.1

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
@@ -1,9 +1,10 @@
1
- import { createTtscTransformCache, isTransformTarget, resolveOptions, transformTtsc } from '@ttsc/unplugin/api';
2
- import { createHash } from 'node:crypto';
1
+ import { createTtscTransformCache, shareTtscTransformCache, readTtscTransformSession, isTransformTarget, resolveOptions, transformTtsc } from '@ttsc/unplugin/api';
2
+ import { createHash, randomBytes } from 'node:crypto';
3
3
  import { createRequire } from 'node:module';
4
4
  import path from 'node:path';
5
5
  import { stableStringify, computeProjectFingerprint, resolveProjectView, createSnapshotRecorder } from './core/fingerprint.mjs';
6
6
  import { resolveOptionsFromEnv } from './core/options.mjs';
7
+ import { remapAstLocations } from './core/remapAstLocations.mjs';
7
8
  import { resolveUpstreamTransformer } from './core/upstream.mjs';
8
9
 
9
10
  /**
@@ -22,6 +23,11 @@ import { resolveUpstreamTransformer } from './core/upstream.mjs';
22
23
  * generation hit. Cross-file invalidation also rides the project fingerprint
23
24
  * {@link getCacheKey} folds into Metro's static transformer key (see
24
25
  * `core/fingerprint.ts`).
26
+ *
27
+ * The adapter passes no `watching` declaration in its hooks, so a project whose
28
+ * plugin observations are unavailable (a generation the core can only serve
29
+ * fresh) fails the transform with an explicit error instead of caching it: the
30
+ * core refuses fresh-only output unless the host states it is not watching.
25
31
  */
26
32
  const nodeRequire = createRequire(import.meta.url);
27
33
  /**
@@ -33,6 +39,9 @@ const nodeRequire = createRequire(import.meta.url);
33
39
  let resolved;
34
40
  let unpluginOptions;
35
41
  const cache = createTtscTransformCache();
42
+ // Metro's workers share each compile through the session `withTtsc` opened
43
+ // (samchon/ttsc#1390).
44
+ shareTtscTransformCache(cache, readTtscTransformSession());
36
45
  let snapshotRecorder;
37
46
  /** Lazily resolve the worker-side options (from {@link resolveOptionsFromEnv}). */
38
47
  function options() {
@@ -54,6 +63,39 @@ function recorder() {
54
63
  * monorepos and when Metro is launched from a parent directory. Getting this
55
64
  * wrong makes every file look "outside the project" and silently skips the
56
65
  * plugin pass.
66
+ *
67
+ * @evidence contracts/common.md#principled-implementation
68
+ * Node path.isAbsolute/path.resolve implement Metro's filename contract.
69
+ * Absolute input is retained; relative input is anchored at supplied
70
+ * projectRoot, with cwd only for callers lacking that option.
71
+ *
72
+ * @evidence contracts/common.md#clear-and-simple-design
73
+ * This helper owns the single relative-to-absolute boundary, keeping Metro's
74
+ * original filename separate from the compiler address.
75
+ *
76
+ * @evidenceExclude contracts/performance.md#efficient-algorithms
77
+ * This operation chooses a base and delegates native path resolution;
78
+ * it owns no input collection or processing strategy.
79
+ *
80
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
81
+ * It maps one filename and supplied options without shared computation.
82
+ *
83
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
84
+ * The returned path transfers to its caller; no resource is retained.
85
+ *
86
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
87
+ * This correct owning anchor avoids monorepo misrouting without matching
88
+ * error text or special-casing fixture names.
89
+ *
90
+ * @evidence contracts/portability.md#os-neutral-implementation
91
+ * Node path handles native separators, roots and drive letters. No URLs or
92
+ * shell commands are mixed with filenames and no filesystem is changed.
93
+ *
94
+ * @evidence contracts/common.md#meaningful-documentation
95
+ * The native JSDoc explains the project-relative input, absolute result and
96
+ * cwd fallback reason. Checked against the documentation skill: separate
97
+ * paragraphs state the contract and why its nonobvious boundary matters;
98
+ * field comments retain their own useful facts.
57
99
  */
58
100
  function resolveAbsoluteFilename(filename, options) {
59
101
  if (path.isAbsolute(filename)) {
@@ -71,7 +113,60 @@ function resolveAbsoluteFilename(filename, options) {
71
113
  * Expo/React-Native Babel transformer to produce the AST Metro expects. The
72
114
  * upstream call receives Metro's original params (notably the project-relative
73
115
  * `filename`, which Babel expects); only `src` is replaced with the
74
- * ttsc-transformed source.
116
+ * ttsc-transformed source. When the adapter returns a source map for that
117
+ * source, the upstream AST's locations are moved back through it to the
118
+ * author's lines, because Metro maps the AST against the file it read
119
+ * (samchon/ttsc#1392).
120
+ *
121
+ * An explicit `project` option selects its tsconfig. Otherwise the adapter
122
+ * discovers the nearest tsconfig and follows its references to the project
123
+ * admitting the file, using Metro's `projectRoot` or the current working
124
+ * directory to resolve a relative file.
125
+ *
126
+ * @evidence contracts/common.md#principled-implementation
127
+ * Metro's transformer callback composes the shared Unplugin transform core
128
+ * with the selected Babel transformer. One resolved project view is frozen
129
+ * into compilation and recorder inputs. Noneligible or out-of-program files
130
+ * follow the shared core contract; genuine compiler/load failures propagate.
131
+ *
132
+ * @evidence contracts/common.md#clear-and-simple-design
133
+ * The entry point gates delivery, freezes one project view for compilation
134
+ * and recording, then delegates to Babel. Shared core helpers own checking
135
+ * and caching; the adapter owns only Metro transport and AST remapping.
136
+ *
137
+ * @evidence contracts/performance.md#efficient-algorithms
138
+ * Filtering runs before compilation. Eligible deliveries resolve one view
139
+ * and record their inputs in a single batch; compiler and AST traversal
140
+ * costs belong to their delegated owners rather than repeated per input.
141
+ *
142
+ * @evidence contracts/performance.md#reuse-equivalent-work
143
+ * The worker's shared transform cache validates project state on each hit,
144
+ * while the inherited session shares compilation across workers. The same
145
+ * project view and options feed compilation and generation recording; Babel
146
+ * is invoked for the actual delivery and is not memoized by this adapter.
147
+ *
148
+ * @evidence contracts/performance.md#bound-retention-and-release-resources
149
+ * Worker singletons own resolved options, the transform cache and recorder
150
+ * until process termination. The shared core owns cached generations and
151
+ * session storage; the recorder owns its cumulative paths. This entry point
152
+ * exposes no disposal signal from Metro and does not claim a fixed byte bound.
153
+ *
154
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
155
+ * Only the returned AST's owned locations are updated, with no patched
156
+ * loader or test-specific production behavior.
157
+ *
158
+ * @evidence contracts/portability.md#os-neutral-implementation
159
+ * Metro-relative filenames drive substring filters; Node path.resolve
160
+ * produces absolute compiler addresses. The shared core owns native
161
+ * compiler/session access, while Babel retains the original filename.
162
+ * Worker transport is JSON and no shell command is constructed here.
163
+ *
164
+ * @evidence contracts/common.md#meaningful-documentation
165
+ * The native JSDoc explains pass order, original parameter preservation,
166
+ * project selection and AST location mutation. Checked against the
167
+ * documentation skill: separate paragraphs state the contract and why its
168
+ * nonobvious boundary matters; field comments retain their own useful
169
+ * facts.
75
170
  */
76
171
  async function transform(params) {
77
172
  const opts = options();
@@ -84,6 +179,8 @@ async function transform(params) {
84
179
  return upstream.transform(params);
85
180
  }
86
181
  let transformedSrc = params.src;
182
+ let transformedMap;
183
+ let absoluteFilename = params.filename;
87
184
  {
88
185
  unpluginOptions ??= resolveOptions(opts.ttsc);
89
186
  const projectRoot = typeof params.options.projectRoot === "string"
@@ -91,6 +188,7 @@ async function transform(params) {
91
188
  : undefined;
92
189
  const explicitProject = typeof opts.ttsc.project === "string" ? opts.ttsc.project : undefined;
93
190
  const filename = resolveAbsoluteFilename(params.filename, params.options);
191
+ absoluteFilename = filename;
94
192
  const project = resolveProjectView({
95
193
  compilerOptions: opts.ttsc.compilerOptions,
96
194
  explicitProject,
@@ -136,9 +234,16 @@ async function transform(params) {
136
234
  // Genuine compile and type failures still propagate so Metro surfaces them.
137
235
  if (result !== undefined && typeof result.code === "string") {
138
236
  transformedSrc = result.code;
237
+ transformedMap = result.map;
139
238
  }
140
239
  }
141
- return upstream.transform({ ...params, src: transformedSrc });
240
+ const output = await upstream.transform({ ...params, src: transformedSrc });
241
+ // Metro maps the returned AST against the file it read, so the upstream's
242
+ // positions in the transformed text are moved back to the author's lines.
243
+ if (transformedMap !== undefined) {
244
+ remapAstLocations(output.ast, transformedMap, absoluteFilename);
245
+ }
246
+ return output;
142
247
  }
143
248
  /**
144
249
  * Metro transform-cache key.
@@ -159,23 +264,70 @@ async function transform(params) {
159
264
  * A change to any fingerprinted input re-keys every transformed file at
160
265
  * project-level granularity, forced by Metro's single static key, replacing the
161
266
  * former manual `--reset-cache` step. Resolving the upstream is deliberately
162
- * non-fatal here: a missing peer must not crash cache-key computation. See the
163
- * README "Caveats" and samchon/ttsc#721.
267
+ * non-fatal here: a missing peer must not crash cache-key computation, but a
268
+ * failed upstream key withdraws reuse with a nonce. See the README "Caveats"
269
+ * and samchon/ttsc#721.
270
+ *
271
+ * @evidence contracts/common.md#principled-implementation
272
+ * Node sha256 combines package identity, stable resolved options, forwarded
273
+ * upstream key and the project fingerprint required by Metro's
274
+ * one-static-key contract. Failed upstream loads or callbacks contribute a
275
+ * nonce; an absent optional callback contributes no additional key.
276
+ * Forwarded compiler and plugin records retain their JSON property order
277
+ * because the compiler or a plugin can give that order semantic meaning.
278
+ * Fingerprint failure disables reuse through a nonce rather
279
+ * than fabricating a proven generation.
280
+ *
281
+ * @evidence contracts/common.md#clear-and-simple-design
282
+ * One hash assembly combines options, upstream contribution and the project
283
+ * fingerprint. The fingerprint owner handles persistence and validity;
284
+ * cacheKeyProjectRoot extracts Metro's argument without duplicating discovery.
285
+ *
286
+ * @evidence contracts/performance.md#efficient-algorithms
287
+ * One static key per Metro run hashes encoded options, the upstream key
288
+ * and one project fingerprint. Key assembly is linear in their string bytes;
289
+ * the fingerprint owner accounts for project scans and config traversal.
290
+ *
291
+ * @evidence contracts/performance.md#reuse-equivalent-work
292
+ * Options, adapter version, upstream key and exact project state contribute
293
+ * to the shared key. Project observation failures withdraw reuse through a
294
+ * nonce. A failing upstream load or key uses a nonce too, preserving the
295
+ * nonfatal keying boundary without pretending its external state is known.
296
+ *
297
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
298
+ * The hash is local to this call. Worker singletons are owned by transform
299
+ * and persisted baseline files by prepareSnapshot, not the hash assembler.
300
+ *
301
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
302
+ * Decision values come from the documented inputs and product protocol
303
+ * rather than expected test answers. No compensating path is introduced to
304
+ * make a known example pass.
305
+ *
306
+ * @evidence contracts/portability.md#os-neutral-implementation
307
+ * Native project roots are interpreted by the fingerprint owner and Node
308
+ * module loading reads package identity. Hash input has deterministic
309
+ * string representation across OSes; filesystem content and identity remain
310
+ * deliberately host-specific.
311
+ *
312
+ * @evidence contracts/common.md#meaningful-documentation
313
+ * The native JSDoc explains one key per run, all contributions,
314
+ * project-wide invalidation and nonfatal upstream key policy. Checked
315
+ * against the documentation skill: separate paragraphs state the contract
316
+ * and why its nonobvious boundary matters; field comments retain their own
317
+ * useful facts.
164
318
  */
165
319
  function getCacheKey(...args) {
166
320
  const opts = options();
167
321
  const hash = createHash("sha256");
168
322
  hash.update(`@ttsc/metro:${packageVersion()}`);
169
323
  hash.update(stableStringify({
170
- ttsc: opts.ttsc,
324
+ ttsc: JSON.stringify(opts.ttsc),
171
325
  include: opts.include,
172
326
  exclude: opts.exclude,
173
327
  upstreamTransformer: opts.upstreamTransformer ?? null,
174
328
  }));
175
329
  const upstreamKey = upstreamCacheKey(opts.upstreamTransformer, args);
176
- if (upstreamKey.length !== 0) {
177
- hash.update(upstreamKey);
178
- }
330
+ hash.update(upstreamKey ?? `nonce:${randomBytes(32).toString("hex")}`);
179
331
  hash.update(computeProjectFingerprint({
180
332
  // The same overlay `transform` hands the recorder. Both read these
181
333
  // options from `options()`, so the walk and the recorder judge one
@@ -208,8 +360,9 @@ function cacheKeyProjectRoot(args) {
208
360
  * Fold the upstream transformer's cache key in, defensively. Forwards Metro's
209
361
  * own `getCacheKey` arguments so the upstream's babelrc-derived key is
210
362
  * preserved, and never throws: a missing peer or a throwing upstream
211
- * `getCacheKey` yields an empty contribution rather than failing the whole
212
- * build's cache keying.
363
+ * `getCacheKey` yields `undefined`, withdrawing cross-run reuse without failing
364
+ * the whole build's cache keying. An absent optional callback still contributes
365
+ * the empty string.
213
366
  */
214
367
  function upstreamCacheKey(upstreamTransformer, args) {
215
368
  let upstream;
@@ -217,7 +370,7 @@ function upstreamCacheKey(upstreamTransformer, args) {
217
370
  upstream = resolveUpstreamTransformer(upstreamTransformer);
218
371
  }
219
372
  catch {
220
- return "";
373
+ return undefined;
221
374
  }
222
375
  if (upstream.getCacheKey === undefined) {
223
376
  return "";
@@ -226,14 +379,56 @@ function upstreamCacheKey(upstreamTransformer, args) {
226
379
  return String(upstream.getCacheKey(...args) ?? "");
227
380
  }
228
381
  catch {
229
- return "";
382
+ return undefined;
230
383
  }
231
384
  }
232
385
  /**
233
386
  * Decide whether a file should run through the ttsc pass. Only TypeScript
234
387
  * sources (`.ts`/`.tsx`/`.mts`/`.cts`, excluding every declaration form)
235
- * qualify; `exclude` substrings win over `include`, and an empty `include`
236
- * means "all TypeScript". Exported for unit testing.
388
+ * qualify, and a file below a `node_modules` directory never does, whatever
389
+ * `include` says, because the shared `isTransformTarget` predicate rejects it
390
+ * first. `exclude` substrings win over `include`, and an empty `include` means
391
+ * "all eligible TypeScript". Patterns use the supplied project-relative
392
+ * filename literally; this operation does not normalize separators or
393
+ * filesystem case.
394
+ *
395
+ * @evidence contracts/common.md#principled-implementation
396
+ * The shared isTransformTarget predicate owns supported TypeScript
397
+ * extensions, declaration exclusions, virtual-module and node_modules
398
+ * exclusions. Literal substring filters apply to Metro's project-relative
399
+ * filename, with exclusion taking precedence.
400
+ *
401
+ * @evidence contracts/common.md#clear-and-simple-design
402
+ * This predicate orders extension eligibility, exclusion and inclusion as
403
+ * early returns. Compiler execution remains outside the filtering policy.
404
+ *
405
+ * @evidence contracts/performance.md#efficient-algorithms
406
+ * Extension matching precedes substring scans; exclusion returns early and
407
+ * inclusion stops at its first match. Cost follows pattern count and supplied
408
+ * filename length without allocating a normalized copy for literal matching.
409
+ *
410
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
411
+ * This inexpensive predicate coordinates no shared computation and accepts
412
+ * caller-owned, potentially mutable option arrays.
413
+ *
414
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
415
+ * Filtering retains no caller data and opens no native resource.
416
+ *
417
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
418
+ * This pure decision neither invokes compilation nor mutates options, and
419
+ * has no fixture or test-mode branch.
420
+ *
421
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation
422
+ * This predicate matches TypeScript extensions and caller-supplied literal
423
+ * substrings. It defines no filesystem identity or native path
424
+ * normalization contract.
425
+ *
426
+ * @evidence contracts/common.md#meaningful-documentation
427
+ * The native JSDoc explains eligible extensions, declaration and
428
+ * node_modules exclusion, empty include and exclusion precedence. Checked
429
+ * against the documentation skill: separate paragraphs state the contract
430
+ * and why its nonobvious boundary matters; field comments retain their own
431
+ * useful facts.
237
432
  */
238
433
  function shouldTransform(filename, opts) {
239
434
  if (!isTransformTarget(filename)) {
@@ -1 +1 @@
1
- {"version":3,"file":"transformer.mjs","sources":["../src/transformer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transformer.mjs","sources":["../src/transformer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttsc/metro",
3
- "version": "0.30.4",
3
+ "version": "0.31.1",
4
4
  "description": "Metro (React Native / Expo) adapter for ttsc plugins.",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.mjs",
@@ -35,25 +35,13 @@
35
35
  "src"
36
36
  ],
37
37
  "dependencies": {
38
- "@ttsc/unplugin": "^0.30.4"
38
+ "@ttsc/unplugin": "^0.31.1"
39
39
  },
40
40
  "peerDependencies": {
41
- "@expo/metro-config": "*",
42
- "@react-native/metro-babel-transformer": "*",
43
- "metro-react-native-babel-transformer": "*"
44
- },
45
- "peerDependenciesMeta": {
46
- "@expo/metro-config": {
47
- "optional": true
48
- },
49
- "@react-native/metro-babel-transformer": {
50
- "optional": true
51
- },
52
- "metro-react-native-babel-transformer": {
53
- "optional": true
54
- }
41
+ "ttsc": "^0.31.1"
55
42
  },
56
43
  "devDependencies": {
44
+ "@wrtnlabs/evidence": "^0.3.1",
57
45
  "@rollup/plugin-commonjs": "^29.0.2",
58
46
  "@rollup/plugin-node-resolve": "^16.0.3",
59
47
  "@types/node": "^25.3.0",
@@ -62,7 +50,7 @@
62
50
  "tinyglobby": "^0.2.16",
63
51
  "tslib": "^2.8.1",
64
52
  "typescript": "^7.0.2",
65
- "ttsc": "0.30.4"
53
+ "ttsc": "0.31.1"
66
54
  },
67
55
  "repository": {
68
56
  "type": "git",
@@ -76,6 +64,7 @@
76
64
  "homepage": "https://ttsc.dev",
77
65
  "sideEffects": false,
78
66
  "scripts": {
79
- "build": "rimraf lib && tsc --emitDeclarationOnly && rollup -c"
67
+ "build": "rimraf lib && tsc --emitDeclarationOnly && rollup -c",
68
+ "evidence": "evidence"
80
69
  }
81
70
  }
@@ -0,0 +1,121 @@
1
+ /**
2
+ * The filesystem reads the snapshot reader performs, injectable so a test can
3
+ * drive the interleaving of a listing with a concurrent compaction. Production
4
+ * passes nothing and reads the real filesystem.
5
+ *
6
+ * @evidence contracts/common.md#principled-implementation
7
+ * A structural record of the three Node filesystem reads the snapshot reader
8
+ * makes; the default delegates to node:fs unchanged.
9
+ *
10
+ * @evidence contracts/common.md#clear-and-simple-design
11
+ * One optional parameter carries the read boundary instead of a test mode
12
+ * flag, mirroring the repository's injectable filesystem operations.
13
+ *
14
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
15
+ * Production code never branches on the injection; no fs method is patched.
16
+ *
17
+ * @evidence contracts/common.md#meaningful-documentation
18
+ * The native JSDoc states why the boundary exists and that production uses
19
+ * the real filesystem.
20
+ *
21
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
22
+ * Declares a shape only; it holds no state, handle or buffer.
23
+ *
24
+ * @evidenceExclude contracts/performance.md#efficient-algorithms
25
+ * Declares a shape only; there is no loop or processing in it.
26
+ *
27
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
28
+ * Declares a shape only; it computes nothing to share.
29
+ *
30
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation
31
+ * Declares three call signatures; the host filesystem interprets every path it is given.
32
+ */
33
+ export interface SnapshotReadOperations {
34
+ /**
35
+ * Whether a path exists, as `fs.existsSync`.
36
+ *
37
+ * @evidence contracts/common.md#principled-implementation
38
+ * Signature of the Node call it replaces; the default delegates to it.
39
+ *
40
+ * @evidence contracts/common.md#clear-and-simple-design
41
+ * One call per member, no behavior of its own.
42
+ *
43
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
44
+ * The reader never branches on whether it was injected.
45
+ *
46
+ * @evidence contracts/common.md#meaningful-documentation
47
+ * States which read this member stands for.
48
+ *
49
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
50
+ * Declares a shape only; it holds no state, handle or buffer.
51
+ *
52
+ * @evidenceExclude contracts/performance.md#efficient-algorithms
53
+ * Declares a shape only; there is no loop or processing in it.
54
+ *
55
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
56
+ * Declares a shape only; it computes nothing to share.
57
+ *
58
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation
59
+ * Forwards its path to the host call unchanged; no path is interpreted here.
60
+ */
61
+ existsSync: (file: string) => boolean;
62
+
63
+ /**
64
+ * Text of a file, as `fs.readFileSync`; throws a missing-file error when
65
+ * absent.
66
+ *
67
+ * @evidence contracts/common.md#principled-implementation
68
+ * Signature of the Node call it replaces; the default delegates to it.
69
+ *
70
+ * @evidence contracts/common.md#clear-and-simple-design
71
+ * One call per member, no behavior of its own.
72
+ *
73
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
74
+ * The reader never branches on whether it was injected.
75
+ *
76
+ * @evidence contracts/common.md#meaningful-documentation
77
+ * States which read this member stands for.
78
+ *
79
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
80
+ * Declares a shape only; it holds no state, handle or buffer.
81
+ *
82
+ * @evidenceExclude contracts/performance.md#efficient-algorithms
83
+ * Declares a shape only; there is no loop or processing in it.
84
+ *
85
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
86
+ * Declares a shape only; it computes nothing to share.
87
+ *
88
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation
89
+ * Forwards its path to the host call unchanged; no path is interpreted here.
90
+ */
91
+ readFileSync: (file: string, encoding: "utf8") => string;
92
+
93
+ /**
94
+ * Entry names of a directory, as `fs.readdirSync`.
95
+ *
96
+ * @evidence contracts/common.md#principled-implementation
97
+ * Signature of the Node call it replaces; the default delegates to it.
98
+ *
99
+ * @evidence contracts/common.md#clear-and-simple-design
100
+ * One call per member, no behavior of its own.
101
+ *
102
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
103
+ * The reader never branches on whether it was injected.
104
+ *
105
+ * @evidence contracts/common.md#meaningful-documentation
106
+ * States which read this member stands for.
107
+ *
108
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
109
+ * Declares a shape only; it holds no state, handle or buffer.
110
+ *
111
+ * @evidenceExclude contracts/performance.md#efficient-algorithms
112
+ * Declares a shape only; there is no loop or processing in it.
113
+ *
114
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
115
+ * Declares a shape only; it computes nothing to share.
116
+ *
117
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation
118
+ * Forwards its directory to the host call unchanged; no path is interpreted here.
119
+ */
120
+ readdirSync: (directory: string) => string[];
121
+ }
@@ -0,0 +1,127 @@
1
+ import type { TtscUnpluginOptions } from "@ttsc/unplugin/api";
2
+
3
+ /**
4
+ * Options accepted by {@link withTtsc} and the Metro transformer.
5
+ *
6
+ * The `project` / `compilerOptions` / `plugins` fields are inherited from
7
+ * `@ttsc/unplugin` so the Metro adapter speaks the exact same configuration
8
+ * language as every other bundler integration. The remaining fields are
9
+ * Metro-specific.
10
+ *
11
+ * Every field is JSON-serialisable on purpose: `withTtsc` runs in the Metro
12
+ * **config** process, but the transformer runs in Metro's **worker** processes,
13
+ * so the resolved options have to survive a JSON / env round-trip to reach them
14
+ * (see {@link serializeOptions}). That is why `include`/`exclude` are plain
15
+ * substring patterns rather than `RegExp`.
16
+ *
17
+ * @evidence contracts/common.md#principled-implementation
18
+ * This interface extends the documented Unplugin option contract rather than
19
+ * defining another plugin protocol. Metro adds JSON-compatible upstream and
20
+ * substring filters for its config-to-worker transport.
21
+ *
22
+ * @evidence contracts/common.md#clear-and-simple-design
23
+ * Inheritance keeps shared compiler options with Unplugin; this interface
24
+ * adds only upstream selection and the two Metro substring filters.
25
+ *
26
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
27
+ * The representation follows the documented consumer contract; its fields do
28
+ * not introduce fixture-selected variants.
29
+ *
30
+ * @evidence contracts/common.md#meaningful-documentation
31
+ * The native JSDoc explains inherited options, JSON transport, upstream
32
+ * precedence and the include/exclude relationship. Checked against the
33
+ * documentation skill: separate paragraphs state the contract and why its
34
+ * nonobvious boundary matters; field comments retain their own useful
35
+ * facts.
36
+ *
37
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources
38
+ * Declares a shape only; it holds no state, handle or buffer.
39
+ *
40
+ * @evidenceExclude contracts/performance.md#efficient-algorithms
41
+ * Declares a shape only; there is no loop or processing in it.
42
+ *
43
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
44
+ * Declares a shape only; it computes nothing to share.
45
+ *
46
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation
47
+ * Carries project and upstream paths as strings; every path is resolved by the code that consumes it.
48
+ */
49
+ export interface TtscMetroOptions extends TtscUnpluginOptions {
50
+ /**
51
+ * Explicit module path of the upstream Metro Babel transformer to delegate to
52
+ * after the ttsc pass.
53
+ *
54
+ * When omitted, `withTtsc` inherits the config's existing transformer unless
55
+ * it names this adapter. Without one it detects
56
+ * `@expo/metro-config/babel-transformer` first (Expo), then
57
+ * `@react-native/metro-babel-transformer`, then the legacy
58
+ * `metro-react-native-babel-transformer`.
59
+ */
60
+ upstreamTransformer?: string;
61
+
62
+ /**
63
+ * Substring patterns; when non-empty only files whose path contains one of
64
+ * them are run through the ttsc pass. Non-matching files are passed straight
65
+ * to the upstream transformer.
66
+ */
67
+ include?: string[];
68
+
69
+ /**
70
+ * Substring patterns; files whose path contains one of them skip the ttsc
71
+ * pass and go straight to the upstream transformer. Applied after
72
+ * {@link include}.
73
+ */
74
+ exclude?: string[];
75
+ }
76
+
77
+ /**
78
+ * Fully-resolved options, split into the ttsc-side overlay and Metro-side
79
+ * knobs.
80
+ *
81
+ * @evidence contracts/common.md#principled-implementation
82
+ * A structural interface separates the existing Unplugin overlay from
83
+ * resolved Metro filters and the private run handshake.
84
+ *
85
+ * @evidence contracts/common.md#clear-and-simple-design
86
+ * The ttsc member groups the forwarded overlay, while always-present filter
87
+ * arrays remove optional-array handling from every worker delivery.
88
+ *
89
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
90
+ * Its optional upstream/run identity and always-present arrays describe
91
+ * worker state without executable branches or mutation.
92
+ *
93
+ * @evidence contracts/common.md#meaningful-documentation
94
+ * The native JSDoc explains the forwarded overlay, empty filter arrays,
95
+ * optional upstream and private snapshot identity. 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
+ * Declares a shape only; it holds no state, handle or buffer.
102
+ *
103
+ * @evidenceExclude contracts/performance.md#efficient-algorithms
104
+ * Declares a shape only; there is no loop or processing in it.
105
+ *
106
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work
107
+ * Declares a shape only; it computes nothing to share.
108
+ *
109
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation
110
+ * Carries project and upstream paths as strings; every path is resolved by the code that consumes it.
111
+ */
112
+ export interface ResolvedTtscMetroOptions {
113
+ /** Options forwarded verbatim to the `@ttsc/unplugin` transform core. */
114
+ ttsc: TtscUnpluginOptions;
115
+
116
+ /** Explicit upstream transformer module path, or `undefined` to auto-detect. */
117
+ upstreamTransformer?: string;
118
+
119
+ /** Resolved include patterns (never `undefined`). */
120
+ include: string[];
121
+
122
+ /** Resolved exclude patterns (never `undefined`). */
123
+ exclude: string[];
124
+
125
+ /** Private run identity shared by `getCacheKey` and Metro workers. */
126
+ snapshotRunId?: string;
127
+ }