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
package/README.md CHANGED
@@ -384,10 +384,16 @@ Electron is an opt-in desktop upgrade. The notarized CLI install did not produce
384
384
  a Gatekeeper prompt on a clean profile. A Mac that previously ran an unsigned
385
385
  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
- Metro wrapper also has two independent non-window opt-ins.
387
+ Metro wrapper also has three independent non-window opt-ins.
388
388
  `devServer` serves the RNX shell from the Metro process. `productionBundles`
389
- appends Metro's exact module-ID-to-source-path map to every production bundle,
390
- as a trailing `globalThis.__sootsimModulePaths = { ... }` assignment.
389
+ appends Metro's exact module identity to every production bundle, as a trailing
390
+ `globalThis.__sootsimModulePaths = { ... }` assignment. The versioned value
391
+ contains the module-ID-to-source-path map and the incoming bare logical
392
+ specifiers Metro resolved for each module. Logical specifiers keep identity
393
+ exact when a custom resolver maps a host package such as `react` outside
394
+ `node_modules`. `developmentBundles` appends the same identity to every
395
+ ordinary development bundle while keeping `__DEV__`, verbose module names, and
396
+ the source map.
391
397
 
392
398
  That footer is the only change. Metro drops the fourth `__d` argument when
393
399
  `dev` is false, so a production bundle names none of its modules, and RNX needs
@@ -396,24 +402,40 @@ load time. Resolution, transforms, minification, and the source map stay the
396
402
  app's own, so the annotated bundle is the bundle you ship: the footer assigns
397
403
  one unused global on a device, and Hermes drops it during bytecode compilation.
398
404
 
405
+ RNX also accepts an ordinary, unannotated Metro production JavaScript bundle.
406
+ That path reports identity as `inferred` and matches package graph fingerprints
407
+ from a separately updated, integrity-checked registry. It is deliberately less
408
+ strong than the plugin path: ambiguous packages stay unknown, every unknown
409
+ module receives a nonmatching synthetic name, and React must be identified
410
+ exactly or the load stops before app code runs. Hermes bytecode is not a
411
+ supported input; pass RNX the JavaScript bundle produced before Hermes
412
+ compilation. Use `productionBundles: true` when exact identity is required.
413
+
399
414
  ```js
400
415
  module.exports = withRNX(config, { productionBundles: true })
401
416
 
402
- // enable both when the same Metro process should provide both integrations
417
+ // enable any combination when one Metro process should provide them
403
418
  module.exports = withRNX(config, {
404
419
  devServer: true,
405
420
  productionBundles: true,
421
+ developmentBundles: true,
406
422
  })
407
423
  ```
408
424
 
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:
425
+ Calling `withRNX(config)` changes nothing. The URL helpers request ordinary
426
+ Metro graphs: `dev=false&minify=true` for production and
427
+ `dev=true&minify=false` for development.
412
428
 
413
429
  ```js
414
- const { toRNXProductionBundleUrl } = require('rnxsim/metro')
430
+ const {
431
+ toRNXProductionBundleUrl,
432
+ toRNXDevelopmentBundleUrl,
433
+ } = require('rnxsim/metro')
415
434
 
416
- const bundleUrl = toRNXProductionBundleUrl(
435
+ const productionUrl = toRNXProductionBundleUrl(
436
+ 'http://localhost:8081/index.bundle?platform=ios',
437
+ )
438
+ const developmentUrl = toRNXDevelopmentBundleUrl(
417
439
  'http://localhost:8081/index.bundle?platform=ios',
418
440
  )
419
441
  ```
@@ -11,7 +11,11 @@ import { BoxClientError, createBoxClient } from '@rnx/box/client'
11
11
  import { createBoxHostProvider } from '@rnx/box/host'
12
12
  import { PROJECT_MOUNT } from '@rnx/box/shell'
13
13
  import { terminalBoxStack } from '@rnx/box/stack'
14
- import { BoxTemplateRegistry, terminalBoxTemplate } from '@rnx/box/template'
14
+ import {
15
+ BoxTemplateRegistry,
16
+ sourceControlBoxTemplate,
17
+ terminalBoxTemplate,
18
+ } from '@rnx/box/template'
15
19
  import { createCloudBoxProvider, heartbeatSession } from 'rnx-cloud-box/client'
16
20
  import { rnxPublicBrand } from '../../src/public-brand'
17
21
  import { authHeaderOrExit } from '../auth'
@@ -34,7 +38,10 @@ interface BoxCommandOptions {
34
38
  // that always fails.
35
39
  const ENDPOINT_ENV = 'RNX_BOX_ENDPOINT'
36
40
  const API_ORIGIN_ENV = 'RNX_API_ORIGIN'
37
- const BOX_TEMPLATES = new BoxTemplateRegistry([terminalBoxTemplate])
41
+ const BOX_TEMPLATES = new BoxTemplateRegistry([
42
+ terminalBoxTemplate,
43
+ sourceControlBoxTemplate,
44
+ ])
38
45
 
39
46
  function usage(): void {
40
47
  const rnx = rnxPublicBrand.commandName
@@ -228,7 +235,7 @@ async function runCloudBoxCreate(
228
235
  return 1
229
236
  }
230
237
 
231
- const templateName = flag(args, 'template') ?? terminalBoxTemplate.name
238
+ const templateName = flag(args, 'template') ?? sourceControlBoxTemplate.name
232
239
  let template: BoxTemplateResolution
233
240
  try {
234
241
  template = BOX_TEMPLATES.resolve({ name: templateName })
@@ -283,12 +283,12 @@ export const DECLARED_OUTBOUND_CALLS: Record<string, OutboundCallDeclaration> =
283
283
  category: 'same_origin_runtime',
284
284
  count: 1,
285
285
  },
286
+ 'packages/sootsim-engine/src/render-worker/canvaskit-shared.ts :: fetch :: pipelineCacheUrl':
287
+ { category: 'same_origin_runtime', count: 1 },
286
288
  'packages/sootsim-engine/src/render-worker/canvaskit-shared.ts :: fetch :: wasmUrl': {
287
289
  category: 'same_origin_runtime',
288
290
  count: 1,
289
291
  },
290
- 'packages/sootsim-engine/src/render-worker/compositor-worker.ts :: fetch :: `${engineDistBase}canvaskit-graphite-pipelines.bin`':
291
- { category: 'same_origin_runtime', count: 1 },
292
292
  'packages/sootsim-engine/src/render-worker/host.ts :: fetch :: msg.url': {
293
293
  category: 'guest_app_network',
294
294
  count: 1,
@@ -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
  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 __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 __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;
package/dist-lib/beta.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/beta.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
 
3
3
  // src/beta.ts
4
4
  var IS_BETA = true;
@@ -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/bridge-contract.ts
4
4
  var SIM_LONG_PRESS_MAX_MS = 5e3;
@@ -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/bridge-contract.ts
4
4
  var SIM_LONG_PRESS_DEFAULT_MS = 500;
@@ -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;
@@ -37,7 +37,9 @@ function selectRnxRasterNodeIds(tree) {
37
37
  for (const node of tree.nodes) {
38
38
  const visibleFrame = node.visibleFrame ?? node.frame;
39
39
  if (!visibleFrame || visibleFrame.width <= 0 || visibleFrame.height <= 0) continue;
40
- if (node.type === "masked-view" || node.style._liquidGlass !== void 0 || node.style._liquidGlassEdge !== void 0) {
40
+ if (node.type === "masked-view" || node.type === "text" && typeof node.text === "string" && (new RegExp("\\p{Emoji_Presentation}", "u").test(node.text) || new RegExp("\\uFE0F|\\u200D|\\u20E3|\\p{Emoji_Modifier}|\\p{Regional_Indicator}", "u").test(
41
+ node.text
42
+ )) || node.style._liquidGlass !== void 0 || node.style._liquidGlassEdge !== void 0) {
41
43
  unsupported.add(node.nodeId);
42
44
  }
43
45
  }
@@ -121,6 +123,7 @@ function rnxCaptureRasterRegions(capture) {
121
123
  nodeId: node.nodeId,
122
124
  parentNodeId: node.parentNodeId,
123
125
  type: node.type,
126
+ text: node.text,
124
127
  style: node.style.resolved,
125
128
  layout: node.layout.local,
126
129
  frame: node.layout.frame,
@@ -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/capture-contract.ts
4
4
  var RNX_SCREEN_CAPTURE_VERSION = 1;
@@ -8,7 +8,9 @@ function selectRnxRasterNodeIds(tree) {
8
8
  for (const node of tree.nodes) {
9
9
  const visibleFrame = node.visibleFrame ?? node.frame;
10
10
  if (!visibleFrame || visibleFrame.width <= 0 || visibleFrame.height <= 0) continue;
11
- if (node.type === "masked-view" || node.style._liquidGlass !== void 0 || node.style._liquidGlassEdge !== void 0) {
11
+ if (node.type === "masked-view" || node.type === "text" && typeof node.text === "string" && (/\p{Emoji_Presentation}/u.test(node.text) || /\uFE0F|\u200D|\u20E3|\p{Emoji_Modifier}|\p{Regional_Indicator}/u.test(
12
+ node.text
13
+ )) || node.style._liquidGlass !== void 0 || node.style._liquidGlassEdge !== void 0) {
12
14
  unsupported.add(node.nodeId);
13
15
  }
14
16
  }
@@ -92,6 +94,7 @@ function rnxCaptureRasterRegions(capture) {
92
94
  nodeId: node.nodeId,
93
95
  parentNodeId: node.parentNodeId,
94
96
  type: node.type,
97
+ text: node.text,
95
98
  style: node.style.resolved,
96
99
  layout: node.layout.local,
97
100
  frame: node.layout.frame,
@@ -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;
@@ -50,7 +50,8 @@ var RNX_CLOUD_COMMAND_TYPES = Object.freeze([
50
50
  "tree",
51
51
  "tap",
52
52
  "longPress",
53
- "memory"
53
+ "memory",
54
+ "diagnostics"
54
55
  ]);
55
56
  var RNX_CLOUD_COMMAND_TYPE_SET = new Set(RNX_CLOUD_COMMAND_TYPES);
56
57
  function isRnxCloudCommandType(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
 
3
3
  // src/cloud-contract.ts
4
4
  var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
@@ -21,7 +21,8 @@ var RNX_CLOUD_COMMAND_TYPES = Object.freeze([
21
21
  "tree",
22
22
  "tap",
23
23
  "longPress",
24
- "memory"
24
+ "memory",
25
+ "diagnostics"
25
26
  ]);
26
27
  var RNX_CLOUD_COMMAND_TYPE_SET = new Set(RNX_CLOUD_COMMAND_TYPES);
27
28
  function isRnxCloudCommandType(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 __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;
@@ -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;
@@ -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 __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
 
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.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 __create = Object.create;
@@ -522,7 +522,8 @@ var RNX_CLOUD_COMMAND_TYPES = Object.freeze([
522
522
  "tree",
523
523
  "tap",
524
524
  "longPress",
525
- "memory"
525
+ "memory",
526
+ "diagnostics"
526
527
  ]);
527
528
  var RNX_CLOUD_COMMAND_TYPE_SET = new Set(RNX_CLOUD_COMMAND_TYPES);
528
529
 
@@ -2676,7 +2677,9 @@ function selectRnxRasterNodeIds(tree) {
2676
2677
  for (const node of tree.nodes) {
2677
2678
  const visibleFrame = node.visibleFrame ?? node.frame;
2678
2679
  if (!visibleFrame || visibleFrame.width <= 0 || visibleFrame.height <= 0) continue;
2679
- if (node.type === "masked-view" || node.style._liquidGlass !== void 0 || node.style._liquidGlassEdge !== void 0) {
2680
+ if (node.type === "masked-view" || node.type === "text" && typeof node.text === "string" && (new RegExp("\\p{Emoji_Presentation}", "u").test(node.text) || new RegExp("\\uFE0F|\\u200D|\\u20E3|\\p{Emoji_Modifier}|\\p{Regional_Indicator}", "u").test(
2681
+ node.text
2682
+ )) || node.style._liquidGlass !== void 0 || node.style._liquidGlassEdge !== void 0) {
2680
2683
  unsupported.add(node.nodeId);
2681
2684
  }
2682
2685
  }
@@ -2760,6 +2763,7 @@ function rnxCaptureRasterRegions(capture) {
2760
2763
  nodeId: node.nodeId,
2761
2764
  parentNodeId: node.parentNodeId,
2762
2765
  type: node.type,
2766
+ text: node.text,
2763
2767
  style: node.style.resolved,
2764
2768
  layout: node.layout.local,
2765
2769
  frame: node.layout.frame,
@@ -3343,6 +3347,11 @@ function serveRuntimeFile(req, res, fullPath) {
3343
3347
  const stat = import_fs3.default.statSync(fullPath);
3344
3348
  const lastModified = stat.mtime.toUTCString();
3345
3349
  res.setHeader("content-type", MIME_TYPES[ext] || "application/octet-stream");
3350
+ if (/^canvaskit-graphite-pipelines-[0-9a-f]{8}\.bin$/.test(import_path2.default.basename(fullPath))) {
3351
+ res.setHeader("cache-control", "public, max-age=31536000, immutable");
3352
+ import_fs3.default.createReadStream(fullPath).pipe(res);
3353
+ return;
3354
+ }
3346
3355
  res.setHeader("cache-control", "no-cache");
3347
3356
  res.setHeader("last-modified", lastModified);
3348
3357
  if (req?.headers?.["if-modified-since"] === lastModified) {
@@ -3492,11 +3501,28 @@ var import_path4 = __toESM(require("path"), 1);
3492
3501
 
3493
3502
  // src/metro-production-bundle.ts
3494
3503
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
3495
- function createRNXMetroModulePathsFooter(modulePaths) {
3496
- const payload = JSON.stringify(modulePaths).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
3504
+ var RNX_METRO_MODULE_IDENTITY_VERSION = 2;
3505
+ var RNXSIM_METRO_SOURCE_MAP_COMMENT = "//# sourceMappingURL=";
3506
+ function detachRNXMetroSourceMapUrl(bundleText) {
3507
+ const trimmedEnd = bundleText.replace(/\s+$/, "");
3508
+ const commentStart = trimmedEnd.lastIndexOf(`
3509
+ ${RNXSIM_METRO_SOURCE_MAP_COMMENT}`);
3510
+ if (commentStart < 0) return { source: bundleText, sourceMappingUrl: null };
3511
+ const url = trimmedEnd.slice(commentStart + 1 + RNXSIM_METRO_SOURCE_MAP_COMMENT.length);
3512
+ if (url.includes("\n")) return { source: bundleText, sourceMappingUrl: null };
3513
+ return { source: trimmedEnd.slice(0, commentStart), sourceMappingUrl: url };
3514
+ }
3515
+ function createRNXMetroModuleIdentityFooter(identity) {
3516
+ const payload = JSON.stringify(identity).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029").replace(/<\//g, "<\\/");
3497
3517
  return `
3498
3518
  ${RNXSIM_METRO_MODULE_PATHS_PREFIX}${payload};`;
3499
3519
  }
3520
+ function appendRNXMetroModuleIdentityFooter(bundleText, identity) {
3521
+ const footer = createRNXMetroModuleIdentityFooter(identity);
3522
+ const detached = detachRNXMetroSourceMapUrl(bundleText);
3523
+ return detached.sourceMappingUrl === null ? bundleText + footer : `${detached.source}${footer}
3524
+ ${RNXSIM_METRO_SOURCE_MAP_COMMENT}${detached.sourceMappingUrl}`;
3525
+ }
3500
3526
 
3501
3527
  // src/metro-plugin.ts
3502
3528
  var prefix = "/__soot";
@@ -3533,22 +3559,44 @@ function appendRNXModulePaths(result, graph, options, projectRoot) {
3533
3559
  const dependencies = graph.dependencies;
3534
3560
  const createModuleId = options.createModuleId;
3535
3561
  if (!dependencies || !createModuleId) {
3536
- throw new Error(
3537
- "rnxsim: Metro did not provide the production module graph and createModuleId"
3538
- );
3562
+ throw new Error("rnxsim: Metro did not provide the module graph and createModuleId");
3539
3563
  }
3540
3564
  const modulePaths = {};
3541
3565
  for (const module2 of dependencies.values()) {
3542
3566
  modulePaths[String(createModuleId(module2.path))] = import_path4.default.relative(projectRoot, module2.path).replaceAll(import_path4.default.sep, "/");
3543
3567
  }
3544
3568
  if (Object.keys(modulePaths).length !== dependencies.size) {
3545
- throw new Error("rnxsim: production module IDs were not unique");
3569
+ throw new Error("rnxsim: bundle module IDs were not unique");
3570
+ }
3571
+ const specifiersByModuleId = /* @__PURE__ */ new Map();
3572
+ for (const module2 of dependencies.values()) {
3573
+ for (const [dependencyKey, dependency] of module2.dependencies ?? []) {
3574
+ const specifier = dependency.data?.name ?? dependencyKey;
3575
+ if (specifier.length === 0 || specifier.startsWith(".") || specifier.startsWith("/") || typeof dependency.absolutePath !== "string") {
3576
+ continue;
3577
+ }
3578
+ const moduleId = String(createModuleId(dependency.absolutePath));
3579
+ if (!Object.prototype.hasOwnProperty.call(modulePaths, moduleId)) continue;
3580
+ const found = specifiersByModuleId.get(moduleId);
3581
+ if (found) found.add(specifier);
3582
+ else specifiersByModuleId.set(moduleId, /* @__PURE__ */ new Set([specifier]));
3583
+ }
3546
3584
  }
3547
- const footer = createRNXMetroModulePathsFooter(modulePaths);
3548
- return typeof result === "string" ? result + footer : { ...result, code: result.code + footer };
3585
+ const logicalSpecifiers = Object.fromEntries(
3586
+ [...specifiersByModuleId].sort(([left], [right]) => Number(left) - Number(right)).map(([moduleId, specifiers]) => [moduleId, [...specifiers].sort()])
3587
+ );
3588
+ const identity = {
3589
+ version: RNX_METRO_MODULE_IDENTITY_VERSION,
3590
+ identitySource: "rnx-plugin",
3591
+ modulePaths,
3592
+ logicalSpecifiers
3593
+ };
3594
+ return typeof result === "string" ? appendRNXMetroModuleIdentityFooter(result, identity) : { ...result, code: appendRNXMetroModuleIdentityFooter(result.code, identity) };
3549
3595
  }
3550
3596
  function withRNX(config, options = {}) {
3551
- if (!options.devServer && !options.open && !options.productionBundles) return config;
3597
+ if (!options.devServer && !options.open && !options.productionBundles && !options.developmentBundles) {
3598
+ return config;
3599
+ }
3552
3600
  const cfgProjectRoot = config.projectRoot || process.cwd();
3553
3601
  const appName = resolveRnxDesktopAppName(options.open, cfgProjectRoot);
3554
3602
  const configuredBundleUrl = options.bundleUrl || "/index.bundle?platform=ios&dev=true&hot=true&minify=false";
@@ -3566,7 +3614,7 @@ function withRNX(config, options = {}) {
3566
3614
  const existingEnhance = cfgServer?.enhanceMiddleware;
3567
3615
  const existingSerializer = cfgSerializer?.customSerializer;
3568
3616
  let productionConfig = {};
3569
- if (options.productionBundles) {
3617
+ if (options.productionBundles || options.developmentBundles) {
3570
3618
  let defaultSerializer;
3571
3619
  productionConfig = {
3572
3620
  serializer: {
@@ -3579,7 +3627,8 @@ function withRNX(config, options = {}) {
3579
3627
  graph,
3580
3628
  serializerOptions
3581
3629
  );
3582
- return graph.transformOptions?.dev === false ? appendRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot) : result;
3630
+ const dev = serializerOptions.dev;
3631
+ return dev === false && options.productionBundles === true || dev === true && options.developmentBundles === true ? appendRNXModulePaths(result, graph, serializerOptions, cfgProjectRoot) : result;
3583
3632
  }
3584
3633
  }
3585
3634
  };
@@ -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/menu.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/menu.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
 
3
3
  // src/public-brand.ts
4
4
  var name = "rnx";