rnxsim 0.1.402 → 0.1.404

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 (59) hide show
  1. package/README.md +31 -9
  2. package/cli/commands/box.ts +10 -3
  3. package/cli/outbound-endpoints.ts +2 -2
  4. package/dist-lib/agent-daemon-client.cjs +1 -1
  5. package/dist-lib/agent-events.cjs +1 -1
  6. package/dist-lib/agent-identity.cjs +1 -1
  7. package/dist-lib/agent-sessions.cjs +1 -1
  8. package/dist-lib/attached-projects.cjs +1 -1
  9. package/dist-lib/auth/shared-session.cjs +1 -1
  10. package/dist-lib/backend-origin.cjs +1 -1
  11. package/dist-lib/beta.cjs +1 -1
  12. package/dist-lib/beta.mjs +1 -1
  13. package/dist-lib/bridge-constants.cjs +1 -1
  14. package/dist-lib/bridge-contract-input.cjs +1 -1
  15. package/dist-lib/bridge-contract-input.mjs +1 -1
  16. package/dist-lib/bridge-contract.cjs +1 -1
  17. package/dist-lib/bridge-contract.mjs +1 -1
  18. package/dist-lib/capture-contract.cjs +5 -2
  19. package/dist-lib/capture-contract.mjs +5 -2
  20. package/dist-lib/cli-constants.cjs +1 -1
  21. package/dist-lib/cloud-contract.cjs +3 -2
  22. package/dist-lib/cloud-contract.mjs +3 -2
  23. package/dist-lib/config.cjs +1 -1
  24. package/dist-lib/detox/index.cjs +1 -1
  25. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  26. package/dist-lib/home-paths.cjs +1 -1
  27. package/dist-lib/host/bridge-host.cjs +1 -1
  28. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  29. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  30. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  31. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  32. package/dist-lib/host/websocket-proxy.cjs +1 -1
  33. package/dist-lib/index.cjs +63 -14
  34. package/dist-lib/jump-to-source-babel.cjs +1 -1
  35. package/dist-lib/menu.cjs +1 -1
  36. package/dist-lib/menu.mjs +1 -1
  37. package/dist-lib/metro-fingerprint-registry.cjs +186 -0
  38. package/dist-lib/metro-fingerprint-registry.mjs +156 -0
  39. package/dist-lib/metro-production-bundle.cjs +131 -17
  40. package/dist-lib/metro-production-bundle.mjs +125 -16
  41. package/dist-lib/metro.cjs +67 -12
  42. package/dist-lib/profiles.cjs +1 -1
  43. package/dist-lib/public-brand.cjs +1 -1
  44. package/dist-lib/react-native-host-modules.cjs +1 -1
  45. package/dist-lib/react-native-host-modules.mjs +1 -1
  46. package/dist-lib/render-mode.cjs +1 -1
  47. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  48. package/dist-lib/sdk.cjs +1 -1
  49. package/dist-lib/sdk.mjs +1 -1
  50. package/dist-lib/skills.cjs +58 -25
  51. package/dist-lib/vite.cjs +6 -1
  52. package/package.json +8 -1
  53. package/src/bridge-contract.ts +20 -0
  54. package/src/capture-contract.ts +8 -0
  55. package/src/cloud-contract.ts +1 -0
  56. package/src/metro-fingerprint-registry.ts +302 -0
  57. package/src/metro-plugin.ts +73 -24
  58. package/src/metro-production-bundle.ts +213 -19
  59. package/src/runtime-assets.ts +5 -0
@@ -1,7 +1,8 @@
1
- /*! rnx v0.1.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/metro-production-bundle.ts
4
4
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
5
+ var RNX_METRO_MODULE_IDENTITY_VERSION = 2;
5
6
  function toRNXProductionBundleUrl(bundleUrl) {
6
7
  const relative = bundleUrl.startsWith("/");
7
8
  const url = new URL(bundleUrl, "http://rnxsim.local");
@@ -10,28 +11,105 @@ function toRNXProductionBundleUrl(bundleUrl) {
10
11
  url.searchParams.set("minify", "true");
11
12
  return relative ? `${url.pathname}${url.search}${url.hash}` : url.toString();
12
13
  }
13
- function createRNXMetroModulePathsFooter(modulePaths) {
14
- const payload = JSON.stringify(modulePaths).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
14
+ function toRNXDevelopmentBundleUrl(bundleUrl) {
15
+ const relative = bundleUrl.startsWith("/");
16
+ const url = new URL(bundleUrl, "http://rnxsim.local");
17
+ url.searchParams.set("dev", "true");
18
+ url.searchParams.set("hot", "false");
19
+ url.searchParams.set("minify", "false");
20
+ return relative ? `${url.pathname}${url.search}${url.hash}` : url.toString();
21
+ }
22
+ var RNXSIM_METRO_SOURCE_MAP_COMMENT = "//# sourceMappingURL=";
23
+ function detachRNXMetroSourceMapUrl(bundleText) {
24
+ const trimmedEnd = bundleText.replace(/\s+$/, "");
25
+ const commentStart = trimmedEnd.lastIndexOf(`
26
+ ${RNXSIM_METRO_SOURCE_MAP_COMMENT}`);
27
+ if (commentStart < 0) return { source: bundleText, sourceMappingUrl: null };
28
+ const url = trimmedEnd.slice(commentStart + 1 + RNXSIM_METRO_SOURCE_MAP_COMMENT.length);
29
+ if (url.includes("\n")) return { source: bundleText, sourceMappingUrl: null };
30
+ return { source: trimmedEnd.slice(0, commentStart), sourceMappingUrl: url };
31
+ }
32
+ function createRNXMetroModuleIdentityFooter(identity) {
33
+ const payload = JSON.stringify(identity).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
15
34
  return `
16
35
  ${RNXSIM_METRO_MODULE_PATHS_PREFIX}${payload};`;
17
36
  }
37
+ function appendRNXMetroModuleIdentityFooter(bundleText, identity) {
38
+ const footer = createRNXMetroModuleIdentityFooter(identity);
39
+ const detached = detachRNXMetroSourceMapUrl(bundleText);
40
+ return detached.sourceMappingUrl === null ? bundleText + footer : `${detached.source}${footer}
41
+ ${RNXSIM_METRO_SOURCE_MAP_COMMENT}${detached.sourceMappingUrl}`;
42
+ }
18
43
  function readRNXMetroModuleIdentity(bundleText) {
44
+ const detached = detachRNXMetroSourceMapUrl(bundleText);
45
+ const withoutMap = detached.source;
19
46
  const footerPrefix = `
20
47
  ${RNXSIM_METRO_MODULE_PATHS_PREFIX}`;
21
- const footerStart = bundleText.lastIndexOf(footerPrefix);
22
- if (footerStart < 0 || !bundleText.endsWith(";")) return null;
23
- const parsed = JSON.parse(
24
- bundleText.slice(footerStart + footerPrefix.length, -1)
25
- );
48
+ const footerStart = withoutMap.lastIndexOf(footerPrefix);
49
+ if (footerStart < 0) return null;
50
+ if (!withoutMap.endsWith(";")) {
51
+ throw new Error("Metro module identity footer is truncated");
52
+ }
53
+ let parsed;
54
+ try {
55
+ parsed = JSON.parse(withoutMap.slice(footerStart + footerPrefix.length, -1));
56
+ } catch {
57
+ throw new Error("Metro module identity footer is not valid JSON");
58
+ }
26
59
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
27
- return null;
60
+ throw new Error("Metro module identity footer is malformed");
61
+ }
62
+ const version = Reflect.get(parsed, "version");
63
+ if (version === void 0) return null;
64
+ const identitySource = Reflect.get(parsed, "identitySource");
65
+ const parsedModulePaths = Reflect.get(parsed, "modulePaths");
66
+ const parsedLogicalSpecifiers = Reflect.get(parsed, "logicalSpecifiers");
67
+ if (version !== RNX_METRO_MODULE_IDENTITY_VERSION || identitySource !== "rnx-plugin" && identitySource !== "contrast-bundler" && identitySource !== "metro-source-map" || typeof parsedModulePaths !== "object" || parsedModulePaths === null || Array.isArray(parsedModulePaths) || typeof parsedLogicalSpecifiers !== "object" || parsedLogicalSpecifiers === null || Array.isArray(parsedLogicalSpecifiers)) {
68
+ throw new Error("Metro module identity footer is malformed");
28
69
  }
29
70
  const modulePaths = {};
30
- for (const [moduleId, modulePath] of Object.entries(parsed)) {
31
- if (typeof modulePath !== "string") return null;
71
+ for (const [moduleId, modulePath] of Object.entries(parsedModulePaths)) {
72
+ if (typeof modulePath !== "string") {
73
+ throw new Error(`Metro module identity has an invalid path for ${moduleId}`);
74
+ }
32
75
  modulePaths[moduleId] = modulePath;
33
76
  }
34
- return { source: bundleText.slice(0, footerStart), modulePaths };
77
+ const logicalSpecifiers = {};
78
+ for (const [moduleId, specifiers] of Object.entries(parsedLogicalSpecifiers)) {
79
+ if (!Array.isArray(specifiers) || specifiers.length === 0 || !specifiers.every(
80
+ (specifier) => typeof specifier === "string" && specifier.length > 0
81
+ )) {
82
+ throw new Error(`Metro module identity has invalid specifiers for ${moduleId}`);
83
+ }
84
+ const unique = [...new Set(specifiers)].sort(
85
+ (left, right) => left.localeCompare(right)
86
+ );
87
+ if (unique.length !== specifiers.length) {
88
+ throw new Error(`Metro module identity repeats a specifier for ${moduleId}`);
89
+ }
90
+ logicalSpecifiers[moduleId] = unique;
91
+ }
92
+ return {
93
+ source: withoutMap.slice(0, footerStart),
94
+ version,
95
+ identitySource,
96
+ modulePaths,
97
+ logicalSpecifiers,
98
+ sourceMappingUrl: detached.sourceMappingUrl
99
+ };
100
+ }
101
+ function readStringLiteralStart(source, start, end) {
102
+ const quote = source[end];
103
+ if (quote !== '"' && quote !== "'") return -1;
104
+ for (let index = end - 1; index > start; index--) {
105
+ if (source[index] !== quote) continue;
106
+ let backslashes = 0;
107
+ while (index - 1 - backslashes > start && source[index - 1 - backslashes] === "\\") {
108
+ backslashes++;
109
+ }
110
+ if (backslashes % 2 === 0) return index;
111
+ }
112
+ return -1;
35
113
  }
36
114
  function readDefineTail(source, start, end) {
37
115
  let cursor = end;
@@ -41,6 +119,19 @@ function readDefineTail(source, start, end) {
41
119
  if (source[cursor] !== ")") return null;
42
120
  cursor--;
43
121
  while (cursor > start && /\s/.test(source[cursor])) cursor--;
122
+ let verboseNameStart;
123
+ let verboseNameEnd;
124
+ if (source[cursor] === '"' || source[cursor] === "'") {
125
+ const literalStart = readStringLiteralStart(source, start, cursor);
126
+ if (literalStart < 0) return null;
127
+ verboseNameStart = literalStart;
128
+ verboseNameEnd = cursor + 1;
129
+ cursor = literalStart - 1;
130
+ while (cursor > start && /\s/.test(source[cursor])) cursor--;
131
+ if (source[cursor] !== ",") return null;
132
+ cursor--;
133
+ while (cursor > start && /\s/.test(source[cursor])) cursor--;
134
+ }
44
135
  if (source[cursor] !== "]") return null;
45
136
  const dependenciesEnd = cursor + 1;
46
137
  let depth = 1;
@@ -58,7 +149,7 @@ function readDefineTail(source, start, end) {
58
149
  while (idEnd > start && /\s/.test(source[idEnd])) idEnd--;
59
150
  if (source[idEnd] !== ",") return null;
60
151
  let idStart = idEnd;
61
- while (idStart > start && /[0-9a-fA-FxX.+\-]/.test(source[idStart - 1])) idStart--;
152
+ while (idStart > start && /[0-9a-fA-FxX.+-]/.test(source[idStart - 1])) idStart--;
62
153
  const literal = source.slice(idStart, idEnd);
63
154
  if (!/^-?(?:0[xXbBoO][0-9a-fA-F]+|\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)$/.test(literal)) {
64
155
  return null;
@@ -72,7 +163,9 @@ function readDefineTail(source, start, end) {
72
163
  moduleId,
73
164
  factoryEnd,
74
165
  dependenciesStart,
75
- dependenciesEnd
166
+ dependenciesEnd,
167
+ verboseNameStart,
168
+ verboseNameEnd
76
169
  };
77
170
  }
78
171
  function readRNXMetroBundleLayout(source) {
@@ -112,7 +205,8 @@ function readRNXMetroBundleLayout(source) {
112
205
  lineIndex,
113
206
  endLineIndex,
114
207
  factory: { start: start + "__d(".length, end: tail.factoryEnd },
115
- dependencies: { start: tail.dependenciesStart, end: tail.dependenciesEnd }
208
+ dependencies: { start: tail.dependenciesStart, end: tail.dependenciesEnd },
209
+ ...tail.verboseNameStart !== void 0 && tail.verboseNameEnd !== void 0 ? { verboseName: { start: tail.verboseNameStart, end: tail.verboseNameEnd } } : {}
116
210
  });
117
211
  }
118
212
  return {
@@ -158,10 +252,25 @@ function validateRNXMetroModulePaths(source, modulePaths) {
158
252
  }
159
253
  }
160
254
  }
255
+ function validateRNXMetroModuleIdentity(identity) {
256
+ validateRNXMetroModulePaths(identity.source, identity.modulePaths);
257
+ for (const moduleId of Object.keys(identity.logicalSpecifiers)) {
258
+ if (!Object.prototype.hasOwnProperty.call(identity.modulePaths, moduleId)) {
259
+ throw new Error(
260
+ `Metro module identity has logical specifiers for unknown module ${moduleId}`
261
+ );
262
+ }
263
+ }
264
+ }
161
265
  export {
162
- createRNXMetroModulePathsFooter,
266
+ RNX_METRO_MODULE_IDENTITY_VERSION,
267
+ appendRNXMetroModuleIdentityFooter,
268
+ createRNXMetroModuleIdentityFooter,
269
+ detachRNXMetroSourceMapUrl,
163
270
  readRNXMetroBundleLayout,
164
271
  readRNXMetroModuleIdentity,
272
+ toRNXDevelopmentBundleUrl,
165
273
  toRNXProductionBundleUrl,
274
+ validateRNXMetroModuleIdentity,
166
275
  validateRNXMetroModulePaths
167
276
  };
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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;
@@ -33,6 +33,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
33
33
  var metro_plugin_exports = {};
34
34
  __export(metro_plugin_exports, {
35
35
  default: () => metro_plugin_default,
36
+ toRNXDevelopmentBundleUrl: () => toRNXDevelopmentBundleUrl,
36
37
  toRNXProductionBundleUrl: () => toRNXProductionBundleUrl,
37
38
  withRNX: () => withRNX
38
39
  });
@@ -411,6 +412,7 @@ exports.jsxDEV = exports.jsx`,
411
412
 
412
413
  // src/metro-production-bundle.ts
413
414
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
415
+ var RNX_METRO_MODULE_IDENTITY_VERSION = 2;
414
416
  function toRNXProductionBundleUrl(bundleUrl) {
415
417
  const relative = bundleUrl.startsWith("/");
416
418
  const url = new URL(bundleUrl, "http://rnxsim.local");
@@ -419,11 +421,35 @@ function toRNXProductionBundleUrl(bundleUrl) {
419
421
  url.searchParams.set("minify", "true");
420
422
  return relative ? `${url.pathname}${url.search}${url.hash}` : url.toString();
421
423
  }
422
- function createRNXMetroModulePathsFooter(modulePaths) {
423
- const payload = JSON.stringify(modulePaths).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
424
+ function toRNXDevelopmentBundleUrl(bundleUrl) {
425
+ const relative = bundleUrl.startsWith("/");
426
+ const url = new URL(bundleUrl, "http://rnxsim.local");
427
+ url.searchParams.set("dev", "true");
428
+ url.searchParams.set("hot", "false");
429
+ url.searchParams.set("minify", "false");
430
+ return relative ? `${url.pathname}${url.search}${url.hash}` : url.toString();
431
+ }
432
+ var RNXSIM_METRO_SOURCE_MAP_COMMENT = "//# sourceMappingURL=";
433
+ function detachRNXMetroSourceMapUrl(bundleText) {
434
+ const trimmedEnd = bundleText.replace(/\s+$/, "");
435
+ const commentStart = trimmedEnd.lastIndexOf(`
436
+ ${RNXSIM_METRO_SOURCE_MAP_COMMENT}`);
437
+ if (commentStart < 0) return { source: bundleText, sourceMappingUrl: null };
438
+ const url = trimmedEnd.slice(commentStart + 1 + RNXSIM_METRO_SOURCE_MAP_COMMENT.length);
439
+ if (url.includes("\n")) return { source: bundleText, sourceMappingUrl: null };
440
+ return { source: trimmedEnd.slice(0, commentStart), sourceMappingUrl: url };
441
+ }
442
+ function createRNXMetroModuleIdentityFooter(identity) {
443
+ const payload = JSON.stringify(identity).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
424
444
  return `
425
445
  ${RNXSIM_METRO_MODULE_PATHS_PREFIX}${payload};`;
426
446
  }
447
+ function appendRNXMetroModuleIdentityFooter(bundleText, identity) {
448
+ const footer = createRNXMetroModuleIdentityFooter(identity);
449
+ const detached = detachRNXMetroSourceMapUrl(bundleText);
450
+ return detached.sourceMappingUrl === null ? bundleText + footer : `${detached.source}${footer}
451
+ ${RNXSIM_METRO_SOURCE_MAP_COMMENT}${detached.sourceMappingUrl}`;
452
+ }
427
453
 
428
454
  // src/runtime-assets.ts
429
455
  var import_fs = __toESM(require("fs"), 1);
@@ -591,6 +617,11 @@ function serveRuntimeFile(req, res, fullPath) {
591
617
  const stat = import_fs.default.statSync(fullPath);
592
618
  const lastModified = stat.mtime.toUTCString();
593
619
  res.setHeader("content-type", MIME_TYPES[ext] || "application/octet-stream");
620
+ if (/^canvaskit-graphite-pipelines-[0-9a-f]{8}\.bin$/.test(import_path.default.basename(fullPath))) {
621
+ res.setHeader("cache-control", "public, max-age=31536000, immutable");
622
+ import_fs.default.createReadStream(fullPath).pipe(res);
623
+ return;
624
+ }
594
625
  res.setHeader("cache-control", "no-cache");
595
626
  res.setHeader("last-modified", lastModified);
596
627
  if (req?.headers?.["if-modified-since"] === lastModified) {
@@ -636,22 +667,44 @@ function appendRNXModulePaths(result, graph, options, projectRoot) {
636
667
  const dependencies = graph.dependencies;
637
668
  const createModuleId = options.createModuleId;
638
669
  if (!dependencies || !createModuleId) {
639
- throw new Error(
640
- "rnxsim: Metro did not provide the production module graph and createModuleId"
641
- );
670
+ throw new Error("rnxsim: Metro did not provide the module graph and createModuleId");
642
671
  }
643
672
  const modulePaths = {};
644
673
  for (const module2 of dependencies.values()) {
645
674
  modulePaths[String(createModuleId(module2.path))] = import_path2.default.relative(projectRoot, module2.path).replaceAll(import_path2.default.sep, "/");
646
675
  }
647
676
  if (Object.keys(modulePaths).length !== dependencies.size) {
648
- throw new Error("rnxsim: production module IDs were not unique");
677
+ throw new Error("rnxsim: bundle module IDs were not unique");
678
+ }
679
+ const specifiersByModuleId = /* @__PURE__ */ new Map();
680
+ for (const module2 of dependencies.values()) {
681
+ for (const [dependencyKey, dependency] of module2.dependencies ?? []) {
682
+ const specifier = dependency.data?.name ?? dependencyKey;
683
+ if (specifier.length === 0 || specifier.startsWith(".") || specifier.startsWith("/") || typeof dependency.absolutePath !== "string") {
684
+ continue;
685
+ }
686
+ const moduleId = String(createModuleId(dependency.absolutePath));
687
+ if (!Object.prototype.hasOwnProperty.call(modulePaths, moduleId)) continue;
688
+ const found = specifiersByModuleId.get(moduleId);
689
+ if (found) found.add(specifier);
690
+ else specifiersByModuleId.set(moduleId, /* @__PURE__ */ new Set([specifier]));
691
+ }
649
692
  }
650
- const footer = createRNXMetroModulePathsFooter(modulePaths);
651
- return typeof result === "string" ? result + footer : { ...result, code: result.code + footer };
693
+ const logicalSpecifiers = Object.fromEntries(
694
+ [...specifiersByModuleId].sort(([left], [right]) => Number(left) - Number(right)).map(([moduleId, specifiers]) => [moduleId, [...specifiers].sort()])
695
+ );
696
+ const identity = {
697
+ version: RNX_METRO_MODULE_IDENTITY_VERSION,
698
+ identitySource: "rnx-plugin",
699
+ modulePaths,
700
+ logicalSpecifiers
701
+ };
702
+ return typeof result === "string" ? appendRNXMetroModuleIdentityFooter(result, identity) : { ...result, code: appendRNXMetroModuleIdentityFooter(result.code, identity) };
652
703
  }
653
704
  function withRNX(config, options = {}) {
654
- if (!options.devServer && !options.open && !options.productionBundles) return config;
705
+ if (!options.devServer && !options.open && !options.productionBundles && !options.developmentBundles) {
706
+ return config;
707
+ }
655
708
  const cfgProjectRoot = config.projectRoot || process.cwd();
656
709
  const appName = resolveRnxDesktopAppName(options.open, cfgProjectRoot);
657
710
  const configuredBundleUrl = options.bundleUrl || "/index.bundle?platform=ios&dev=true&hot=true&minify=false";
@@ -669,7 +722,7 @@ function withRNX(config, options = {}) {
669
722
  const existingEnhance = cfgServer?.enhanceMiddleware;
670
723
  const existingSerializer = cfgSerializer?.customSerializer;
671
724
  let productionConfig = {};
672
- if (options.productionBundles) {
725
+ if (options.productionBundles || options.developmentBundles) {
673
726
  let defaultSerializer;
674
727
  productionConfig = {
675
728
  serializer: {
@@ -682,7 +735,8 @@ function withRNX(config, options = {}) {
682
735
  graph,
683
736
  serializerOptions
684
737
  );
685
- return graph.transformOptions?.dev === false ? appendRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot) : result;
738
+ const dev = serializerOptions.dev;
739
+ return dev === false && options.productionBundles === true || dev === true && options.developmentBundles === true ? appendRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot) : result;
686
740
  }
687
741
  }
688
742
  };
@@ -809,6 +863,7 @@ function resolveMetroPort(server) {
809
863
  var metro_plugin_default = withRNX;
810
864
  // Annotate the CommonJS export names for ESM import in node:
811
865
  0 && (module.exports = {
866
+ toRNXDevelopmentBundleUrl,
812
867
  toRNXProductionBundleUrl,
813
868
  withRNX
814
869
  });
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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;
@@ -1347,23 +1347,35 @@ var init_supported_native_packages = __esm({
1347
1347
  "expo-apple-authentication",
1348
1348
  // preset
1349
1349
  "expo-application",
1350
- // coverage
1350
+ // visual-proof+coverage
1351
1351
  "expo-asset",
1352
1352
  // preset+coverage
1353
1353
  "expo-audio",
1354
1354
  // coverage
1355
1355
  "expo-av",
1356
1356
  // coverage
1357
+ "expo-background-fetch",
1358
+ // visual-proof
1359
+ "expo-background-task",
1360
+ // visual-proof
1357
1361
  "expo-battery",
1358
- // coverage
1362
+ // visual-proof+coverage
1359
1363
  "expo-blur",
1360
1364
  // preset+coverage
1365
+ "expo-brightness",
1366
+ // visual-proof
1367
+ "expo-calendar",
1368
+ // visual-proof
1361
1369
  "expo-camera",
1362
1370
  // coverage
1371
+ "expo-cellular",
1372
+ // visual-proof
1363
1373
  "expo-clipboard",
1364
1374
  // preset+coverage
1365
1375
  "expo-constants",
1366
- // preset+coverage
1376
+ // preset+visual-proof+coverage
1377
+ "expo-contacts",
1378
+ // visual-proof
1367
1379
  "expo-crypto",
1368
1380
  // preset+coverage
1369
1381
  "expo-dev-client",
@@ -1385,23 +1397,27 @@ var init_supported_native_packages = __esm({
1385
1397
  "expo-ignore-battery-optimizations",
1386
1398
  // coverage
1387
1399
  "expo-image",
1388
- // preset+coverage
1400
+ // preset+visual-proof+coverage
1389
1401
  "expo-image-manipulator",
1390
1402
  // coverage
1391
1403
  "expo-image-picker",
1392
1404
  // preset+coverage
1393
1405
  "expo-insights",
1394
1406
  // coverage
1407
+ "expo-intent-launcher",
1408
+ // visual-proof
1395
1409
  "expo-keep-awake",
1396
1410
  // coverage
1397
1411
  "expo-linear-gradient",
1398
- // preset+coverage
1412
+ // preset+visual-proof+coverage
1399
1413
  "expo-linking",
1400
1414
  // preset+coverage
1401
1415
  "expo-local-authentication",
1402
1416
  // coverage
1403
1417
  "expo-localization",
1404
1418
  // coverage
1419
+ "expo-mail-composer",
1420
+ // visual-proof
1405
1421
  "expo-media-library",
1406
1422
  // coverage
1407
1423
  "expo-mesh-gradient",
@@ -1409,35 +1425,51 @@ var init_supported_native_packages = __esm({
1409
1425
  "expo-modules-core",
1410
1426
  // preset
1411
1427
  "expo-network",
1412
- // preset+coverage
1428
+ // preset+visual-proof+coverage
1413
1429
  "expo-notifications",
1414
1430
  // preset+coverage
1431
+ "expo-print",
1432
+ // visual-proof
1433
+ "expo-screen-capture",
1434
+ // visual-proof
1415
1435
  "expo-screen-corner-radius",
1416
1436
  // coverage
1417
1437
  "expo-screen-orientation",
1418
- // coverage
1438
+ // visual-proof+coverage
1419
1439
  "expo-secure-store",
1420
- // coverage
1440
+ // visual-proof+coverage
1441
+ "expo-sensors",
1442
+ // visual-proof
1443
+ "expo-sharing",
1444
+ // visual-proof
1445
+ "expo-sms",
1446
+ // visual-proof
1447
+ "expo-speech",
1448
+ // visual-proof
1421
1449
  "expo-speech-recognition",
1422
1450
  // preset
1423
1451
  "expo-splash-screen",
1424
- // coverage
1452
+ // visual-proof+coverage
1425
1453
  "expo-sqlite",
1426
1454
  // preset+coverage
1427
1455
  "expo-store-review",
1428
- // coverage
1456
+ // visual-proof+coverage
1429
1457
  "expo-symbols",
1430
1458
  // coverage
1431
1459
  "expo-system-ui",
1432
1460
  // coverage
1433
1461
  "expo-task-manager",
1434
- // coverage
1462
+ // visual-proof+coverage
1435
1463
  "expo-testflight",
1436
1464
  // coverage
1437
1465
  "expo-tracking-transparency",
1438
- // coverage
1466
+ // visual-proof+coverage
1439
1467
  "expo-updates",
1440
1468
  // preset+coverage
1469
+ "expo-video",
1470
+ // visual-proof
1471
+ "expo-video-thumbnails",
1472
+ // visual-proof
1441
1473
  "expo-web-browser",
1442
1474
  // preset
1443
1475
  "expo-winter-fetch",
@@ -1461,7 +1493,7 @@ var init_supported_native_packages = __esm({
1461
1493
  "posthog-react-native-session-replay",
1462
1494
  // preset+coverage
1463
1495
  "react-native",
1464
- // preset+coverage
1496
+ // preset+visual-proof+coverage
1465
1497
  "react-native-actions-shortcuts",
1466
1498
  // coverage
1467
1499
  "react-native-adjust",
@@ -1485,7 +1517,7 @@ var init_supported_native_packages = __esm({
1485
1517
  "react-native-bootsplash",
1486
1518
  // preset+coverage
1487
1519
  "react-native-bottom-tabs",
1488
- // preset
1520
+ // preset+visual-proof
1489
1521
  "react-native-branch",
1490
1522
  // coverage
1491
1523
  "react-native-config",
@@ -1507,7 +1539,7 @@ var init_supported_native_packages = __esm({
1507
1539
  "react-native-fs",
1508
1540
  // coverage
1509
1541
  "react-native-gesture-handler",
1510
- // preset+coverage
1542
+ // preset+visual-proof+coverage
1511
1543
  "react-native-get-device-locale",
1512
1544
  // coverage
1513
1545
  "react-native-get-location",
@@ -1535,7 +1567,7 @@ var init_supported_native_packages = __esm({
1535
1567
  "react-native-key-command",
1536
1568
  // coverage
1537
1569
  "react-native-keyboard-controller",
1538
- // preset
1570
+ // preset+visual-proof
1539
1571
  "react-native-keychain",
1540
1572
  // coverage
1541
1573
  "react-native-keys",
@@ -1565,7 +1597,7 @@ var init_supported_native_packages = __esm({
1565
1597
  "react-native-notification-badge",
1566
1598
  // coverage
1567
1599
  "react-native-pager-view",
1568
- // preset
1600
+ // preset+visual-proof
1569
1601
  "react-native-pdf",
1570
1602
  // coverage
1571
1603
  "react-native-permissions",
@@ -1585,7 +1617,7 @@ var init_supported_native_packages = __esm({
1585
1617
  "react-native-randombytes",
1586
1618
  // coverage
1587
1619
  "react-native-reanimated",
1588
- // preset+coverage
1620
+ // preset+visual-proof+coverage
1589
1621
  "react-native-restart",
1590
1622
  // coverage
1591
1623
  "react-native-restart-newarch",
@@ -1593,11 +1625,11 @@ var init_supported_native_packages = __esm({
1593
1625
  "react-native-rsa-signer",
1594
1626
  // coverage
1595
1627
  "react-native-safe-area-context",
1596
- // preset+coverage
1628
+ // preset+visual-proof+coverage
1597
1629
  "react-native-screen-corner-radius",
1598
1630
  // coverage
1599
1631
  "react-native-screens",
1600
- // preset+coverage
1632
+ // preset+visual-proof+coverage
1601
1633
  "react-native-securerandom",
1602
1634
  // coverage
1603
1635
  "react-native-settings",
@@ -1613,7 +1645,7 @@ var init_supported_native_packages = __esm({
1613
1645
  "react-native-splash-screen",
1614
1646
  // coverage
1615
1647
  "react-native-svg",
1616
- // preset
1648
+ // preset+visual-proof
1617
1649
  "react-native-system-bars",
1618
1650
  // coverage
1619
1651
  "react-native-teleport",
@@ -1627,7 +1659,7 @@ var init_supported_native_packages = __esm({
1627
1659
  "react-native-turbo-haptics",
1628
1660
  // coverage
1629
1661
  "react-native-uitextview",
1630
- // coverage
1662
+ // visual-proof+coverage
1631
1663
  "react-native-ulid-jsi",
1632
1664
  // coverage
1633
1665
  "react-native-ux-cam",
@@ -1647,7 +1679,7 @@ var init_supported_native_packages = __esm({
1647
1679
  "react-native-webp-format",
1648
1680
  // coverage
1649
1681
  "react-native-webview",
1650
- // preset
1682
+ // preset+visual-proof
1651
1683
  "react-native-worklets",
1652
1684
  // preset+coverage
1653
1685
  "react-native-xxhash",
@@ -21421,7 +21453,8 @@ var init_cloud_contract = __esm({
21421
21453
  "tree",
21422
21454
  "tap",
21423
21455
  "longPress",
21424
- "memory"
21456
+ "memory",
21457
+ "diagnostics"
21425
21458
  ]);
21426
21459
  RNX_CLOUD_COMMAND_TYPE_SET = new Set(RNX_CLOUD_COMMAND_TYPES);
21427
21460
  }
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.402 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.404 | (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;
@@ -526,6 +526,11 @@ function serveRuntimeFile(req, res, fullPath) {
526
526
  const stat = import_fs.default.statSync(fullPath);
527
527
  const lastModified = stat.mtime.toUTCString();
528
528
  res.setHeader("content-type", MIME_TYPES[ext] || "application/octet-stream");
529
+ if (/^canvaskit-graphite-pipelines-[0-9a-f]{8}\.bin$/.test(import_path.default.basename(fullPath))) {
530
+ res.setHeader("cache-control", "public, max-age=31536000, immutable");
531
+ import_fs.default.createReadStream(fullPath).pipe(res);
532
+ return;
533
+ }
529
534
  res.setHeader("cache-control", "no-cache");
530
535
  res.setHeader("last-modified", lastModified);
531
536
  if (req?.headers?.["if-modified-since"] === lastModified) {