vxrn 2.9.2 → 2.11.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 (84) hide show
  1. package/dist/config/getBaseVitePlugins.mjs +3 -1
  2. package/dist/config/getBaseVitePlugins.mjs.map +1 -1
  3. package/dist/config/getBaseVitePlugins.native.js +3 -1
  4. package/dist/config/getBaseVitePlugins.native.js.map +1 -1
  5. package/dist/constants.mjs +23 -1
  6. package/dist/constants.mjs.map +1 -1
  7. package/dist/constants.native.js +23 -1
  8. package/dist/constants.native.js.map +1 -1
  9. package/dist/exports/build.mjs +11 -12
  10. package/dist/exports/build.mjs.map +1 -1
  11. package/dist/exports/build.native.js +11 -12
  12. package/dist/exports/build.native.js.map +1 -1
  13. package/dist/exports/prebuildWithoutExpo.mjs +16 -1
  14. package/dist/exports/prebuildWithoutExpo.mjs.map +1 -1
  15. package/dist/exports/prebuildWithoutExpo.native.js +16 -1
  16. package/dist/exports/prebuildWithoutExpo.native.js.map +1 -1
  17. package/dist/index.js +2 -1
  18. package/dist/index.mjs +2 -1
  19. package/dist/index.native.js +2 -1
  20. package/dist/plugins/reactNativeDevServer.mjs +7 -5
  21. package/dist/plugins/reactNativeDevServer.mjs.map +1 -1
  22. package/dist/plugins/reactNativeDevServer.native.js +8 -5
  23. package/dist/plugins/reactNativeDevServer.native.js.map +1 -1
  24. package/dist/rn-commands/bundle/buildBundle.mjs +9 -0
  25. package/dist/rn-commands/bundle/buildBundle.mjs.map +1 -1
  26. package/dist/rn-commands/bundle/buildBundle.native.js +9 -0
  27. package/dist/rn-commands/bundle/buildBundle.native.js.map +1 -1
  28. package/dist/runtime/native-prelude.mjs +7 -1
  29. package/dist/runtime/native-prelude.mjs.map +1 -1
  30. package/dist/runtime/native-prelude.native.js +7 -1
  31. package/dist/runtime/native-prelude.native.js.map +1 -1
  32. package/dist/utils/compileNativeDevBytecode.mjs +13 -3
  33. package/dist/utils/compileNativeDevBytecode.mjs.map +1 -1
  34. package/dist/utils/compileNativeDevBytecode.native.js +13 -3
  35. package/dist/utils/compileNativeDevBytecode.native.js.map +1 -1
  36. package/dist/utils/createNativeDevEngine.mjs +375 -173
  37. package/dist/utils/createNativeDevEngine.mjs.map +1 -1
  38. package/dist/utils/createNativeDevEngine.native.js +429 -193
  39. package/dist/utils/createNativeDevEngine.native.js.map +1 -1
  40. package/dist/utils/environmentUtils.mjs +1 -1
  41. package/dist/utils/environmentUtils.mjs.map +1 -1
  42. package/dist/utils/environmentUtils.native.js +1 -1
  43. package/dist/utils/environmentUtils.native.js.map +1 -1
  44. package/dist/utils/scanDepsToOptimize.mjs +37 -15
  45. package/dist/utils/scanDepsToOptimize.mjs.map +1 -1
  46. package/dist/utils/scanDepsToOptimize.native.js +45 -15
  47. package/dist/utils/scanDepsToOptimize.native.js.map +1 -1
  48. package/package.json +13 -13
  49. package/src/config/getBaseVitePlugins.ts +2 -0
  50. package/src/constants.ts +24 -0
  51. package/src/exports/build.lifecycle.test.ts +152 -0
  52. package/src/exports/build.ts +16 -14
  53. package/src/exports/prebuildWithoutExpo.ts +16 -1
  54. package/src/index.ts +1 -0
  55. package/src/plugins/reactNativeCommonJsPlugin.ts +1 -1
  56. package/src/plugins/reactNativeDevServer.ts +19 -8
  57. package/src/rn-commands/bundle/buildBundle.ts +13 -1
  58. package/src/runtime/native-prelude.ts +7 -1
  59. package/src/types.ts +1 -1
  60. package/src/utils/compileNativeDevBytecode.test.ts +8 -8
  61. package/src/utils/compileNativeDevBytecode.ts +22 -2
  62. package/src/utils/createNativeDevEngine.test.ts +52 -25
  63. package/src/utils/createNativeDevEngine.ts +567 -254
  64. package/src/utils/environmentUtils.ts +6 -1
  65. package/src/utils/scanDepsToOptimize.test.ts +46 -2
  66. package/src/utils/scanDepsToOptimize.ts +78 -18
  67. package/types/config/getBaseVitePlugins.d.ts.map +1 -1
  68. package/types/constants.d.ts +2 -0
  69. package/types/constants.d.ts.map +1 -1
  70. package/types/exports/build.d.ts.map +1 -1
  71. package/types/exports/prebuildWithoutExpo.d.ts.map +1 -1
  72. package/types/index.d.ts +1 -0
  73. package/types/index.d.ts.map +1 -1
  74. package/types/plugins/reactNativeDevServer.d.ts.map +1 -1
  75. package/types/rn-commands/bundle/buildBundle.d.ts.map +1 -1
  76. package/types/runtime/native-prelude.d.ts.map +1 -1
  77. package/types/types.d.ts +1 -1
  78. package/types/types.d.ts.map +1 -1
  79. package/types/utils/compileNativeDevBytecode.d.ts +2 -1
  80. package/types/utils/compileNativeDevBytecode.d.ts.map +1 -1
  81. package/types/utils/createNativeDevEngine.d.ts +11 -5
  82. package/types/utils/createNativeDevEngine.d.ts.map +1 -1
  83. package/types/utils/environmentUtils.d.ts.map +1 -1
  84. package/types/utils/scanDepsToOptimize.d.ts.map +1 -1
@@ -7,6 +7,7 @@ import { parseSync } from "oxc-parser";
7
7
  import { loadEnv, normalizePath } from "vite";
8
8
  import { shouldStripFlow, transformHermesAsync } from "@vxrn/compiler";
9
9
  import { resolvePath } from "@vxrn/resolve";
10
+ import { desktopReactNativeFile, requireOnePackageRoot } from "@vxrn/utils/desktopReactNativeResolve";
10
11
  import { nativeAppDefines } from "@vxrn/utils/nativeAppManifest";
11
12
  import { withExpoPublicEnvAliases } from "@vxrn/utils/publicEnv";
12
13
  import { DEFAULT_ASSET_EXTS } from "../constants/defaults.mjs";
@@ -27,37 +28,52 @@ const HERMES_ASYNC_TRANSFORMS = ["transform-async-to-generator"];
27
28
  function getHermesSWCIncludes(dev) {
28
29
  return [...HERMES_CLASS_TRANSFORMS, ...HERMES_ASYNC_TRANSFORMS];
29
30
  }
30
- function getResolveExtensions(platform) {
31
- const platformExts = platform === "ios" ? [
31
+ const NATIVE_PLATFORM_EXTENSIONS = {
32
+ ios: [
32
33
  ".ios.tsx",
33
34
  ".ios.ts",
34
35
  ".ios.jsx",
35
36
  ".ios.js"
36
- ] : [
37
+ ],
38
+ android: [
37
39
  ".android.tsx",
38
40
  ".android.ts",
39
41
  ".android.jsx",
40
42
  ".android.js"
41
- ];
42
- const nativeExts = [
43
- ".native.tsx",
44
- ".native.ts",
45
- ".native.jsx",
46
- ".native.js"
47
- ];
48
- const defaultExts = [
49
- ".tsx",
50
- ".ts",
51
- ".jsx",
52
- ".js",
53
- ".mjs",
54
- ".cjs",
55
- ".json"
56
- ];
43
+ ],
44
+ macos: [
45
+ ".macos.tsx",
46
+ ".macos.ts",
47
+ ".macos.jsx",
48
+ ".macos.js"
49
+ ],
50
+ linux: [
51
+ ".linux.tsx",
52
+ ".linux.ts",
53
+ ".linux.jsx",
54
+ ".linux.js"
55
+ ]
56
+ };
57
+ const NATIVE_SHARED_EXTENSIONS = [
58
+ ".native.tsx",
59
+ ".native.ts",
60
+ ".native.jsx",
61
+ ".native.js"
62
+ ];
63
+ const PLAIN_EXTENSIONS = [
64
+ ".tsx",
65
+ ".ts",
66
+ ".jsx",
67
+ ".js",
68
+ ".mjs",
69
+ ".cjs",
70
+ ".json"
71
+ ];
72
+ function getResolveExtensions(platform) {
57
73
  return [
58
- ...platformExts,
59
- ...nativeExts,
60
- ...defaultExts
74
+ ...NATIVE_PLATFORM_EXTENSIONS[platform],
75
+ ...NATIVE_SHARED_EXTENSIONS,
76
+ ...PLAIN_EXTENSIONS
61
77
  ];
62
78
  }
63
79
  function getNativeResolveConfig(platform) {
@@ -153,14 +169,112 @@ function getNativeTransformConfig(platform, dev, root) {
153
169
  inject: { React: "react" }
154
170
  };
155
171
  }
156
- function getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest, onAsset, sourceMaps = false, userPlugins = [], minify = false) {
172
+ function desktopReactNativeResolvePlugin(root, platform) {
173
+ const oneRoot = requireOnePackageRoot(root, platform);
174
+ return {
175
+ name: `vxrn:${platform}-react-native-resolve`,
176
+ resolveId(source, importer) {
177
+ if (!importer) return;
178
+ const file = desktopReactNativeFile(importer, source, oneRoot, platform);
179
+ if (file) return file;
180
+ }
181
+ };
182
+ }
183
+ const PLATFORM_VARIANT_EXTS = [
184
+ ".ios.tsx",
185
+ ".ios.ts",
186
+ ".ios.jsx",
187
+ ".ios.js",
188
+ ".android.tsx",
189
+ ".android.ts",
190
+ ".android.jsx",
191
+ ".android.js",
192
+ ".web.tsx",
193
+ ".web.ts",
194
+ ".web.jsx",
195
+ ".web.js"
196
+ ];
197
+ function desktopNormalFile(target, source, platform) {
198
+ if (/\.(?:tsx|ts|jsx|js|mjs|cjs|json)$/.test(source)) return existsSync(target);
199
+ const extensions = getResolveExtensions(platform);
200
+ for (const ext of extensions) {
201
+ if (existsSync(target + ext)) return true;
202
+ if (existsSync(join(target, "index" + ext))) return true;
203
+ }
204
+ return false;
205
+ }
206
+ function desktopVariantSource(target) {
207
+ for (const ext of PLATFORM_VARIANT_EXTS) {
208
+ const file = target + ext;
209
+ if (existsSync(file)) return file;
210
+ }
211
+ return null;
212
+ }
213
+ function desktopPackageImportLabel(variantFile) {
214
+ let dir = dirname(variantFile);
215
+ for (let i = 0; i < 8; i++) {
216
+ const manifest = join(dir, "package.json");
217
+ if (existsSync(manifest)) try {
218
+ const name = JSON.parse(readFileSync(manifest, "utf8")).name;
219
+ if (typeof name === "string" && name.length > 0) return `${name}/${relative(dir, variantFile).split("\\").join("/").replace(/\.(?:ios|android|web)\.(?:tsx|ts|jsx|js)$/, "")}`;
220
+ } catch {}
221
+ const parent = dirname(dir);
222
+ if (parent === dir) break;
223
+ dir = parent;
224
+ }
225
+ return variantFile;
226
+ }
227
+ function desktopUnsupportedImportPlugin(platform) {
228
+ const label = platform === "macos" ? "macOS" : "Linux";
229
+ return {
230
+ name: `vxrn:${platform}-unsupported-import`,
231
+ onLog(_level, log) {
232
+ if (log.code === "UNRESOLVED_IMPORT") this.error({
233
+ ...log,
234
+ message: `[vxrn] ${label} bundle cannot resolve an import: ${log.message}`
235
+ });
236
+ },
237
+ resolveId(source, importer) {
238
+ if (!importer || !source.startsWith(".") || source.includes("\0")) return;
239
+ if (source.includes("?") || source.includes("#")) return;
240
+ const target = resolve(dirname(importer), source);
241
+ if (desktopNormalFile(target, source, platform)) return;
242
+ const variant = desktopVariantSource(target);
243
+ if (!variant) return;
244
+ this.error(`[vxrn] ${desktopPackageImportLabel(variant)} has no ${label} implementation: cannot resolve import "${source}" from "${importer}". Add a .${platform}, .native or plain file.`);
245
+ }
246
+ };
247
+ }
248
+ function desktopDistVariantPlugin(platform) {
249
+ return {
250
+ name: `vxrn:${platform}-dist-variant`,
251
+ resolveId(source, importer) {
252
+ if (!importer || !source.startsWith(".") || !source.endsWith(".native.js")) return;
253
+ if (source.endsWith(`.${platform}.native.js`)) return;
254
+ const variant = resolve(dirname(importer), source).replace(/\.native\.js$/, `.${platform}.native.js`);
255
+ if (variant === importer || !existsSync(variant)) return;
256
+ return variant;
257
+ }
258
+ };
259
+ }
260
+ function getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest, onAsset, sourceMaps = false, userPlugins = [], minify = false, command = "serve") {
157
261
  const context = {
158
262
  root,
159
263
  platform,
160
- dev
264
+ dev,
265
+ command,
266
+ assetsDest
161
267
  };
162
- return [
163
- ...globalThis.__vxrnAddNativePlugins?.(platform) || [],
268
+ const desktopPlugins = platform === "macos" || platform === "linux" ? [
269
+ desktopReactNativeResolvePlugin(root, platform),
270
+ desktopDistVariantPlugin(platform),
271
+ desktopUnsupportedImportPlugin(platform)
272
+ ] : [];
273
+ const globalPlugins = globalThis.__vxrnAddNativePlugins?.(platform) || [];
274
+ const trace = dev && command === "serve" ? [...globalPlugins, ...userPlugins].find((plugin) => plugin.api?.vxrnNativeCompilerTrace)?.api.vxrnNativeCompilerTrace : void 0;
275
+ const plugins = [
276
+ ...desktopPlugins,
277
+ ...globalPlugins,
164
278
  serverFileExclusionPlugin(),
165
279
  environmentGuardPlugin(),
166
280
  missingDynamicImportPlugin(),
@@ -173,7 +287,7 @@ function getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest,
173
287
  viteImportGlobPlugin({ root }),
174
288
  rnCodegenPlugin({ projectRoot: root }),
175
289
  flowStripPlugin(),
176
- vxrnCompilerPlugin(platform, dev, root, sourceMaps),
290
+ vxrnCompilerPlugin(platform, dev, root, sourceMaps, trace),
177
291
  mixedNativeModulePlugin(sourceMaps),
178
292
  nativeAnimatedGuardPlugin(),
179
293
  assetPlugin({
@@ -188,6 +302,55 @@ function getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest,
188
302
  nativeExportsPrecedencePlugin(root, platform),
189
303
  nativeDeclarationAliasPlugin(root, platform)
190
304
  ].map((plugin) => plugin.api?.vxrnNative ? plugin.api.vxrnNative(context) : plugin);
305
+ if (!trace) return plugins;
306
+ const start = (id, stage) => {
307
+ try {
308
+ const record = trace(id);
309
+ if (!record) return;
310
+ const mark = (status) => {
311
+ try {
312
+ record(stage, status);
313
+ } catch {}
314
+ };
315
+ mark("start");
316
+ return mark;
317
+ } catch {}
318
+ };
319
+ return [{
320
+ name: "test-native-hmr-trace-first-pre",
321
+ transform: {
322
+ order: "pre",
323
+ handler(_code, id) {
324
+ start(id, "pre:first")?.("end");
325
+ return null;
326
+ }
327
+ }
328
+ }, ...plugins.map((plugin, index) => {
329
+ if (plugin.name !== "one:use-dom-native" && plugin.name !== "vxrn:rn-codegen" && plugin.name !== "one:background-computation:native" && plugin.name !== "one-client-tree-shake") return plugin;
330
+ const hook = plugin.transform;
331
+ if (!hook || typeof hook === "function" || hook.order !== "pre") return plugin;
332
+ return {
333
+ ...plugin,
334
+ transform: {
335
+ ...hook,
336
+ handler(...args) {
337
+ const mark = start(args[1], `pre:${index}:${plugin.name}`);
338
+ if (!mark) return hook.handler.apply(this, args);
339
+ try {
340
+ const result = hook.handler.apply(this, args);
341
+ if (result instanceof Promise) try {
342
+ Promise.prototype.then.call(result, () => mark("end"), () => mark("error"));
343
+ } catch {}
344
+ else mark("end");
345
+ return result;
346
+ } catch (error) {
347
+ mark("error");
348
+ throw error;
349
+ }
350
+ }
351
+ }
352
+ };
353
+ })];
191
354
  }
192
355
  function getNativeOutputOptions(prelude, sourcemap, minify) {
193
356
  return {
@@ -312,19 +475,19 @@ function postProcessNativeBundle(code) {
312
475
  }
313
476
  return code;
314
477
  }
478
+ const NATIVE_MODULE_SCOPE_MARKER = "// vxrn: native module scope";
479
+ const NATIVE_DEV_RUNTIME_END = "globalThis.__rolldown_runtime__ = new ReactNativeDevRuntime();";
315
480
  function wrapNativeBundleModuleScope(code) {
316
- const idx = code.indexOf("//#region \\0rolldown/runtime.js");
317
- if (idx === -1) return code;
481
+ const idx = code.indexOf(NATIVE_MODULE_SCOPE_MARKER);
482
+ if (idx === -1) throw new Error("[vxrn] the dev bundle lost the end of its prelude, so its modules would run at script scope");
318
483
  return code.slice(0, idx) + ";(function() {" + code.slice(idx) + "\n})();\n";
319
484
  }
320
485
  async function downlevelClassFieldsInBundle(code) {
321
- const startMarker = "//#region \\0rolldown/runtime.js";
322
- const endMarker = "//#endregion";
323
- const startIdx = code.indexOf(startMarker);
324
- if (startIdx === -1) return code;
325
- const endIdx = code.indexOf(endMarker, startIdx);
326
- if (endIdx === -1) return code;
327
- const runtimeEnd = endIdx + 12;
486
+ const markerIdx = code.indexOf(NATIVE_MODULE_SCOPE_MARKER);
487
+ const endIdx = markerIdx === -1 ? -1 : code.indexOf(NATIVE_DEV_RUNTIME_END, markerIdx);
488
+ if (endIdx === -1) throw new Error("[vxrn] could not locate the rolldown runtime in the dev bundle");
489
+ const startIdx = code.indexOf("\n", markerIdx) + 1;
490
+ const runtimeEnd = endIdx + 62;
328
491
  const runtimeSection = code.slice(startIdx, runtimeEnd);
329
492
  const originalNewlines = runtimeSection.match(/\n/g)?.length ?? 0;
330
493
  const { transformSync } = await import("oxc-transform");
@@ -333,19 +496,17 @@ async function downlevelClassFieldsInBundle(code) {
333
496
  assumptions: { setPublicClassFields: true }
334
497
  });
335
498
  if (result.errors?.length) throw new Error(result.errors.map((e) => e.message).join("\n"));
336
- const transformedCode = result.code.trimEnd();
337
- const transformed = transformedCode.includes(startMarker) ? transformedCode : `${startMarker}
338
- ${transformedCode}`;
499
+ const transformed = result.code.trimEnd();
339
500
  const transformedNewlines = transformed.match(/\n/g)?.length ?? 0;
340
- if (transformedNewlines > originalNewlines) throw new Error("[vxrn] Hermes runtime transform added lines and would invalidate the production source map");
501
+ if (transformedNewlines > originalNewlines) throw new Error("[vxrn] Hermes runtime transform added lines and would invalidate the dev source map");
341
502
  const linePreservingRuntime = transformed + "\n".repeat(originalNewlines - transformedNewlines);
342
503
  return code.slice(0, startIdx) + linePreservingRuntime + code.slice(runtimeEnd);
343
504
  }
344
505
  function nativeBundlePostProcessPlugin() {
345
506
  return {
346
507
  name: "vxrn:native-post-process",
347
- async renderChunk(code) {
348
- const processed = await downlevelClassFieldsInBundle(postProcessNativeBundle(code));
508
+ renderChunk(code) {
509
+ const processed = postProcessNativeBundle(code);
349
510
  assertBundleLinesPreserved(code, processed, "production");
350
511
  return {
351
512
  code: processed,
@@ -401,7 +562,8 @@ async function createNativeDevEngine(options) {
401
562
  plugins: [virtualEntry.plugin, ...getNativePlugins(root, platform, viteImportGlobPlugin, true, void 0, assetRegistry.register, true, userPlugins)]
402
563
  };
403
564
  const outputOptions = {
404
- ...getNativeOutputOptions(prelude, true, false),
565
+ ...getNativeOutputOptions(`${prelude}
566
+ ${NATIVE_MODULE_SCOPE_MARKER}`, true, false),
405
567
  outro: `
406
568
  try {
407
569
  var __WS = (init_WebSocket(), __toCommonJS(WebSocket_exports)).default;
@@ -493,6 +655,7 @@ try {
493
655
  code = postProcessNativeBundle(chunk.code);
494
656
  code = await downlevelClassFieldsInBundle(code);
495
657
  assertBundleLinesPreserved(chunk.code, code, "dev");
658
+ code = wrapNativeBundleModuleScope(code);
496
659
  } catch (error) {
497
660
  const failure = error instanceof Error ? error : new Error(String(error));
498
661
  console.error("[vxrn] native bundle post-processing failed:", failure.message);
@@ -508,7 +671,6 @@ try {
508
671
  }
509
672
  return;
510
673
  }
511
- code = wrapNativeBundleModuleScope(code);
512
674
  if (!chunk.map) throw new Error("[vxrn] rolldown produced no source map for the dev bundle, so /symbolicate cannot resolve a frame");
513
675
  currentBundle = {
514
676
  code,
@@ -612,7 +774,7 @@ async function buildNativeBundle(options) {
612
774
  dev,
613
775
  platform
614
776
  }).plugin],
615
- ...getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest, void 0, sourcemap, userPlugins, minify),
777
+ ...getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest, void 0, sourcemap, userPlugins, minify, "build"),
616
778
  nativeBundlePostProcessPlugin()
617
779
  ],
618
780
  output: {
@@ -639,7 +801,8 @@ function nativeVirtualEntryPlugin(root, opts) {
639
801
  const setupFileImport = (() => {
640
802
  const sf = entryConfig.setupFile;
641
803
  if (!sf) return "";
642
- const file = typeof sf === "string" ? sf : "native" in sf ? sf.native : sf.ios;
804
+ const perPlatform = sf;
805
+ const file = typeof sf === "string" ? sf : "native" in sf ? sf.native : opts.platform === "macos" || opts.platform === "linux" ? perPlatform[opts.platform] : sf.ios;
643
806
  if (!file) return "";
644
807
  const resolved = pathToFileURL(resolve(root, file)).href;
645
808
  return `import ${JSON.stringify(resolved)};`;
@@ -1084,7 +1247,7 @@ function cssStubPlugin() {
1084
1247
  } }
1085
1248
  };
1086
1249
  }
1087
- function vxrnCompilerPlugin(platform, dev, projectRoot = process.cwd(), sourceMaps = false) {
1250
+ function vxrnCompilerPlugin(platform, dev, projectRoot = process.cwd(), sourceMaps = false, trace) {
1088
1251
  let compiler = null;
1089
1252
  const isRefreshCandidate = (id) => dev && !id.includes("node_modules") && !id.includes("__virtual-native-entry") && /\.[tj]sx?$/.test(id);
1090
1253
  return {
@@ -1092,93 +1255,92 @@ function vxrnCompilerPlugin(platform, dev, projectRoot = process.cwd(), sourceMa
1092
1255
  async transform(code, id) {
1093
1256
  if (!/\.[cm]?[jt]sx?$/.test(id)) return;
1094
1257
  if (id.includes("\0") || id.includes("virtual:")) return;
1095
- const needsRefresh = isRefreshCandidate(id);
1096
- if (!compiler) compiler = await import("@vxrn/compiler");
1097
- const props = {
1098
- id,
1099
- code,
1100
- projectRoot,
1101
- development: dev,
1102
- environment: platform,
1103
- reactForRNVersion: "19"
1104
- };
1105
- let babelOptions = compiler.getBabelOptions(props);
1106
- let curCode = code;
1107
- const intermediateMaps = [];
1108
- const isWorkletPlugin = (entry) => {
1109
- if (!entry) return false;
1110
- const name = typeof entry === "string" ? entry : Array.isArray(entry) ? entry[0] : null;
1111
- return typeof name === "string" && (name.includes("react-native-worklets") || name.includes("react-native-reanimated"));
1112
- };
1113
- const workletEntry = babelOptions?.plugins?.find(isWorkletPlugin);
1114
- const workletPluginOptions = Array.isArray(workletEntry) ? workletEntry[1] : void 0;
1115
- const useWorklets = compiler.isNativeWorkletsEnabled() && (Boolean(workletEntry) || compiler.shouldTransformWorklets({
1116
- id,
1117
- code
1118
- }));
1119
- const compilerPluginIndex = babelOptions?.plugins?.findIndex((x) => Array.isArray(x) && x[0] === "babel-plugin-react-compiler") ?? -1;
1120
- if (compilerPluginIndex !== -1) {
1121
- if (useWorklets) {
1122
- const prepared = compiler.prepareWorkletsForReactCompiler(id, curCode, sourceMaps);
1123
- if (prepared) {
1124
- curCode = prepared.code;
1125
- if (prepared.map) intermediateMaps.push(prepared.map);
1126
- }
1127
- }
1128
- const compilerPluginOptions = babelOptions.plugins[compilerPluginIndex][1] || {};
1129
- if (!(compilerPluginOptions.compiler === "babel" || process.env.ONE_REACT_COMPILER === "babel" || process.env.VXRN_REACT_COMPILER === "babel")) {
1130
- const compilerOut = await compiler.transformOxcReactCompiler(id, curCode, compilerPluginOptions, sourceMaps);
1131
- if (compilerOut?.code) {
1132
- curCode = compilerOut.code;
1133
- if (sourceMaps && compilerOut.map) intermediateMaps.push(compilerOut.map);
1134
- }
1135
- babelOptions.plugins.splice(compilerPluginIndex, 1);
1136
- if (babelOptions.plugins.length === 0 && !babelOptions.configFile && !babelOptions.babelrc) babelOptions = null;
1258
+ let active = "transform";
1259
+ let failed = false;
1260
+ let mark;
1261
+ if (trace) try {
1262
+ const record = trace(id);
1263
+ if (record) mark = (stage, status) => {
1264
+ active = status === "start" ? stage : "transform";
1265
+ try {
1266
+ record(stage, status);
1267
+ } catch {}
1268
+ };
1269
+ } catch {}
1270
+ mark?.("transform", "start");
1271
+ try {
1272
+ const needsRefresh = isRefreshCandidate(id);
1273
+ if (!compiler) {
1274
+ mark?.("compiler-import", "start");
1275
+ compiler = await import("@vxrn/compiler");
1276
+ mark?.("compiler-import", "end");
1137
1277
  }
1138
- }
1139
- if (useWorklets) {
1140
- const workletOut = await compiler.transformWorklets(id, curCode, sourceMaps, {
1278
+ const props = {
1279
+ id,
1280
+ code,
1141
1281
  projectRoot,
1142
- ...workletPluginOptions
1143
- });
1144
- if (workletOut?.code) {
1145
- curCode = workletOut.code;
1146
- if (sourceMaps && workletOut.map) intermediateMaps.push(workletOut.map);
1147
- }
1148
- if (babelOptions?.plugins) {
1149
- babelOptions.plugins = babelOptions.plugins.filter((entry) => !isWorkletPlugin(entry));
1150
- if (babelOptions.plugins.length === 0 && !babelOptions.configFile && !babelOptions.babelrc) babelOptions = null;
1282
+ development: dev,
1283
+ environment: platform === "android" ? "android" : "ios",
1284
+ reactForRNVersion: "19"
1285
+ };
1286
+ mark?.("options", "start");
1287
+ let babelOptions = compiler.getBabelOptions(props);
1288
+ mark?.("options", "end");
1289
+ let curCode = code;
1290
+ const intermediateMaps = [];
1291
+ const isWorkletPlugin = (entry) => {
1292
+ if (!entry) return false;
1293
+ const name = typeof entry === "string" ? entry : Array.isArray(entry) ? entry[0] : null;
1294
+ return typeof name === "string" && (name.includes("react-native-worklets") || name.includes("react-native-reanimated"));
1295
+ };
1296
+ const workletEntry = babelOptions?.plugins?.find(isWorkletPlugin);
1297
+ const workletPluginOptions = Array.isArray(workletEntry) ? workletEntry[1] : void 0;
1298
+ const useWorklets = compiler.isNativeWorkletsEnabled() && (Boolean(workletEntry) || compiler.shouldTransformWorklets({
1299
+ id,
1300
+ code
1301
+ }));
1302
+ const compilerPluginIndex = babelOptions?.plugins?.findIndex((x) => Array.isArray(x) && x[0] === "babel-plugin-react-compiler") ?? -1;
1303
+ if (compilerPluginIndex !== -1) {
1304
+ if (useWorklets) {
1305
+ mark?.("worklets-prepare", "start");
1306
+ const prepared = compiler.prepareWorkletsForReactCompiler(id, curCode, sourceMaps);
1307
+ mark?.("worklets-prepare", "end");
1308
+ if (prepared) {
1309
+ curCode = prepared.code;
1310
+ if (prepared.map) intermediateMaps.push(prepared.map);
1311
+ }
1312
+ }
1313
+ const compilerPluginOptions = babelOptions.plugins[compilerPluginIndex][1] || {};
1314
+ if (!(compilerPluginOptions.compiler === "babel" || process.env.ONE_REACT_COMPILER === "babel" || process.env.VXRN_REACT_COMPILER === "babel")) {
1315
+ mark?.("oxc-react-compiler", "start");
1316
+ const compilerOut = await compiler.transformOxcReactCompiler(id, curCode, compilerPluginOptions, sourceMaps);
1317
+ mark?.("oxc-react-compiler", "end");
1318
+ if (compilerOut?.code) {
1319
+ curCode = compilerOut.code;
1320
+ if (sourceMaps && compilerOut.map) intermediateMaps.push(compilerOut.map);
1321
+ }
1322
+ babelOptions.plugins.splice(compilerPluginIndex, 1);
1323
+ if (babelOptions.plugins.length === 0 && !babelOptions.configFile && !babelOptions.babelrc) babelOptions = null;
1324
+ }
1151
1325
  }
1152
- }
1153
- if (!babelOptions && !needsRefresh) {
1154
- if (curCode !== code) {
1155
- let finalMap = void 0;
1156
- if (sourceMaps && intermediateMaps.length > 0) if (intermediateMaps.length === 1) finalMap = intermediateMaps[0];
1157
- else {
1158
- const remapping = (await import("@jridgewell/remapping")).default;
1159
- finalMap = remapping(intermediateMaps.slice().reverse(), () => null);
1326
+ if (useWorklets) {
1327
+ mark?.("worklets", "start");
1328
+ const workletOut = await compiler.transformWorklets(id, curCode, sourceMaps, {
1329
+ projectRoot,
1330
+ ...workletPluginOptions
1331
+ });
1332
+ mark?.("worklets", "end");
1333
+ if (workletOut?.code) {
1334
+ curCode = workletOut.code;
1335
+ if (sourceMaps && workletOut.map) intermediateMaps.push(workletOut.map);
1336
+ }
1337
+ if (babelOptions?.plugins) {
1338
+ babelOptions.plugins = babelOptions.plugins.filter((entry) => !isWorkletPlugin(entry));
1339
+ if (babelOptions.plugins.length === 0 && !babelOptions.configFile && !babelOptions.babelrc) babelOptions = null;
1160
1340
  }
1161
- return {
1162
- code: curCode,
1163
- map: finalMap
1164
- };
1165
1341
  }
1166
- return;
1167
- }
1168
- if (sourceMaps && babelOptions) {
1169
- babelOptions = {
1170
- ...babelOptions,
1171
- sourceMaps: true,
1172
- sourceFileName: id
1173
- };
1174
- delete babelOptions.inputSourceMap;
1175
- }
1176
- if (babelOptions) {
1177
- const result = await compiler.transformBabel(id, curCode, babelOptions);
1178
- if (result?.code) {
1179
- curCode = result.code;
1180
- if (sourceMaps && result.map) intermediateMaps.push(result.map);
1181
- if (!needsRefresh) {
1342
+ if (!babelOptions && !needsRefresh) {
1343
+ if (curCode !== code) {
1182
1344
  let finalMap = void 0;
1183
1345
  if (sourceMaps && intermediateMaps.length > 0) if (intermediateMaps.length === 1) finalMap = intermediateMaps[0];
1184
1346
  else {
@@ -1190,26 +1352,59 @@ function vxrnCompilerPlugin(platform, dev, projectRoot = process.cwd(), sourceMa
1190
1352
  map: finalMap
1191
1353
  };
1192
1354
  }
1355
+ return;
1193
1356
  }
1194
- }
1195
- if (needsRefresh) {
1196
- const { transformSync } = await import("oxc-transform-react");
1197
- const jsxImportSource = compiler.configuration?.enableNativewind && !id.includes("node_modules") ? "nativewind" : "react";
1198
- const res = transformSync(id, curCode, {
1199
- jsx: {
1200
- development: dev,
1201
- runtime: "automatic",
1202
- importSource: jsxImportSource,
1203
- refresh: {
1204
- refreshReg: "__vxrnRefreshReg",
1205
- refreshSig: "__vxrnRefreshSig"
1357
+ if (sourceMaps && babelOptions) {
1358
+ babelOptions = {
1359
+ ...babelOptions,
1360
+ sourceMaps: true,
1361
+ sourceFileName: id
1362
+ };
1363
+ delete babelOptions.inputSourceMap;
1364
+ }
1365
+ if (babelOptions) {
1366
+ mark?.("babel", "start");
1367
+ const result = await compiler.transformBabel(id, curCode, babelOptions);
1368
+ mark?.("babel", "end");
1369
+ if (result?.code) {
1370
+ curCode = result.code;
1371
+ if (sourceMaps && result.map) intermediateMaps.push(result.map);
1372
+ if (!needsRefresh) {
1373
+ let finalMap = void 0;
1374
+ if (sourceMaps && intermediateMaps.length > 0) if (intermediateMaps.length === 1) finalMap = intermediateMaps[0];
1375
+ else {
1376
+ const remapping = (await import("@jridgewell/remapping")).default;
1377
+ finalMap = remapping(intermediateMaps.slice().reverse(), () => null);
1378
+ }
1379
+ return {
1380
+ code: curCode,
1381
+ map: finalMap
1382
+ };
1206
1383
  }
1207
- },
1208
- reactCompiler: false,
1209
- sourcemap: sourceMaps
1210
- });
1211
- if (res.fatal) throw new Error(`[vxrn:compiler] oxc react transform failed on ${id}: ${(res.errors ?? []).map((e) => e.message ?? String(e)).join(", ")}`);
1212
- const header = `var __prevRefreshReg = globalThis.$RefreshReg$;
1384
+ }
1385
+ }
1386
+ if (needsRefresh) {
1387
+ mark?.("refresh-import", "start");
1388
+ const { transformSync } = await import("oxc-transform-react");
1389
+ mark?.("refresh-import", "end");
1390
+ const jsxImportSource = compiler.configuration?.enableNativewind && !id.includes("node_modules") ? "nativewind" : "react";
1391
+ mark?.("refresh", "start");
1392
+ const res = transformSync(id, curCode, {
1393
+ jsx: {
1394
+ development: dev,
1395
+ runtime: "automatic",
1396
+ importSource: jsxImportSource,
1397
+ refresh: {
1398
+ refreshReg: "__vxrnRefreshReg",
1399
+ refreshSig: "__vxrnRefreshSig"
1400
+ }
1401
+ },
1402
+ reactCompiler: false,
1403
+ sourcemap: sourceMaps
1404
+ });
1405
+ if (res.fatal) throw new Error(`[vxrn:compiler] oxc react transform failed on ${id}: ${(res.errors ?? []).map((e) => e.message ?? String(e)).join(", ")}`);
1406
+ mark?.("refresh", "end");
1407
+ const header = `var __prevRefreshReg = globalThis.$RefreshReg$;
1213
1408
  var __prevRefreshSig = globalThis.$RefreshSig$;
1214
1409
  if (globalThis.__ReactRefresh) {
1215
1410
  globalThis.$RefreshReg$ = function(type, id) {
@@ -1222,7 +1417,7 @@ var __vxrnRefreshReg = globalThis.$RefreshReg$;
1222
1417
  var __vxrnRefreshSig = globalThis.$RefreshSig$;
1223
1418
 
1224
1419
  `;
1225
- const footer = `
1420
+ const footer = `
1226
1421
 
1227
1422
  globalThis.$RefreshReg$ = __prevRefreshReg;
1228
1423
  globalThis.$RefreshSig$ = __prevRefreshSig;
@@ -1234,29 +1429,36 @@ if (import.meta.hot) {
1234
1429
  });
1235
1430
  }
1236
1431
  `;
1237
- let out;
1238
- let finalMap = void 0;
1239
- if (sourceMaps) {
1240
- const MagicString = (await import("magic-string")).default;
1241
- const ms = new MagicString(res.code);
1242
- ms.prepend(header);
1243
- ms.append(footer);
1244
- out = ms.toString();
1245
- const allMaps = [
1246
- ms.generateMap({
1247
- source: id,
1248
- hires: true
1249
- }),
1250
- res.map,
1251
- ...intermediateMaps.slice().reverse()
1252
- ].filter(Boolean);
1253
- const remapping = (await import("@jridgewell/remapping")).default;
1254
- finalMap = remapping(allMaps, () => null);
1255
- } else out = header + res.code + footer;
1256
- return {
1257
- code: out,
1258
- map: finalMap
1259
- };
1432
+ let out;
1433
+ let finalMap = void 0;
1434
+ if (sourceMaps) {
1435
+ const MagicString = (await import("magic-string")).default;
1436
+ const ms = new MagicString(res.code);
1437
+ ms.prepend(header);
1438
+ ms.append(footer);
1439
+ out = ms.toString();
1440
+ const allMaps = [
1441
+ ms.generateMap({
1442
+ source: id,
1443
+ hires: true
1444
+ }),
1445
+ res.map,
1446
+ ...intermediateMaps.slice().reverse()
1447
+ ].filter(Boolean);
1448
+ const remapping = (await import("@jridgewell/remapping")).default;
1449
+ finalMap = remapping(allMaps, () => null);
1450
+ } else out = header + res.code + footer;
1451
+ return {
1452
+ code: out,
1453
+ map: finalMap
1454
+ };
1455
+ }
1456
+ } catch (error) {
1457
+ failed = true;
1458
+ if (active !== "transform") mark?.(active, "error");
1459
+ throw error;
1460
+ } finally {
1461
+ mark?.("transform", failed ? "error" : "end");
1260
1462
  }
1261
1463
  }
1262
1464
  };
@@ -1751,9 +1953,9 @@ class ReactNativeDevRuntime extends BaseDevRuntime {
1751
1953
  }
1752
1954
  }
1753
1955
 
1754
- globalThis.__rolldown_runtime__ = new ReactNativeDevRuntime();
1956
+ ${NATIVE_DEV_RUNTIME_END}
1755
1957
  `;
1756
1958
  }
1757
1959
 
1758
- export { buildNativeBundle, createNativeDevAssetRegistry, createNativeDevEngine, getHermesSWCIncludes, getHmrRuntimeSource, getNativeAssetData, getNativeTransformConfig, hermesCompatPlugin, hermesCompatSWCPlugin, hermesLoopsPlugin, hmrClientNoopPlugin, nativeAnimatedGuardPlugin, normalizeNativeCommonJSInterop, postProcessNativeBundle, vxrnCompilerPlugin, wrapNativeBundleModuleScope };
1960
+ export { NATIVE_DEV_RUNTIME_END, NATIVE_MODULE_SCOPE_MARKER, buildNativeBundle, createNativeDevAssetRegistry, createNativeDevEngine, getHermesSWCIncludes, getHmrRuntimeSource, getNativeAssetData, getNativeTransformConfig, hermesCompatPlugin, hermesCompatSWCPlugin, hermesLoopsPlugin, hmrClientNoopPlugin, nativeAnimatedGuardPlugin, normalizeNativeCommonJSInterop, postProcessNativeBundle, vxrnCompilerPlugin, wrapNativeBundleModuleScope };
1759
1961
  //# sourceMappingURL=createNativeDevEngine.mjs.map