@ecrindigital/facetpack 0.1.9 → 0.2.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.
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
2
2
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
3
 
4
4
  // src/transformer.ts
5
- import { transformSync, JsxRuntime, resolveBatchSync } from "@ecrindigital/facetpack-native";
5
+ import { transformSync, JsxRuntime, resolveBatchSync, parseSync } from "@ecrindigital/facetpack-native";
6
6
  import { parse } from "@babel/parser";
7
7
 
8
8
  // src/cache.ts
@@ -40,9 +40,368 @@ function getCacheStats() {
40
40
  return { files: resolutionCache.size, resolutions };
41
41
  }
42
42
 
43
+ // src/stats.ts
44
+ import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync } from "fs";
45
+ import { tmpdir } from "os";
46
+ import { join } from "path";
47
+ var ANSI = {
48
+ green: "\x1B[32m",
49
+ yellow: "\x1B[33m",
50
+ cyan: "\x1B[36m",
51
+ white: "\x1B[37m",
52
+ gray: "\x1B[90m",
53
+ bold: "\x1B[1m",
54
+ dim: "\x1B[2m",
55
+ reset: "\x1B[0m"
56
+ };
57
+ var STATS_DIR = join(tmpdir(), "facetpack-stats");
58
+ var STATS_FILE_PREFIX = "stats-";
59
+ var LOCK_FILE = join(STATS_DIR, ".print-lock");
60
+ var PRINT_DELAY = 1000;
61
+ function getStatsFilePath() {
62
+ const workerId = process.env.METRO_WORKER_ID || process.pid.toString();
63
+ return join(STATS_DIR, `${STATS_FILE_PREFIX}${workerId}.json`);
64
+ }
65
+ function ensureStatsDir() {
66
+ if (!existsSync(STATS_DIR)) {
67
+ mkdirSync(STATS_DIR, { recursive: true });
68
+ }
69
+ }
70
+ function acquirePrintLock() {
71
+ try {
72
+ ensureStatsDir();
73
+ if (existsSync(LOCK_FILE)) {
74
+ const lockTime = parseInt(readFileSync(LOCK_FILE, "utf-8"), 10);
75
+ if (Date.now() - lockTime < 5000) {
76
+ return false;
77
+ }
78
+ }
79
+ writeFileSync(LOCK_FILE, Date.now().toString());
80
+ return true;
81
+ } catch {
82
+ return false;
83
+ }
84
+ }
85
+ function releasePrintLock() {
86
+ try {
87
+ if (existsSync(LOCK_FILE)) {
88
+ unlinkSync(LOCK_FILE);
89
+ }
90
+ } catch {}
91
+ }
92
+
93
+ class GlobalStats {
94
+ stats = this.createEmptyStats();
95
+ exitHandlerRegistered = false;
96
+ hasPrinted = false;
97
+ printTimer = null;
98
+ createEmptyStats() {
99
+ return {
100
+ transformer: { oxc: 0, babel: 0 },
101
+ resolver: { facetpack: 0, metro: 0 },
102
+ minifier: { files: 0, originalSize: 0, minifiedSize: 0 },
103
+ treeShaking: { modulesAnalyzed: 0, modulesRemoved: 0, exportsRemoved: 0 },
104
+ startTime: Date.now()
105
+ };
106
+ }
107
+ recordTransform(engine) {
108
+ this.stats.transformer[engine]++;
109
+ this.persistStats();
110
+ this.schedulePrint();
111
+ }
112
+ adjustTransformFallback() {
113
+ this.stats.transformer.oxc--;
114
+ this.stats.transformer.babel++;
115
+ this.persistStats();
116
+ }
117
+ recordResolve(engine) {
118
+ this.stats.resolver[engine]++;
119
+ }
120
+ flush() {
121
+ this.persistStats();
122
+ }
123
+ schedulePrint() {
124
+ if (this.printTimer) {
125
+ clearTimeout(this.printTimer);
126
+ }
127
+ this.printTimer = setTimeout(() => {
128
+ if (acquirePrintLock()) {
129
+ this.print();
130
+ releasePrintLock();
131
+ }
132
+ }, PRINT_DELAY);
133
+ }
134
+ recordMinify(originalSize, minifiedSize) {
135
+ this.stats.minifier.files++;
136
+ this.stats.minifier.originalSize += originalSize;
137
+ this.stats.minifier.minifiedSize += minifiedSize;
138
+ }
139
+ recordTreeShaking(analyzed, removed, exports) {
140
+ this.stats.treeShaking.modulesAnalyzed += analyzed;
141
+ this.stats.treeShaking.modulesRemoved += removed;
142
+ this.stats.treeShaking.exportsRemoved += exports;
143
+ }
144
+ get() {
145
+ return JSON.parse(JSON.stringify(this.stats));
146
+ }
147
+ reset() {
148
+ this.stats = this.createEmptyStats();
149
+ this.hasPrinted = false;
150
+ this.cleanupStatsFiles();
151
+ }
152
+ persistStats() {
153
+ try {
154
+ ensureStatsDir();
155
+ writeFileSync(getStatsFilePath(), JSON.stringify(this.stats));
156
+ } catch {}
157
+ }
158
+ cleanupStatsFiles() {
159
+ try {
160
+ if (existsSync(STATS_DIR)) {
161
+ const { readdirSync } = __require("fs");
162
+ const files = readdirSync(STATS_DIR);
163
+ for (const file of files) {
164
+ if (file.startsWith(STATS_FILE_PREFIX)) {
165
+ try {
166
+ unlinkSync(join(STATS_DIR, file));
167
+ } catch {}
168
+ }
169
+ }
170
+ }
171
+ } catch {}
172
+ }
173
+ aggregateWorkerStats() {
174
+ const aggregated = this.createEmptyStats();
175
+ aggregated.startTime = this.stats.startTime;
176
+ try {
177
+ if (existsSync(STATS_DIR)) {
178
+ const { readdirSync } = __require("fs");
179
+ const files = readdirSync(STATS_DIR);
180
+ for (const file of files) {
181
+ if (file.startsWith(STATS_FILE_PREFIX)) {
182
+ try {
183
+ const content = readFileSync(join(STATS_DIR, file), "utf-8");
184
+ const workerStats = JSON.parse(content);
185
+ aggregated.transformer.oxc += workerStats.transformer.oxc;
186
+ aggregated.transformer.babel += workerStats.transformer.babel;
187
+ aggregated.resolver.facetpack += workerStats.resolver.facetpack;
188
+ aggregated.resolver.metro += workerStats.resolver.metro;
189
+ if (workerStats.startTime < aggregated.startTime) {
190
+ aggregated.startTime = workerStats.startTime;
191
+ }
192
+ } catch {}
193
+ }
194
+ }
195
+ }
196
+ } catch {}
197
+ aggregated.minifier = this.stats.minifier;
198
+ aggregated.treeShaking = this.stats.treeShaking;
199
+ return aggregated;
200
+ }
201
+ formatPercent(value, total) {
202
+ if (total === 0)
203
+ return "0.0";
204
+ return (value / total * 100).toFixed(1);
205
+ }
206
+ formatSize(bytes) {
207
+ if (bytes < 1024)
208
+ return `${bytes} B`;
209
+ if (bytes < 1024 * 1024)
210
+ return `${(bytes / 1024).toFixed(1)} KB`;
211
+ return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
212
+ }
213
+ formatDuration(ms) {
214
+ if (ms < 1000)
215
+ return `${ms}ms`;
216
+ return `${(ms / 1000).toFixed(2)}s`;
217
+ }
218
+ print() {
219
+ if (!process.env.FACETPACK_DEBUG || this.hasPrinted)
220
+ return;
221
+ const aggregated = this.aggregateWorkerStats();
222
+ const { transformer, resolver, minifier, treeShaking, startTime } = aggregated;
223
+ const duration = Date.now() - startTime;
224
+ const transformTotal = transformer.oxc + transformer.babel;
225
+ const resolveTotal = resolver.facetpack + resolver.metro;
226
+ if (transformTotal === 0 && resolveTotal === 0 && minifier.files === 0)
227
+ return;
228
+ this.hasPrinted = true;
229
+ const { cyan, green, yellow, white, gray, bold, dim, reset } = ANSI;
230
+ console.log(`
231
+ `);
232
+ console.log(`${bold}${cyan}╔════════════════════════════════════════════════════════════════════╗${reset}`);
233
+ console.log(`${bold}${cyan}║${reset} ${bold}FACETPACK BUNDLE STATS${reset} ${cyan}║${reset}`);
234
+ console.log(`${bold}${cyan}╠════════════════════════════════════════════════════════════════════╣${reset}`);
235
+ if (transformTotal > 0) {
236
+ const oxcPct = this.formatPercent(transformer.oxc, transformTotal);
237
+ const babelPct = this.formatPercent(transformer.babel, transformTotal);
238
+ console.log(`${cyan}║${reset} ${cyan}║${reset}`);
239
+ console.log(`${cyan}║${reset} ${bold}TRANSFORMER${reset} ${cyan}║${reset}`);
240
+ console.log(`${cyan}║${reset} ${green}●${reset} OXC (native) ${bold}${green}${transformer.oxc.toString().padStart(6)}${reset} files ${green}${oxcPct.padStart(6)}%${reset} ${cyan}║${reset}`);
241
+ console.log(`${cyan}║${reset} ${yellow}●${reset} Babel ${bold}${yellow}${transformer.babel.toString().padStart(6)}${reset} files ${yellow}${babelPct.padStart(6)}%${reset} ${cyan}║${reset}`);
242
+ console.log(`${cyan}║${reset} ${dim}${white} Total ${transformTotal.toString().padStart(6)} files${reset} ${cyan}║${reset}`);
243
+ }
244
+ if (resolveTotal > 0) {
245
+ const fpPct = this.formatPercent(resolver.facetpack, resolveTotal);
246
+ const metroPct = this.formatPercent(resolver.metro, resolveTotal);
247
+ console.log(`${cyan}║${reset} ${cyan}║${reset}`);
248
+ console.log(`${cyan}║${reset} ${bold}RESOLVER${reset} ${cyan}║${reset}`);
249
+ console.log(`${cyan}║${reset} ${green}●${reset} Facetpack ${bold}${green}${resolver.facetpack.toString().padStart(6)}${reset} hits ${green}${fpPct.padStart(6)}%${reset} ${cyan}║${reset}`);
250
+ console.log(`${cyan}║${reset} ${yellow}●${reset} Metro ${bold}${yellow}${resolver.metro.toString().padStart(6)}${reset} hits ${yellow}${metroPct.padStart(6)}%${reset} ${cyan}║${reset}`);
251
+ console.log(`${cyan}║${reset} ${dim}${white} Total ${resolveTotal.toString().padStart(6)} resolutions${reset} ${cyan}║${reset}`);
252
+ }
253
+ if (minifier.files > 0) {
254
+ const savings = minifier.originalSize - minifier.minifiedSize;
255
+ const savingsPct = this.formatPercent(savings, minifier.originalSize);
256
+ console.log(`${cyan}║${reset} ${cyan}║${reset}`);
257
+ console.log(`${cyan}║${reset} ${bold}MINIFIER${reset} ${cyan}║${reset}`);
258
+ console.log(`${cyan}║${reset} ${green}●${reset} Files minified ${bold}${green}${minifier.files.toString().padStart(6)}${reset} ${cyan}║${reset}`);
259
+ console.log(`${cyan}║${reset} ${gray}●${reset} Original size ${this.formatSize(minifier.originalSize).padStart(12)} ${cyan}║${reset}`);
260
+ console.log(`${cyan}║${reset} ${green}●${reset} Minified size ${this.formatSize(minifier.minifiedSize).padStart(12)} ${green}-${savingsPct}%${reset} ${cyan}║${reset}`);
261
+ }
262
+ if (treeShaking.modulesAnalyzed > 0) {
263
+ console.log(`${cyan}║${reset} ${cyan}║${reset}`);
264
+ console.log(`${cyan}║${reset} ${bold}TREE SHAKING${reset} ${cyan}║${reset}`);
265
+ console.log(`${cyan}║${reset} ${gray}●${reset} Modules analyzed ${bold}${treeShaking.modulesAnalyzed.toString().padStart(5)}${reset} ${cyan}║${reset}`);
266
+ console.log(`${cyan}║${reset} ${green}●${reset} Modules removed ${bold}${green}${treeShaking.modulesRemoved.toString().padStart(5)}${reset} ${cyan}║${reset}`);
267
+ console.log(`${cyan}║${reset} ${green}●${reset} Exports removed ${bold}${green}${treeShaking.exportsRemoved.toString().padStart(5)}${reset} ${cyan}║${reset}`);
268
+ }
269
+ console.log(`${cyan}║${reset} ${cyan}║${reset}`);
270
+ console.log(`${cyan}║${reset} ${dim}Duration: ${this.formatDuration(duration)}${reset} ${cyan}║${reset}`);
271
+ console.log(`${bold}${cyan}╚════════════════════════════════════════════════════════════════════╝${reset}`);
272
+ console.log(`
273
+ `);
274
+ this.cleanupStatsFiles();
275
+ }
276
+ registerExitHandler() {
277
+ if (this.exitHandlerRegistered)
278
+ return;
279
+ this.exitHandlerRegistered = true;
280
+ process.on("SIGINT", () => {
281
+ this.print();
282
+ process.exit(0);
283
+ });
284
+ process.on("beforeExit", () => this.print());
285
+ }
286
+ }
287
+ var globalStats = new GlobalStats;
288
+ function printStats() {
289
+ globalStats.print();
290
+ }
291
+ function resetStats() {
292
+ globalStats.reset();
293
+ }
294
+ function getStats() {
295
+ return globalStats.get();
296
+ }
297
+
43
298
  // src/transformer.ts
299
+ var ANSI2 = {
300
+ green: "\x1B[32m",
301
+ yellow: "\x1B[33m",
302
+ cyan: "\x1B[36m",
303
+ bold: "\x1B[1m",
304
+ reset: "\x1B[0m"
305
+ };
44
306
  var IMPORT_REGEX = /(?:import|export)\s+(?:[\s\S]*?\s+from\s+)?['"]([^'"]+)['"]/g;
45
307
  var REQUIRE_REGEX = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
308
+ var BABEL_REQUIRED_PATTERNS = [
309
+ /'worklet'/,
310
+ /"worklet"/,
311
+ /require\.context\s*\(/,
312
+ /useAnimatedStyle/,
313
+ /useAnimatedProps/,
314
+ /useAnimatedScrollHandler/,
315
+ /useAnimatedGestureHandler/,
316
+ /useAnimatedReaction/,
317
+ /useDerivedValue/,
318
+ /useAnimatedSensor/,
319
+ /useFrameCallback/,
320
+ /useScrollViewOffset/,
321
+ /runOnUI/,
322
+ /runOnJS/
323
+ ];
324
+ var DEFAULT_OPTIONS = {
325
+ jsx: true,
326
+ jsxRuntime: "automatic",
327
+ jsxImportSource: "react",
328
+ jsxPragma: "React.createElement",
329
+ jsxPragmaFrag: "React.Fragment",
330
+ typescript: true,
331
+ sourceExts: ["ts", "tsx", "js", "jsx", "mjs", "cjs"],
332
+ minifier: true,
333
+ treeShake: true,
334
+ noAst: false
335
+ };
336
+
337
+ class Logger {
338
+ startupLogged = false;
339
+ logStartup() {
340
+ if (this.startupLogged || !process.env.FACETPACK_DEBUG)
341
+ return;
342
+ this.startupLogged = true;
343
+ console.log(`${ANSI2.cyan}${ANSI2.bold}[Facetpack]${ANSI2.reset} Transformer loaded`);
344
+ }
345
+ logTransform(decision, filename) {
346
+ if (!process.env.FACETPACK_DEBUG)
347
+ return;
348
+ const color = decision === "oxc" ? ANSI2.green : ANSI2.yellow;
349
+ console.log(`${color}[Facetpack]${ANSI2.reset} ${decision.toUpperCase()}: ${filename}`);
350
+ }
351
+ logFallback(filename, error) {
352
+ if (!process.env.FACETPACK_DEBUG)
353
+ return;
354
+ const message = error instanceof Error ? error.message : String(error);
355
+ console.log(`${ANSI2.yellow}[Facetpack]${ANSI2.reset} OXC failed, falling back to Babel: ${filename}`);
356
+ console.log(`${ANSI2.yellow}[Facetpack]${ANSI2.reset} Error: ${message}`);
357
+ }
358
+ }
359
+
360
+ class OptionsManager {
361
+ globalOptions = {};
362
+ setGlobal(options) {
363
+ this.globalOptions = options;
364
+ }
365
+ get() {
366
+ return { ...DEFAULT_OPTIONS, ...this.globalOptions, ...this.getFromEnv() };
367
+ }
368
+ merge(options) {
369
+ return { ...DEFAULT_OPTIONS, ...options };
370
+ }
371
+ getFromEnv() {
372
+ try {
373
+ const json = process.env.FACETPACK_OPTIONS;
374
+ return json ? JSON.parse(json) : {};
375
+ } catch {
376
+ return {};
377
+ }
378
+ }
379
+ }
380
+
381
+ class FallbackTransformerManager {
382
+ instance = null;
383
+ get() {
384
+ if (this.instance)
385
+ return this.instance;
386
+ const envPath = process.env.FACETPACK_FALLBACK_TRANSFORMER;
387
+ if (envPath) {
388
+ try {
389
+ this.instance = __require(envPath);
390
+ return this.instance;
391
+ } catch (e) {
392
+ console.warn(`[Facetpack] Failed to load fallback transformer from ${envPath}:`, e);
393
+ }
394
+ }
395
+ this.instance = {
396
+ transform: ({ src }) => ({ code: src, map: null })
397
+ };
398
+ return this.instance;
399
+ }
400
+ }
401
+ var logger = new Logger;
402
+ var options = new OptionsManager;
403
+ var fallback = new FallbackTransformerManager;
404
+ logger.logStartup();
46
405
  function extractSpecifiers(code) {
47
406
  const specifiers = new Set;
48
407
  let match;
@@ -71,168 +430,126 @@ function preResolveImports(filename, code, sourceExts) {
71
430
  const specifier = specifiers[i];
72
431
  if (specifier) {
73
432
  resolutions.set(specifier, results[i]?.path ?? null);
433
+ if (results[i]?.path) {
434
+ globalStats.recordResolve("facetpack");
435
+ }
74
436
  }
75
437
  }
76
438
  setCachedResolutions(filename, resolutions);
77
439
  }
78
- var defaultOptions = {
79
- jsx: true,
80
- jsxRuntime: "automatic",
81
- jsxImportSource: "react",
82
- jsxPragma: "React.createElement",
83
- jsxPragmaFrag: "React.Fragment",
84
- typescript: true,
85
- sourceExts: ["ts", "tsx", "js", "jsx", "mjs", "cjs"],
86
- minifier: true,
87
- treeShake: true,
88
- noAst: false
89
- };
90
- var globalOptions = {};
91
- var fallbackTransformer = null;
92
- function getFallbackTransformer() {
93
- if (fallbackTransformer) {
94
- return fallbackTransformer;
95
- }
96
- const fallbackPath = process.env.FACETPACK_FALLBACK_TRANSFORMER;
97
- if (fallbackPath) {
98
- try {
99
- fallbackTransformer = __require(fallbackPath);
100
- return fallbackTransformer;
101
- } catch (e) {
102
- console.warn(`[Facetpack] Failed to load fallback transformer from ${fallbackPath}:`, e);
103
- }
104
- }
105
- fallbackTransformer = {
106
- transform: ({ src }) => ({ code: src, map: null })
107
- };
108
- return fallbackTransformer;
109
- }
110
- function setTransformerOptions(options) {
111
- globalOptions = options;
112
- }
113
- function getStoredOptions() {
114
- try {
115
- const optionsJson = process.env.FACETPACK_OPTIONS;
116
- if (optionsJson) {
117
- return JSON.parse(optionsJson);
118
- }
119
- } catch {}
120
- return {};
121
- }
122
- function getOptions() {
123
- const storedOptions = getStoredOptions();
124
- return { ...defaultOptions, ...globalOptions, ...storedOptions };
440
+ function requiresBabelTransform(src) {
441
+ return BABEL_REQUIRED_PATTERNS.some((pattern) => pattern.test(src));
125
442
  }
126
443
  function isNodeModules(filename) {
127
444
  return filename.includes("node_modules");
128
445
  }
129
- var BABEL_REQUIRED_PATTERNS = [
130
- /'worklet'/,
131
- /"worklet"/,
132
- /useAnimatedStyle/,
133
- /useAnimatedProps/,
134
- /useDerivedValue/,
135
- /useAnimatedReaction/,
136
- /useAnimatedScrollHandler/,
137
- /useAnimatedGestureHandler/,
138
- /runOnUI/,
139
- /runOnJS/
140
- ];
141
- function requiresBabelTransform(src) {
142
- return BABEL_REQUIRED_PATTERNS.some((pattern) => pattern.test(src));
446
+ function getFileExtension(filename) {
447
+ return filename.split(".").pop()?.toLowerCase();
143
448
  }
144
- function shouldTransform(filename, src, options) {
145
- if (isNodeModules(filename)) {
146
- return false;
147
- }
148
- if (requiresBabelTransform(src)) {
149
- if (process.env.FACETPACK_DEBUG) {
150
- console.log(`[Facetpack] Babel required for worklets: ${filename}`);
449
+ function getTransformDecision(filename, src, opts) {
450
+ if (requiresBabelTransform(src))
451
+ return "babel";
452
+ if (isNodeModules(filename))
453
+ return "babel";
454
+ const ext = getFileExtension(filename);
455
+ if (!ext || !opts.sourceExts.includes(ext))
456
+ return "babel";
457
+ return "oxc";
458
+ }
459
+ function formatDiagnostics(diagnostics) {
460
+ return diagnostics.map((d) => {
461
+ if (d.formatted)
462
+ return d.formatted;
463
+ if (!d.message)
464
+ return "";
465
+ let output = `
466
+ × ${d.message}
467
+ `;
468
+ if (d.snippet) {
469
+ output += ` ╭─[${d.filename}:${d.line}:${d.column}]
470
+ `;
471
+ output += ` ${d.line} │ ${d.snippet}
472
+ `;
473
+ output += ` ╰────
474
+ `;
151
475
  }
152
- return false;
476
+ if (d.help)
477
+ output += ` help: ${d.help}
478
+ `;
479
+ return output;
480
+ }).join(`
481
+ `);
482
+ }
483
+ function transformWithOxc(filename, src, opts, isDev) {
484
+ const parseResult = parseSync(filename, src);
485
+ if (parseResult.errors.length > 0) {
486
+ const error = parseResult.diagnostics.length > 0 ? new Error(`
487
+ ${formatDiagnostics(parseResult.diagnostics)}`) : new Error(`Parse error in ${filename}:
488
+ ${parseResult.errors.join(`
489
+ `)}`);
490
+ error.isParseError = true;
491
+ throw error;
153
492
  }
154
- const ext = filename.split(".").pop()?.toLowerCase();
155
- if (!ext)
156
- return false;
157
- return options.sourceExts.includes(ext);
493
+ const isClassic = opts.jsxRuntime === "classic";
494
+ const result = transformSync(filename, src, {
495
+ jsx: opts.jsx,
496
+ jsxRuntime: isClassic ? JsxRuntime.Classic : JsxRuntime.Automatic,
497
+ ...isClassic ? { jsxPragma: opts.jsxPragma, jsxPragmaFrag: opts.jsxPragmaFrag } : { jsxImportSource: opts.jsxImportSource },
498
+ typescript: opts.typescript,
499
+ sourcemap: isDev
500
+ });
501
+ if (result.errors.length > 0) {
502
+ throw new Error(`Facetpack transform error in ${filename}:
503
+ ${result.errors.join(`
504
+ `)}`);
505
+ }
506
+ preResolveImports(filename, result.code, opts.sourceExts);
507
+ globalStats.flush();
508
+ const ast = parse(result.code, {
509
+ sourceType: "unambiguous",
510
+ plugins: ["jsx"]
511
+ });
512
+ return {
513
+ ast,
514
+ code: result.code,
515
+ map: result.map ? JSON.parse(result.map) : null
516
+ };
517
+ }
518
+ function setTransformerOptions(opts) {
519
+ options.setGlobal(opts);
158
520
  }
159
521
  function transform(params) {
160
522
  const { filename, src, options: metroOptions } = params;
161
- const opts = getOptions();
162
- if (process.env.FACETPACK_DEBUG) {
163
- console.log(`[Facetpack] Processing: ${filename}`);
164
- }
165
- if (!shouldTransform(filename, src, opts)) {
166
- if (process.env.FACETPACK_DEBUG) {
167
- console.log(`[Facetpack] Fallback: ${filename}`);
168
- }
169
- return getFallbackTransformer().transform(params);
170
- }
171
- if (process.env.FACETPACK_DEBUG) {
172
- console.log(`[Facetpack] OXC Transform: ${filename}`);
523
+ const opts = options.get();
524
+ globalStats.registerExitHandler();
525
+ const decision = getTransformDecision(filename, src, opts);
526
+ globalStats.recordTransform(decision);
527
+ logger.logTransform(decision, filename);
528
+ if (decision === "babel") {
529
+ return fallback.get().transform(params);
173
530
  }
174
531
  try {
175
- const isClassic = opts.jsxRuntime === "classic";
176
- const result = transformSync(filename, src, {
177
- jsx: opts.jsx,
178
- jsxRuntime: isClassic ? JsxRuntime.Classic : JsxRuntime.Automatic,
179
- ...isClassic ? { jsxPragma: opts.jsxPragma, jsxPragmaFrag: opts.jsxPragmaFrag } : { jsxImportSource: opts.jsxImportSource },
180
- typescript: opts.typescript,
181
- sourcemap: metroOptions.dev
182
- });
183
- if (result.errors.length > 0) {
184
- const errorMessage = result.errors.join(`
185
- `);
186
- throw new Error(`Facetpack transform error in ${filename}:
187
- ${errorMessage}`);
188
- }
189
- preResolveImports(filename, result.code, opts.sourceExts);
190
- const ast = opts.noAst ? undefined : parse(result.code, {
191
- sourceType: "unambiguous",
192
- plugins: ["jsx"]
193
- });
194
- const output = {
195
- ast,
196
- code: result.code,
197
- map: result.map ? JSON.parse(result.map) : null
198
- };
199
- if (process.env.FACETPACK_DEBUG) {
200
- console.log(`[Facetpack] Output for ${filename}:`);
201
- console.log(result.code.slice(0, 500));
202
- }
203
- return output;
532
+ return transformWithOxc(filename, src, opts, metroOptions.dev);
204
533
  } catch (error) {
205
- if (error instanceof Error) {
206
- error.message = `[Facetpack] ${error.message}`;
534
+ if (error.isParseError) {
535
+ throw error;
207
536
  }
208
- throw error;
537
+ logger.logFallback(filename, error);
538
+ globalStats.adjustTransformFallback();
539
+ return fallback.get().transform(params);
209
540
  }
210
541
  }
211
- function createTransformer(options = {}) {
212
- const opts = { ...defaultOptions, ...options };
542
+ function createTransformer(customOptions = {}) {
543
+ const opts = options.merge(customOptions);
213
544
  return {
214
545
  transform(params) {
215
546
  const { filename, src, options: metroOptions } = params;
216
- if (!shouldTransform(filename, src, opts)) {
217
- return getFallbackTransformer().transform(params);
218
- }
219
- const isClassic = opts.jsxRuntime === "classic";
220
- const result = transformSync(filename, src, {
221
- jsx: opts.jsx,
222
- jsxRuntime: isClassic ? JsxRuntime.Classic : JsxRuntime.Automatic,
223
- ...isClassic ? { jsxPragma: opts.jsxPragma, jsxPragmaFrag: opts.jsxPragmaFrag } : { jsxImportSource: opts.jsxImportSource },
224
- typescript: opts.typescript,
225
- sourcemap: metroOptions.dev
226
- });
227
- if (result.errors.length > 0) {
228
- throw new Error(`Facetpack transform error in ${filename}:
229
- ${result.errors.join(`
230
- `)}`);
547
+ const decision = getTransformDecision(filename, src, opts);
548
+ globalStats.recordTransform(decision);
549
+ if (decision === "babel") {
550
+ return fallback.get().transform(params);
231
551
  }
232
- return {
233
- code: result.code,
234
- map: result.map ? JSON.parse(result.map) : null
235
- };
552
+ return transformWithOxc(filename, src, opts, metroOptions.dev);
236
553
  }
237
554
  };
238
555
  }
package/dist/types.d.ts CHANGED
@@ -66,7 +66,8 @@ export interface TransformOptions {
66
66
  }
67
67
  export interface TransformResult {
68
68
  ast?: object;
69
- code: string;
69
+ code?: string;
70
70
  map?: object | null;
71
+ metadata?: Record<string, unknown>;
71
72
  }
72
73
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"withFacetpack.d.ts","sourceRoot":"","sources":["../src/withFacetpack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAkB,MAAM,SAAS,CAAA;AAkC5E,wBAAgB,aAAa,CAC3B,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,gBAAqB,GAC7B,WAAW,CAiGb;AASD,wBAAgB,gBAAgB,IAAI,gBAAgB,CASnD"}
1
+ {"version":3,"file":"withFacetpack.d.ts","sourceRoot":"","sources":["../src/withFacetpack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAkB,MAAM,SAAS,CAAA;AAkC5E,wBAAgB,aAAa,CAC3B,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,gBAAqB,GAC7B,WAAW,CAqGb;AASD,wBAAgB,gBAAgB,IAAI,gBAAgB,CASnD"}