rnxsim 0.1.394 → 0.1.396

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 +12 -5
  2. package/dist-lib/agent-daemon-client.cjs +1 -1
  3. package/dist-lib/agent-events.cjs +1 -1
  4. package/dist-lib/agent-identity.cjs +1 -1
  5. package/dist-lib/agent-sessions.cjs +1 -1
  6. package/dist-lib/attached-projects.cjs +1 -1
  7. package/dist-lib/auth/shared-session.cjs +1 -1
  8. package/dist-lib/backend-origin.cjs +1 -1
  9. package/dist-lib/beta.cjs +1 -1
  10. package/dist-lib/beta.mjs +1 -1
  11. package/dist-lib/bridge-constants.cjs +1 -1
  12. package/dist-lib/bridge-contract-input.cjs +1 -1
  13. package/dist-lib/bridge-contract-input.mjs +1 -1
  14. package/dist-lib/bridge-contract.cjs +1 -1
  15. package/dist-lib/bridge-contract.mjs +1 -1
  16. package/dist-lib/capture-contract.cjs +1 -1
  17. package/dist-lib/capture-contract.mjs +1 -1
  18. package/dist-lib/cli-constants.cjs +1 -1
  19. package/dist-lib/cloud-contract.cjs +1 -1
  20. package/dist-lib/cloud-contract.mjs +1 -1
  21. package/dist-lib/config.cjs +1 -1
  22. package/dist-lib/detox/index.cjs +1 -1
  23. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  24. package/dist-lib/home-paths.cjs +1 -1
  25. package/dist-lib/host/bridge-host.cjs +1 -1
  26. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  27. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  28. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  29. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  30. package/dist-lib/host/websocket-proxy.cjs +1 -1
  31. package/dist-lib/index.cjs +3 -53
  32. package/dist-lib/jump-to-source-babel.cjs +1 -1
  33. package/dist-lib/menu.cjs +1 -1
  34. package/dist-lib/menu.mjs +1 -1
  35. package/dist-lib/metro-production-bundle.cjs +1 -6
  36. package/dist-lib/metro-production-bundle.mjs +1 -5
  37. package/dist-lib/metro.cjs +3 -55
  38. package/dist-lib/profiles.cjs +1 -1
  39. package/dist-lib/public-brand.cjs +1 -1
  40. package/dist-lib/react-native-host-modules.cjs +1 -1
  41. package/dist-lib/react-native-host-modules.mjs +1 -1
  42. package/dist-lib/render-mode.cjs +1 -1
  43. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  44. package/dist-lib/sdk.cjs +1 -1
  45. package/dist-lib/sdk.mjs +1 -1
  46. package/dist-lib/skills.cjs +1 -1
  47. package/dist-lib/vite.cjs +1 -1
  48. package/package.json +1 -1
  49. package/src/metro-plugin.ts +17 -98
  50. package/src/metro-production-bundle.ts +4 -3
  51. package/dist-lib/metro-host-modules/react-dom.js +0 -6
  52. package/dist-lib/metro-host-modules/react-native-web.js +0 -6
  53. package/dist-lib/metro-host-modules/react-native.js +0 -6
  54. package/dist-lib/metro-host-modules/react.js +0 -6
  55. package/dist-lib/metro-host-modules/react__jsx-dev-runtime.js +0 -6
  56. package/dist-lib/metro-host-modules/react__jsx-runtime.js +0 -6
  57. package/src/metro-host-modules/react-dom.js +0 -6
  58. package/src/metro-host-modules/react-native-web.js +0 -6
  59. package/src/metro-host-modules/react-native.js +0 -6
  60. package/src/metro-host-modules/react.js +0 -6
  61. package/src/metro-host-modules/react__jsx-dev-runtime.js +0 -6
  62. package/src/metro-host-modules/react__jsx-runtime.js +0 -6
package/README.md CHANGED
@@ -386,9 +386,15 @@ development Electron build against the same user-data directory may ask for
386
386
  one-time Keychain approval. `RNX_NO_OPEN=1` keeps the server headless. The
387
387
  Metro wrapper also has two independent non-window opt-ins.
388
388
  `devServer` serves the RNX shell from the Metro process. `productionBundles`
389
- lets explicitly marked production bundle requests use the RNX host
390
- implementations of React and React Native while the rest of the app receives
391
- production transforms.
389
+ appends Metro's exact module-ID-to-source-path map to every production bundle,
390
+ as a trailing `globalThis.__sootsimModulePaths = { ... }` assignment.
391
+
392
+ That footer is the only change. Metro drops the fourth `__d` argument when
393
+ `dev` is false, so a production bundle names none of its modules, and RNX needs
394
+ those names to recognize React, React Native, and native compatibility seams at
395
+ load time. Resolution, transforms, minification, and the source map stay the
396
+ app's own, so the annotated bundle is the bundle you ship: the footer assigns
397
+ one unused global on a device, and Hermes drops it during bytecode compilation.
392
398
 
393
399
  ```js
394
400
  module.exports = withRNX(config, { productionBundles: true })
@@ -400,8 +406,9 @@ module.exports = withRNX(config, {
400
406
  })
401
407
  ```
402
408
 
403
- Calling `withRNX(config)` changes nothing. Production requests must run in a
404
- Metro process started with `NODE_ENV=production` and use the URL helper:
409
+ Calling `withRNX(config)` changes nothing. To load a production bundle from a
410
+ running Metro dev server, use the URL helper, which sets Metro's ordinary
411
+ `dev=false&minify=true` options:
405
412
 
406
413
  ```js
407
414
  const { toRNXProductionBundleUrl } = require('rnxsim/metro')
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/beta.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/beta.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/beta.ts
4
4
  var IS_BETA = true;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var SIM_LONG_PRESS_MAX_MS = 5e3;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var SIM_LONG_PRESS_DEFAULT_MS = 500;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/capture-contract.ts
4
4
  var RNX_SCREEN_CAPTURE_VERSION = 1;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/cloud-contract.ts
4
4
  var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/host/fetch-proxy-overrides.ts
4
4
  var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -3491,7 +3491,6 @@ var import_node_crypto4 = require("node:crypto");
3491
3491
  var import_path4 = __toESM(require("path"), 1);
3492
3492
 
3493
3493
  // src/metro-production-bundle.ts
3494
- var RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION = "rnxsim";
3495
3494
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
3496
3495
  function createRNXMetroModulePathsFooter(modulePaths) {
3497
3496
  const payload = JSON.stringify(modulePaths).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
@@ -3501,35 +3500,6 @@ ${RNXSIM_METRO_MODULE_PATHS_PREFIX}${payload};`;
3501
3500
 
3502
3501
  // src/metro-plugin.ts
3503
3502
  var prefix = "/__soot";
3504
- var hostModuleSpecifiers = [
3505
- "react",
3506
- "react-dom",
3507
- "react/jsx-runtime",
3508
- "react/jsx-dev-runtime",
3509
- "react-native",
3510
- "react-native-web"
3511
- ];
3512
- function isRNXProductionBundle(graph) {
3513
- return graph.transformOptions?.dev === false && graph.transformOptions.customTransformOptions?.[RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION] === "true";
3514
- }
3515
- function assertProductionEnvironment() {
3516
- if (process.env.NODE_ENV === "production") return;
3517
- throw new Error(
3518
- "rnxsim: production bundle requests require NODE_ENV=production; restart Metro with NODE_ENV=production"
3519
- );
3520
- }
3521
- function hostModuleFileName(specifier) {
3522
- return `${specifier.replaceAll("/", "__")}.js`;
3523
- }
3524
- function resolveHostModules() {
3525
- const root = import_path4.default.join(__dirname, "metro-host-modules");
3526
- const files = /* @__PURE__ */ new Map();
3527
- for (const specifier of hostModuleSpecifiers) {
3528
- const filePath = import_path4.default.join(root, hostModuleFileName(specifier));
3529
- files.set(specifier, filePath);
3530
- }
3531
- return { root, files };
3532
- }
3533
3503
  function readCallableMetroExport(moduleValue, label) {
3534
3504
  const callable = typeof moduleValue === "function" ? moduleValue : typeof moduleValue === "object" && moduleValue !== null ? Reflect.get(moduleValue, "default") : void 0;
3535
3505
  if (typeof callable !== "function") {
@@ -3559,7 +3529,7 @@ function createMetroDefaultSerializer(projectRoot) {
3559
3529
  return code;
3560
3530
  };
3561
3531
  }
3562
- function prependRNXModulePaths(result, graph, options, projectRoot) {
3532
+ function appendRNXModulePaths(result, graph, options, projectRoot) {
3563
3533
  const dependencies = graph.dependencies;
3564
3534
  const createModuleId = options.createModuleId;
3565
3535
  if (!dependencies || !createModuleId) {
@@ -3592,44 +3562,24 @@ function withRNX(config, options = {}) {
3592
3562
  cfgProjectRoot,
3593
3563
  appName
3594
3564
  );
3595
- const cfgResolver = config.resolver;
3596
3565
  const cfgSerializer = config.serializer;
3597
3566
  const existingEnhance = cfgServer?.enhanceMiddleware;
3598
- const existingResolveRequest = cfgResolver?.resolveRequest;
3599
3567
  const existingSerializer = cfgSerializer?.customSerializer;
3600
3568
  let productionConfig = {};
3601
3569
  if (options.productionBundles) {
3602
- const hostModules = resolveHostModules();
3603
3570
  let defaultSerializer;
3604
3571
  productionConfig = {
3605
- watchFolders: [
3606
- ...config.watchFolders || [],
3607
- hostModules.root
3608
- ],
3609
- resolver: {
3610
- ...cfgResolver,
3611
- resolveRequest: (context, moduleName, platform) => {
3612
- if (context.customResolverOptions?.[RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION] === "true") {
3613
- assertProductionEnvironment();
3614
- const hostModule = hostModules.files.get(moduleName);
3615
- if (hostModule) return { type: "sourceFile", filePath: hostModule };
3616
- }
3617
- return existingResolveRequest ? existingResolveRequest(context, moduleName, platform) : context.resolveRequest(context, moduleName, platform);
3618
- }
3619
- },
3620
3572
  serializer: {
3621
3573
  ...cfgSerializer,
3622
3574
  customSerializer: async (entryPoint, preModules, graph, serializerOptions) => {
3623
3575
  const serializer = existingSerializer || (defaultSerializer ||= createMetroDefaultSerializer(cfgProjectRoot));
3624
- const productionBundle = isRNXProductionBundle(graph);
3625
- if (productionBundle) assertProductionEnvironment();
3626
3576
  const result = await serializer(
3627
3577
  entryPoint,
3628
3578
  preModules,
3629
3579
  graph,
3630
3580
  serializerOptions
3631
3581
  );
3632
- return productionBundle ? prependRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot) : result;
3582
+ return graph.transformOptions?.dev === false ? appendRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot) : result;
3633
3583
  }
3634
3584
  }
3635
3585
  };
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/menu.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/menu.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/public-brand.ts
4
4
  var name = "rnx";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -22,7 +22,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
22
  // src/metro-production-bundle.ts
23
23
  var metro_production_bundle_exports = {};
24
24
  __export(metro_production_bundle_exports, {
25
- RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION: () => RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION,
26
25
  createRNXMetroModulePathsFooter: () => createRNXMetroModulePathsFooter,
27
26
  readRNXMetroBundleLayout: () => readRNXMetroBundleLayout,
28
27
  readRNXMetroModuleIdentity: () => readRNXMetroModuleIdentity,
@@ -30,7 +29,6 @@ __export(metro_production_bundle_exports, {
30
29
  validateRNXMetroModulePaths: () => validateRNXMetroModulePaths
31
30
  });
32
31
  module.exports = __toCommonJS(metro_production_bundle_exports);
33
- var RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION = "rnxsim";
34
32
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
35
33
  function toRNXProductionBundleUrl(bundleUrl) {
36
34
  const relative = bundleUrl.startsWith("/");
@@ -38,8 +36,6 @@ function toRNXProductionBundleUrl(bundleUrl) {
38
36
  url.searchParams.set("dev", "false");
39
37
  url.searchParams.set("hot", "false");
40
38
  url.searchParams.set("minify", "true");
41
- url.searchParams.set(`resolver.${RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION}`, "true");
42
- url.searchParams.set(`transform.${RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION}`, "true");
43
39
  return relative ? `${url.pathname}${url.search}${url.hash}` : url.toString();
44
40
  }
45
41
  function createRNXMetroModulePathsFooter(modulePaths) {
@@ -192,7 +188,6 @@ function validateRNXMetroModulePaths(source, modulePaths) {
192
188
  }
193
189
  // Annotate the CommonJS export names for ESM import in node:
194
190
  0 && (module.exports = {
195
- RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION,
196
191
  createRNXMetroModulePathsFooter,
197
192
  readRNXMetroBundleLayout,
198
193
  readRNXMetroModuleIdentity,
@@ -1,7 +1,6 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/metro-production-bundle.ts
4
- var RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION = "rnxsim";
5
4
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
6
5
  function toRNXProductionBundleUrl(bundleUrl) {
7
6
  const relative = bundleUrl.startsWith("/");
@@ -9,8 +8,6 @@ function toRNXProductionBundleUrl(bundleUrl) {
9
8
  url.searchParams.set("dev", "false");
10
9
  url.searchParams.set("hot", "false");
11
10
  url.searchParams.set("minify", "true");
12
- url.searchParams.set(`resolver.${RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION}`, "true");
13
- url.searchParams.set(`transform.${RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION}`, "true");
14
11
  return relative ? `${url.pathname}${url.search}${url.hash}` : url.toString();
15
12
  }
16
13
  function createRNXMetroModulePathsFooter(modulePaths) {
@@ -162,7 +159,6 @@ function validateRNXMetroModulePaths(source, modulePaths) {
162
159
  }
163
160
  }
164
161
  export {
165
- RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION,
166
162
  createRNXMetroModulePathsFooter,
167
163
  readRNXMetroBundleLayout,
168
164
  readRNXMetroModuleIdentity,
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -410,7 +410,6 @@ exports.jsxDEV = exports.jsx`,
410
410
  }
411
411
 
412
412
  // src/metro-production-bundle.ts
413
- var RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION = "rnxsim";
414
413
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
415
414
  function toRNXProductionBundleUrl(bundleUrl) {
416
415
  const relative = bundleUrl.startsWith("/");
@@ -418,8 +417,6 @@ function toRNXProductionBundleUrl(bundleUrl) {
418
417
  url.searchParams.set("dev", "false");
419
418
  url.searchParams.set("hot", "false");
420
419
  url.searchParams.set("minify", "true");
421
- url.searchParams.set(`resolver.${RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION}`, "true");
422
- url.searchParams.set(`transform.${RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION}`, "true");
423
420
  return relative ? `${url.pathname}${url.search}${url.hash}` : url.toString();
424
421
  }
425
422
  function createRNXMetroModulePathsFooter(modulePaths) {
@@ -606,35 +603,6 @@ function serveRuntimeFile(req, res, fullPath) {
606
603
 
607
604
  // src/metro-plugin.ts
608
605
  var prefix = "/__soot";
609
- var hostModuleSpecifiers = [
610
- "react",
611
- "react-dom",
612
- "react/jsx-runtime",
613
- "react/jsx-dev-runtime",
614
- "react-native",
615
- "react-native-web"
616
- ];
617
- function isRNXProductionBundle(graph) {
618
- return graph.transformOptions?.dev === false && graph.transformOptions.customTransformOptions?.[RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION] === "true";
619
- }
620
- function assertProductionEnvironment() {
621
- if (process.env.NODE_ENV === "production") return;
622
- throw new Error(
623
- "rnxsim: production bundle requests require NODE_ENV=production; restart Metro with NODE_ENV=production"
624
- );
625
- }
626
- function hostModuleFileName(specifier) {
627
- return `${specifier.replaceAll("/", "__")}.js`;
628
- }
629
- function resolveHostModules() {
630
- const root = import_path2.default.join(__dirname, "metro-host-modules");
631
- const files = /* @__PURE__ */ new Map();
632
- for (const specifier of hostModuleSpecifiers) {
633
- const filePath = import_path2.default.join(root, hostModuleFileName(specifier));
634
- files.set(specifier, filePath);
635
- }
636
- return { root, files };
637
- }
638
606
  function readCallableMetroExport(moduleValue, label) {
639
607
  const callable = typeof moduleValue === "function" ? moduleValue : typeof moduleValue === "object" && moduleValue !== null ? Reflect.get(moduleValue, "default") : void 0;
640
608
  if (typeof callable !== "function") {
@@ -664,7 +632,7 @@ function createMetroDefaultSerializer(projectRoot) {
664
632
  return code;
665
633
  };
666
634
  }
667
- function prependRNXModulePaths(result, graph, options, projectRoot) {
635
+ function appendRNXModulePaths(result, graph, options, projectRoot) {
668
636
  const dependencies = graph.dependencies;
669
637
  const createModuleId = options.createModuleId;
670
638
  if (!dependencies || !createModuleId) {
@@ -697,44 +665,24 @@ function withRNX(config, options = {}) {
697
665
  cfgProjectRoot,
698
666
  appName
699
667
  );
700
- const cfgResolver = config.resolver;
701
668
  const cfgSerializer = config.serializer;
702
669
  const existingEnhance = cfgServer?.enhanceMiddleware;
703
- const existingResolveRequest = cfgResolver?.resolveRequest;
704
670
  const existingSerializer = cfgSerializer?.customSerializer;
705
671
  let productionConfig = {};
706
672
  if (options.productionBundles) {
707
- const hostModules = resolveHostModules();
708
673
  let defaultSerializer;
709
674
  productionConfig = {
710
- watchFolders: [
711
- ...config.watchFolders || [],
712
- hostModules.root
713
- ],
714
- resolver: {
715
- ...cfgResolver,
716
- resolveRequest: (context, moduleName, platform) => {
717
- if (context.customResolverOptions?.[RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION] === "true") {
718
- assertProductionEnvironment();
719
- const hostModule = hostModules.files.get(moduleName);
720
- if (hostModule) return { type: "sourceFile", filePath: hostModule };
721
- }
722
- return existingResolveRequest ? existingResolveRequest(context, moduleName, platform) : context.resolveRequest(context, moduleName, platform);
723
- }
724
- },
725
675
  serializer: {
726
676
  ...cfgSerializer,
727
677
  customSerializer: async (entryPoint, preModules, graph, serializerOptions) => {
728
678
  const serializer = existingSerializer || (defaultSerializer ||= createMetroDefaultSerializer(cfgProjectRoot));
729
- const productionBundle = isRNXProductionBundle(graph);
730
- if (productionBundle) assertProductionEnvironment();
731
679
  const result = await serializer(
732
680
  entryPoint,
733
681
  preModules,
734
682
  graph,
735
683
  serializerOptions
736
684
  );
737
- return productionBundle ? prependRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot) : result;
685
+ return graph.transformOptions?.dev === false ? appendRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot) : result;
738
686
  }
739
687
  }
740
688
  };
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/react-native-host-modules.ts
4
4
  var REACT_NATIVE_PASSTHROUGH_SPECIFIERS = [
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
package/dist-lib/sdk.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.394 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.396 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rnxsim",
3
- "version": "0.1.394",
3
+ "version": "0.1.396",
4
4
  "description": "Vite and Metro plugins, testing drivers, and SDK exports for rnx.",
5
5
  "author": "Tamagui LLC",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -1,4 +1,4 @@
1
- // rnx metro plugin for opt-in dev shell and production bundle integration.
1
+ // rnx metro plugin for opt-in dev shell and production bundle annotation.
2
2
  // shell assets come from an engine runtime under ~/.rnx/runtimes/, fetched
3
3
  // by `rnx runtime install`. ordinary localhost requests
4
4
  // follow active; a version-owned localhost origin stays on its exact directory
@@ -24,7 +24,6 @@ import {
24
24
  isReplacementModuleRequestUrl,
25
25
  } from './host/replacement-module-handler'
26
26
  import {
27
- RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION,
28
27
  createRNXMetroModulePathsFooter,
29
28
  toRNXProductionBundleUrl,
30
29
  } from './metro-production-bundle'
@@ -39,37 +38,10 @@ import {
39
38
  const prefix = '/__soot'
40
39
  export { toRNXProductionBundleUrl }
41
40
 
42
- const hostModuleSpecifiers = [
43
- 'react',
44
- 'react-dom',
45
- 'react/jsx-runtime',
46
- 'react/jsx-dev-runtime',
47
- 'react-native',
48
- 'react-native-web',
49
- ] as const
50
-
51
- type MetroResolverContext = {
52
- customResolverOptions?: Record<string, unknown>
53
- resolveRequest: MetroResolver
54
- }
55
-
56
- type MetroResolution = {
57
- type: string
58
- filePath?: string
59
- [key: string]: unknown
60
- }
61
-
62
- type MetroResolver = (
63
- context: MetroResolverContext,
64
- moduleName: string,
65
- platform: string | null,
66
- ) => MetroResolution
67
-
68
41
  type MetroSerializerGraph = {
69
42
  dependencies?: ReadonlyMap<unknown, { path: string }>
70
43
  transformOptions?: {
71
44
  dev?: boolean
72
- customTransformOptions?: Record<string, unknown>
73
45
  }
74
46
  }
75
47
 
@@ -92,6 +64,11 @@ export interface RNXMetroOptions {
92
64
  bundleUrl?: string
93
65
  devServer?: boolean
94
66
  open?: RnxDesktopOpenOption
67
+ /**
68
+ * append the `moduleId -> sourcePath` identity footer to every production
69
+ * bundle. resolution is untouched, so the annotated artifact is the same
70
+ * bundle the app ships and rnx can load it directly.
71
+ */
95
72
  productionBundles?: boolean
96
73
  }
97
74
 
@@ -99,11 +76,6 @@ export interface RNXMetroOptions {
99
76
  // shape consumers pass while letting us extend `server.enhanceMiddleware`.
100
77
  type MetroConfigWithServer = {
101
78
  projectRoot?: string
102
- watchFolders?: readonly string[]
103
- resolver?: {
104
- resolveRequest?: MetroResolver
105
- [key: string]: unknown
106
- }
107
79
  serializer?: {
108
80
  customSerializer?: MetroSerializer
109
81
  [key: string]: unknown
@@ -115,38 +87,6 @@ type MetroConfigWithServer = {
115
87
  }
116
88
  }
117
89
 
118
- function isRNXProductionBundle(graph: MetroSerializerGraph): boolean {
119
- return (
120
- graph.transformOptions?.dev === false &&
121
- graph.transformOptions.customTransformOptions?.[
122
- RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION
123
- ] === 'true'
124
- )
125
- }
126
-
127
- function assertProductionEnvironment(): void {
128
- if (process.env.NODE_ENV === 'production') return
129
- throw new Error(
130
- 'rnxsim: production bundle requests require NODE_ENV=production; restart Metro with NODE_ENV=production',
131
- )
132
- }
133
-
134
- function hostModuleFileName(specifier: (typeof hostModuleSpecifiers)[number]): string {
135
- return `${specifier.replaceAll('/', '__')}.js`
136
- }
137
-
138
- function resolveHostModules(): { root: string; files: ReadonlyMap<string, string> } {
139
- const root = path.join(__dirname, 'metro-host-modules')
140
- const files = new Map<string, string>()
141
-
142
- for (const specifier of hostModuleSpecifiers) {
143
- const filePath = path.join(root, hostModuleFileName(specifier))
144
- files.set(specifier, filePath)
145
- }
146
-
147
- return { root, files }
148
- }
149
-
150
90
  function readCallableMetroExport(
151
91
  moduleValue: unknown,
152
92
  label: string,
@@ -190,7 +130,12 @@ function createMetroDefaultSerializer(projectRoot: string): MetroSerializer {
190
130
  }
191
131
  }
192
132
 
193
- function prependRNXModulePaths(
133
+ // the only thing rnx adds to a production bundle. Metro drops the fourth `__d`
134
+ // argument when `dev` is false, so nothing in the artifact names its modules;
135
+ // the engine's `__d` trap needs those names to swap react, react-native, and
136
+ // the native-seam packages for its own. the footer restores exactly that, and
137
+ // is inert everywhere else — on a device it assigns one unused global.
138
+ function appendRNXModulePaths(
194
139
  result: MetroSerializerResult,
195
140
  graph: MetroSerializerGraph,
196
141
  options: MetroSerializerOptions,
@@ -241,42 +186,15 @@ export function withRNX<T extends Record<string, unknown>>(
241
186
  cfgProjectRoot,
242
187
  appName,
243
188
  )
244
- const cfgResolver = (config as MetroConfigWithServer).resolver
245
189
  const cfgSerializer = (config as MetroConfigWithServer).serializer
246
190
  const existingEnhance = cfgServer?.enhanceMiddleware
247
- const existingResolveRequest = cfgResolver?.resolveRequest
248
191
  const existingSerializer = cfgSerializer?.customSerializer
249
192
  let productionConfig: Partial<MetroConfigWithServer> = {}
250
193
 
251
194
  if (options.productionBundles) {
252
- const hostModules = resolveHostModules()
253
195
  let defaultSerializer: MetroSerializer | undefined
254
196
 
255
197
  productionConfig = {
256
- watchFolders: [
257
- ...((config as MetroConfigWithServer).watchFolders || []),
258
- hostModules.root,
259
- ],
260
- resolver: {
261
- ...cfgResolver,
262
- resolveRequest: (
263
- context: MetroResolverContext,
264
- moduleName: string,
265
- platform: string | null,
266
- ) => {
267
- if (
268
- context.customResolverOptions?.[RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION] ===
269
- 'true'
270
- ) {
271
- assertProductionEnvironment()
272
- const hostModule = hostModules.files.get(moduleName)
273
- if (hostModule) return { type: 'sourceFile', filePath: hostModule }
274
- }
275
- return existingResolveRequest
276
- ? existingResolveRequest(context, moduleName, platform)
277
- : context.resolveRequest(context, moduleName, platform)
278
- },
279
- },
280
198
  serializer: {
281
199
  ...cfgSerializer,
282
200
  customSerializer: async (
@@ -288,16 +206,17 @@ export function withRNX<T extends Record<string, unknown>>(
288
206
  const serializer =
289
207
  existingSerializer ||
290
208
  (defaultSerializer ||= createMetroDefaultSerializer(cfgProjectRoot))
291
- const productionBundle = isRNXProductionBundle(graph)
292
- if (productionBundle) assertProductionEnvironment()
293
209
  const result = await serializer(
294
210
  entryPoint,
295
211
  preModules,
296
212
  graph,
297
213
  serializerOptions,
298
214
  )
299
- return productionBundle
300
- ? prependRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot)
215
+ // every production build gets the footer, so the artifact the app
216
+ // already ships is the one rnx loads. a development build keeps
217
+ // Metro's fourth `__d` argument and needs nothing.
218
+ return graph.transformOptions?.dev === false
219
+ ? appendRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot)
301
220
  : result
302
221
  },
303
222
  },
@@ -1,4 +1,3 @@
1
- export const RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION = 'rnxsim'
2
1
  const RNXSIM_METRO_MODULE_PATHS_PREFIX = 'globalThis.__sootsimModulePaths='
3
2
 
4
3
  export type RNXMetroModulePathMap = Record<string, string>
@@ -7,14 +6,16 @@ export interface RNXMetroModuleIdentity {
7
6
  modulePaths: RNXMetroModulePathMap
8
7
  }
9
8
 
9
+ // the production bundle rnx loads is the app's ORDINARY production bundle.
10
+ // nothing about resolution changes, so these are plain Metro production
11
+ // options and the artifact is byte-identical to what the app ships apart
12
+ // from the identity footer the plugin's serializer appends.
10
13
  export function toRNXProductionBundleUrl(bundleUrl: string): string {
11
14
  const relative = bundleUrl.startsWith('/')
12
15
  const url = new URL(bundleUrl, 'http://rnxsim.local')
13
16
  url.searchParams.set('dev', 'false')
14
17
  url.searchParams.set('hot', 'false')
15
18
  url.searchParams.set('minify', 'true')
16
- url.searchParams.set(`resolver.${RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION}`, 'true')
17
- url.searchParams.set(`transform.${RNXSIM_METRO_PRODUCTION_BUNDLE_OPTION}`, 'true')
18
19
  return relative ? `${url.pathname}${url.search}${url.hash}` : url.toString()
19
20
  }
20
21
 
@@ -1,6 +0,0 @@
1
- const name = 'react-dom'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react-native-web'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react-native'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react/jsx-dev-runtime'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react/jsx-runtime'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react-dom'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react-native-web'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react-native'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react/jsx-dev-runtime'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]
@@ -1,6 +0,0 @@
1
- const name = 'react/jsx-runtime'
2
- const host = globalThis.__contrastHostModules
3
- if (!host || !(name in host)) {
4
- throw new Error(`rnxsim: runtime did not publish __contrastHostModules[${name}]`)
5
- }
6
- module.exports = host[name]