rnxsim 0.1.522 → 0.1.523

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 (56) hide show
  1. package/cli/commands/control.ts +31 -15
  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/cloud.cjs +1 -1
  22. package/dist-lib/cloud.mjs +1 -1
  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 +1 -1
  34. package/dist-lib/jump-to-source-babel.cjs +1 -1
  35. package/dist-lib/jump-to-source-native.cjs +1 -1
  36. package/dist-lib/menu.cjs +1 -1
  37. package/dist-lib/menu.mjs +1 -1
  38. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  39. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  40. package/dist-lib/metro-production-bundle.cjs +1 -1
  41. package/dist-lib/metro-production-bundle.mjs +1 -1
  42. package/dist-lib/metro.cjs +1 -1
  43. package/dist-lib/profiles.cjs +1 -1
  44. package/dist-lib/public-brand.cjs +1 -1
  45. package/dist-lib/react-native-host-modules.cjs +1 -1
  46. package/dist-lib/react-native-host-modules.mjs +1 -1
  47. package/dist-lib/render-mode.cjs +1 -1
  48. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  49. package/dist-lib/sdk.cjs +1 -1
  50. package/dist-lib/sdk.mjs +1 -1
  51. package/dist-lib/skills.cjs +26 -12
  52. package/dist-lib/swift.cjs +129 -71
  53. package/dist-lib/vite.cjs +6 -21
  54. package/package.json +1 -1
  55. package/src/swift.ts +2 -3
  56. package/src/vite-plugin-swift.ts +22 -36
@@ -393,30 +393,46 @@ function localBasePort(target: string): number | null {
393
393
  }
394
394
  }
395
395
 
396
+ // a dev server started alongside open connect may still be booting when the
397
+ // first probe lands. retry briefly so staging does not fail on a server that
398
+ // becomes probe-ready a few seconds later.
399
+ const DEV_BUNDLE_RESOLVE_ATTEMPTS = 15
400
+ const DEV_BUNDLE_RESOLVE_INTERVAL_MS = 1000
401
+
396
402
  async function resolveConnectionInputForCli(target: string): Promise<ResolvedDevBundle> {
397
403
  const normalized = normalizeKnownTarget(target)
398
404
  const registeredPort = /^\d+$/.test(normalized)
399
405
  ? Number(normalized)
400
406
  : localBasePort(normalized)
401
407
 
402
- if (registeredPort && registeredPort > 0) {
403
- const discovered = await probePort(registeredPort)
404
- // a provisional bundle URL means the scanner's fast manifest probe got no
405
- // answer and fell back to the generic `/index.bundle`. that is enough to
406
- // LIST the server and not enough to open it, so hand the question to
407
- // `resolveConnectionInput`, which asks the manifest again with a budget
408
- // that fits a real dev server and returns the entry point the app names.
409
- if (discovered && !discovered.bundleUrlProvisional) {
410
- return {
411
- bundleUrl: discovered.bundleUrl,
412
- port: discovered.port,
413
- framework: discovered.framework,
414
- projectName: discovered.projectName,
408
+ let lastError: Error | null = null
409
+ for (let attempt = 0; attempt < DEV_BUNDLE_RESOLVE_ATTEMPTS; attempt++) {
410
+ if (registeredPort && registeredPort > 0) {
411
+ const discovered = await probePort(registeredPort)
412
+ // a provisional bundle URL is enough to LIST the server but not to open
413
+ // it; fall through to resolveConnectionInput, which asks the manifest
414
+ // again with a budget that fits a real dev server.
415
+ if (discovered && !discovered.bundleUrlProvisional) {
416
+ return {
417
+ bundleUrl: discovered.bundleUrl,
418
+ port: discovered.port,
419
+ framework: discovered.framework,
420
+ projectName: discovered.projectName,
421
+ }
415
422
  }
416
423
  }
417
- }
418
424
 
419
- return resolveConnectionInput(normalized)
425
+ try {
426
+ return await resolveConnectionInput(normalized)
427
+ } catch (error) {
428
+ if (!(error instanceof Error) || !error.message.startsWith("could not resolve a native bundle")) {
429
+ throw error
430
+ }
431
+ lastError = error
432
+ }
433
+ await sleep(DEV_BUNDLE_RESOLVE_INTERVAL_MS)
434
+ }
435
+ throw lastError ?? new Error("could not resolve a native bundle for " + normalized + " after retrying.")
420
436
  }
421
437
 
422
438
  function getShellRoutePrefix(pathname: string): string {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var REFUSED_PERFORM_STEP_TYPES = [
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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/menu.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/metro-fingerprint-registry.ts
4
4
  var RNX_METRO_FINGERPRINT_SCHEMA_VERSION = 2;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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=";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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;
@@ -34247,18 +34247,30 @@ function localBasePort(target) {
34247
34247
  async function resolveConnectionInputForCli(target) {
34248
34248
  const normalized = normalizeKnownTarget(target);
34249
34249
  const registeredPort = /^\d+$/.test(normalized) ? Number(normalized) : localBasePort(normalized);
34250
- if (registeredPort && registeredPort > 0) {
34251
- const discovered = await probePort(registeredPort);
34252
- if (discovered && !discovered.bundleUrlProvisional) {
34253
- return {
34254
- bundleUrl: discovered.bundleUrl,
34255
- port: discovered.port,
34256
- framework: discovered.framework,
34257
- projectName: discovered.projectName
34258
- };
34250
+ let lastError = null;
34251
+ for (let attempt = 0; attempt < DEV_BUNDLE_RESOLVE_ATTEMPTS; attempt++) {
34252
+ if (registeredPort && registeredPort > 0) {
34253
+ const discovered = await probePort(registeredPort);
34254
+ if (discovered && !discovered.bundleUrlProvisional) {
34255
+ return {
34256
+ bundleUrl: discovered.bundleUrl,
34257
+ port: discovered.port,
34258
+ framework: discovered.framework,
34259
+ projectName: discovered.projectName
34260
+ };
34261
+ }
34262
+ }
34263
+ try {
34264
+ return await resolveConnectionInput(normalized);
34265
+ } catch (error) {
34266
+ if (!(error instanceof Error) || !error.message.startsWith("could not resolve a native bundle")) {
34267
+ throw error;
34268
+ }
34269
+ lastError = error;
34259
34270
  }
34271
+ await sleep2(DEV_BUNDLE_RESOLVE_INTERVAL_MS);
34260
34272
  }
34261
- return resolveConnectionInput(normalized);
34273
+ throw lastError ?? new Error("could not resolve a native bundle for " + normalized + " after retrying.");
34262
34274
  }
34263
34275
  function getShellRoutePrefix(pathname) {
34264
34276
  const normalized = pathname.replace(/\/+$/, "") || "/";
@@ -35543,7 +35555,7 @@ async function runCloseCommand(args, opts = {}) {
35543
35555
  bridge.close();
35544
35556
  }
35545
35557
  }
35546
- var import_node_child_process7, import_node_fs20, import_node_os3, import_node_path22, import_settings, import_ws4, DEFAULT_DRIVER_CONNECT_TIMEOUT_MS, DRIVER_CONNECT_INTERVAL_MS, DRIVER_CONNECT_HOST_GRACE_MS, OPEN_BRIDGE_SPAWN_TIMEOUT_MS, SHELL_APPS;
35558
+ var import_node_child_process7, import_node_fs20, import_node_os3, import_node_path22, import_settings, import_ws4, DEFAULT_DRIVER_CONNECT_TIMEOUT_MS, DRIVER_CONNECT_INTERVAL_MS, DRIVER_CONNECT_HOST_GRACE_MS, OPEN_BRIDGE_SPAWN_TIMEOUT_MS, SHELL_APPS, DEV_BUNDLE_RESOLVE_ATTEMPTS, DEV_BUNDLE_RESOLVE_INTERVAL_MS;
35547
35559
  var init_control = __esm({
35548
35560
  "cli/commands/control.ts"() {
35549
35561
  "use strict";
@@ -35594,6 +35606,8 @@ var init_control = __esm({
35594
35606
  photos: "/app/photos",
35595
35607
  camera: "/app/camera"
35596
35608
  };
35609
+ DEV_BUNDLE_RESOLVE_ATTEMPTS = 15;
35610
+ DEV_BUNDLE_RESOLVE_INTERVAL_MS = 1e3;
35597
35611
  }
35598
35612
  });
35599
35613
 
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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;
@@ -32,8 +32,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
  // src/swift.ts
33
33
  var swift_exports = {};
34
34
  __export(swift_exports, {
35
- createSwiftModule: () => createSwiftModule,
36
- createSwiftView: () => createSwiftView
35
+ createSwiftEntry: () => createSwiftEntry
37
36
  });
38
37
  module.exports = __toCommonJS(swift_exports);
39
38
 
@@ -190,20 +189,6 @@ function pointerExport(exports2, name) {
190
189
  return result;
191
190
  };
192
191
  }
193
- function maybePointerExport(exports2, name) {
194
- const value = exports2[name];
195
- if (value === void 0) return void 0;
196
- if (typeof value !== "function") {
197
- throw new Error(`swift export ${name} is not a function`);
198
- }
199
- return (...args) => {
200
- const result = Reflect.apply(value, void 0, args);
201
- if (typeof result !== "number") {
202
- throw new Error(`swift export ${name} returned ${typeof result}`);
203
- }
204
- return result;
205
- };
206
- }
207
192
  function voidExport(exports2, name) {
208
193
  const fn = rawExport(exports2, name);
209
194
  return (...args) => {
@@ -236,13 +221,35 @@ function instantiate(module2) {
236
221
  const initialize = voidExport(instance.exports, "_initialize");
237
222
  const mainArgv = voidExport(instance.exports, "__main_argc_argv");
238
223
  const mount = pointerExport(instance.exports, "rnx_mount");
239
- const mountViewExport = maybePointerExport(instance.exports, "rnx_mount_view");
240
- const hasViewExport = maybePointerExport(instance.exports, "rnx_has_view");
224
+ const mountViewExport = pointerExport(instance.exports, "rnx_mount_view");
225
+ const hasViewExport = pointerExport(instance.exports, "rnx_has_view");
241
226
  const event = pointerExport(instance.exports, "rnx_event");
242
227
  const stateExport = pointerExport(instance.exports, "rnx_state_export");
243
228
  const stateImport = voidExport(instance.exports, "rnx_state_import");
244
229
  const alloc = pointerExport(instance.exports, "rnx_alloc");
245
230
  const free = voidExport(instance.exports, "rnx_free");
231
+ const openURLDrain = typeof instance.exports.rnx_open_url_drain === "function" ? pointerExport(instance.exports, "rnx_open_url_drain") : null;
232
+ const drainOpenURLs = () => {
233
+ if (!openURLDrain) return;
234
+ let urls;
235
+ try {
236
+ urls = JSON.parse(readBuffer(openURLDrain()));
237
+ } catch {
238
+ return;
239
+ }
240
+ if (!Array.isArray(urls)) return;
241
+ for (const url of urls) {
242
+ if (typeof url !== "string") continue;
243
+ import_react_native.Linking.canOpenURL(url).then(
244
+ (open) => {
245
+ if (open) import_react_native.Linking.openURL(url).catch(() => {
246
+ });
247
+ },
248
+ () => {
249
+ }
250
+ );
251
+ }
252
+ };
246
253
  const readBuffer = (ptr) => {
247
254
  const view = new DataView(requireMemory().buffer);
248
255
  const length = view.getUint32(ptr, true);
@@ -262,41 +269,44 @@ function instantiate(module2) {
262
269
  mainArgv(0, 0);
263
270
  return {
264
271
  mount: () => {
265
- if ((hasViewExport?.() ?? 0) === 1) {
272
+ if (hasViewExport() === 1) {
266
273
  throw new Error(
267
274
  "swift package has an RNXPackage entry, not an App entry; mount it as a view or make its @main type conform to App"
268
275
  );
269
276
  }
270
- return readTree(readBuffer(mount()));
277
+ const tree = readTree(readBuffer(mount()));
278
+ drainOpenURLs();
279
+ return tree;
271
280
  },
272
281
  mountView: (props) => {
273
- if (!mountViewExport) {
274
- throw new Error(
275
- "swift artifact has no rnx_mount_view export; rebuild the swift package"
276
- );
277
- }
278
- if ((hasViewExport?.() ?? 0) !== 1) {
282
+ if (hasViewExport() !== 1) {
279
283
  throw new Error(
280
284
  "swift package has no RNXPackage entry; its @main type must conform to RNXPackage to mount as a view"
281
285
  );
282
286
  }
283
- return readTree(
287
+ const tree = readTree(
284
288
  readBuffer(withPayload(props, (ptr, length) => mountViewExport(ptr, length)))
285
289
  );
290
+ drainOpenURLs();
291
+ return tree;
286
292
  },
287
- hasView: () => (hasViewExport?.() ?? 0) === 1,
288
- deliver: (handlerId2, payload) => readTree(
289
- readBuffer(
290
- withPayload(
291
- payload,
292
- (ptr, length) => (
293
- // handler ids are opaque to the tenant: they come from the tree
294
- // this instance just returned and they are only meaningful to it
295
- event(handlerId2, ptr, length)
293
+ hasView: () => hasViewExport() === 1,
294
+ deliver: (handlerId2, payload) => {
295
+ const tree = readTree(
296
+ readBuffer(
297
+ withPayload(
298
+ payload,
299
+ (ptr, length) => (
300
+ // handler ids are opaque to the tenant: they come from the tree
301
+ // this instance just returned and they are only meaningful to it
302
+ event(handlerId2, ptr, length)
303
+ )
296
304
  )
297
305
  )
298
- )
299
- ),
306
+ );
307
+ drainOpenURLs();
308
+ return tree;
309
+ },
300
310
  exportState: () => readBuffer(stateExport()),
301
311
  importState: (state) => {
302
312
  withPayload(JSON.parse(state), (ptr, length) => {
@@ -378,6 +388,16 @@ function resolveModifier(modifier) {
378
388
  }
379
389
  return { ...modifier, color: resolveColor(color) };
380
390
  }
391
+ var SwiftResourcesContext = (0, import_react.createContext)(void 0);
392
+ function SwiftImage(props) {
393
+ const table = (0, import_react.useContext)(SwiftResourcesContext);
394
+ const { source, ...rest } = props ?? {};
395
+ const url = typeof source === "string" ? table?.[source] : void 0;
396
+ return (0, import_react.createElement)(import_ui.Image, {
397
+ ...rest,
398
+ ...source === void 0 ? {} : { source: typeof url === "string" ? { uri: url } : source }
399
+ });
400
+ }
381
401
  var NODE_COMPONENTS = {
382
402
  Alert: SwiftAlert,
383
403
  BottomSheet: import_ui.BottomSheet,
@@ -390,14 +410,17 @@ var NODE_COMPONENTS = {
390
410
  Divider: import_ui.Divider,
391
411
  Ellipse: import_ui.Ellipse,
392
412
  Form: import_ui.Form,
413
+ GeometryReader: import_ui.GeometryReader,
393
414
  GlassEffectContainer: import_ui.GlassEffectContainer,
394
415
  Group: import_ui.Group,
395
416
  HStack: import_ui.HStack,
396
- Image: import_ui.Image,
417
+ Image: SwiftImage,
397
418
  Label: import_ui.Label,
398
419
  LazyVStack: import_ui.LazyVStack,
420
+ LinearGradient: import_ui.LinearGradient,
399
421
  List: import_ui.List,
400
422
  Menu: import_ui.Menu,
423
+ Path: import_ui.Path,
401
424
  Picker: import_ui.Picker,
402
425
  ProgressView: import_ui.ProgressView,
403
426
  Rectangle: import_ui.Rectangle,
@@ -613,6 +636,12 @@ function nodeProps(node, deliver) {
613
636
  const size = typeof font?.size === "number" ? font.size : void 0;
614
637
  return {
615
638
  ...typeof props.systemName === "string" ? { systemName: props.systemName } : {},
639
+ // a bundle asset name rides as the kit image source; the kit paints
640
+ // its placeholder until its named-source lane lands (contrast-kit,
641
+ // not this mount row).
642
+ ...typeof props.name === "string" ? { source: props.name } : {},
643
+ ...props.resizable === true ? { resizable: true } : {},
644
+ ...typeof props.renderingMode === "string" ? { renderingMode: props.renderingMode } : {},
616
645
  ...size === void 0 ? {} : { size },
617
646
  ...pressProps(node, deliver)
618
647
  };
@@ -1095,10 +1124,26 @@ function SplitViewHost({
1095
1124
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: { flex: 1 }, children: pushed.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigationStackHost, { node: { ...node, c: pushed }, deliver }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: detail.map((child) => renderNode(child, deliver, cache)) }) })
1096
1125
  ] });
1097
1126
  }
1127
+ function SwiftAppear({
1128
+ node,
1129
+ deliver,
1130
+ children
1131
+ }) {
1132
+ const onAppear = handlerId(node, "onAppear");
1133
+ const onDisappear = handlerId(node, "onDisappear");
1134
+ (0, import_react.useEffect)(() => {
1135
+ if (onAppear !== void 0) deliver(onAppear, null);
1136
+ return () => {
1137
+ if (onDisappear !== void 0) deliver(onDisappear, null);
1138
+ };
1139
+ }, []);
1140
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
1141
+ }
1098
1142
  function renderNode(node, deliver, cache) {
1099
1143
  const cached = cache?.entries.get(node.id);
1100
1144
  if (cached && sameNode(cached.node, node)) return cached.element;
1101
- const element = buildNode(node, deliver, cache);
1145
+ const built = buildNode(node, deliver, cache);
1146
+ const element = node.h?.onAppear !== void 0 || node.h?.onDisappear !== void 0 ? (0, import_react.createElement)(SwiftAppear, { key: node.id, node, deliver }, built) : built;
1102
1147
  cache?.entries.set(node.id, { node, element });
1103
1148
  return element;
1104
1149
  }
@@ -1140,7 +1185,8 @@ function buildNode(node, deliver, cache) {
1140
1185
  function SwiftTree({
1141
1186
  tree,
1142
1187
  deliver,
1143
- cache
1188
+ cache,
1189
+ resources
1144
1190
  }) {
1145
1191
  return (
1146
1192
  // a navigation stack at the root lays its own bar out under the status
@@ -1153,7 +1199,7 @@ function SwiftTree({
1153
1199
  ignoreSafeArea: tree.some(
1154
1200
  (node) => node.t === "NavigationStack" || node.t === "NavigationSplitView"
1155
1201
  ),
1156
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_native.NavigationIndependentTree, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_native.NavigationContainer, { children: tree.map((node) => renderNode(node, deliver, cache)) }) })
1202
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_native.NavigationIndependentTree, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_native.NavigationContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwiftResourcesContext.Provider, { value: resources, children: tree.map((node) => renderNode(node, deliver, cache)) }) }) })
1157
1203
  }
1158
1204
  )
1159
1205
  );
@@ -1166,19 +1212,19 @@ function rootRegistry() {
1166
1212
  Reflect.set(globalThis, ROOT_KEY, created);
1167
1213
  return created;
1168
1214
  }
1169
- function slotFor(rootId, mountTree, props) {
1215
+ function slotFor(rootId, mountTree) {
1170
1216
  const registry = rootRegistry();
1171
1217
  const existing = registry.get(rootId);
1172
1218
  if (existing) return existing;
1173
- const created = { root: createRoot(mountTree, props), props };
1219
+ const created = { root: createRoot(mountTree) };
1174
1220
  registry.set(rootId, created);
1175
1221
  return created;
1176
1222
  }
1177
- function createRoot(mountTree, props) {
1223
+ function createRoot(mountTree) {
1178
1224
  let instance = null;
1179
1225
  let source = null;
1180
1226
  let refresh;
1181
- let state = { tree: null, error: null };
1227
+ let state = { tree: null, isView: false, error: null };
1182
1228
  let swap = Promise.resolve();
1183
1229
  const listeners = /* @__PURE__ */ new Set();
1184
1230
  const cache = { entries: /* @__PURE__ */ new Map() };
@@ -1186,13 +1232,14 @@ function createRoot(mountTree, props) {
1186
1232
  state = next;
1187
1233
  for (const listener of listeners) listener();
1188
1234
  };
1189
- const apply = async (options) => {
1235
+ const apply = async (options, props) => {
1190
1236
  const carried = instance?.exportState() ?? null;
1191
1237
  const created = instantiate(await compile(options.url));
1192
1238
  if (carried !== null) created.importState(carried);
1193
1239
  if (source !== options) return;
1194
1240
  instance = created;
1195
- publish({ tree: mountTree(created, props.current), error: null });
1241
+ const mounted = mountTree(created, props);
1242
+ publish({ tree: mounted.tree, isView: mounted.isView, error: null });
1196
1243
  };
1197
1244
  const component = function SwiftRoot() {
1198
1245
  const rendered = (0, import_react.useSyncExternalStore)(
@@ -1206,24 +1253,41 @@ function createRoot(mountTree, props) {
1206
1253
  if (!rendered.tree) return null;
1207
1254
  const deliver = (handlerId2, payload) => {
1208
1255
  if (!instance) throw new Error("swift app received an event before it mounted");
1209
- publish({ tree: instance.deliver(handlerId2, payload), error: null });
1256
+ publish({
1257
+ tree: instance.deliver(handlerId2, payload),
1258
+ isView: rendered.isView,
1259
+ error: null
1260
+ });
1210
1261
  };
1211
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwiftTree, { tree: rendered.tree, deliver, cache });
1262
+ const resources = source?.resources;
1263
+ if (rendered.isView)
1264
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwiftResourcesContext.Provider, { value: resources, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: rendered.tree.map((node) => renderNode(node, deliver, cache)) }) });
1265
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1266
+ SwiftTree,
1267
+ {
1268
+ tree: rendered.tree,
1269
+ deliver,
1270
+ cache,
1271
+ resources
1272
+ }
1273
+ );
1212
1274
  };
1213
1275
  return {
1214
1276
  component,
1215
- use(options, refreshKey) {
1216
- const changed = source === null || source.hash !== options.hash || source.url !== options.url || refreshKey !== void 0 && refreshKey !== refresh;
1277
+ use(options, refreshKey, props) {
1278
+ const changed = source === null || source.hash !== options.hash || source.url !== options.url || JSON.stringify(source.resources ?? null) !== JSON.stringify(options.resources ?? null) || refreshKey !== void 0 && refreshKey !== refresh;
1217
1279
  if (changed) {
1218
1280
  source = options;
1219
1281
  refresh = refreshKey;
1282
+ const next = props ?? {};
1220
1283
  swap = swap.then(
1221
- () => apply(options),
1222
- () => apply(options)
1284
+ () => apply(options, next),
1285
+ () => apply(options, next)
1223
1286
  );
1224
1287
  swap.catch((error) => {
1225
1288
  publish({
1226
1289
  tree: null,
1290
+ isView: false,
1227
1291
  error: error instanceof Error ? error : new Error(String(error))
1228
1292
  });
1229
1293
  });
@@ -1232,11 +1296,6 @@ function createRoot(mountTree, props) {
1232
1296
  }
1233
1297
  };
1234
1298
  }
1235
- function createSwiftModule(options) {
1236
- const rootId = options.rootId ?? "root";
1237
- const slot = slotFor(rootId, (instance) => instance.mount(), { current: {} });
1238
- return slot.root.use(options);
1239
- }
1240
1299
  function propsSignature(props) {
1241
1300
  try {
1242
1301
  return JSON.stringify(props, (_key, value) => {
@@ -1253,22 +1312,21 @@ function propsSignature(props) {
1253
1312
  );
1254
1313
  }
1255
1314
  }
1256
- function createSwiftView(options) {
1257
- const rootId = options.rootId ?? "view";
1258
- const slot = slotFor(rootId, (instance, props) => instance.mountView(props), {
1259
- current: {}
1260
- });
1261
- return function SwiftView(props) {
1315
+ function createSwiftEntry(options) {
1316
+ const rootId = options.rootId ?? "root";
1317
+ const slot = slotFor(
1318
+ rootId,
1319
+ (instance, props) => instance.hasView() ? { tree: instance.mountView(props), isView: true } : { tree: instance.mount(), isView: false }
1320
+ );
1321
+ return function SwiftEntry(props) {
1262
1322
  if (props.children !== void 0) {
1263
- throw new Error("swift views take data props, not children");
1323
+ throw new Error("swift entries take data props, not children");
1264
1324
  }
1265
- slot.props.current = props;
1266
- const component = slot.root.use(options, propsSignature(props));
1325
+ const component = slot.root.use(options, propsSignature(props), props);
1267
1326
  return (0, import_react.createElement)(component);
1268
1327
  };
1269
1328
  }
1270
1329
  // Annotate the CommonJS export names for ESM import in node:
1271
1330
  0 && (module.exports = {
1272
- createSwiftModule,
1273
- createSwiftView
1331
+ createSwiftEntry
1274
1332
  });
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.522 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.523 | (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;
@@ -829,8 +829,9 @@ function sourceStamp(packagePath) {
829
829
  }
830
830
  return hash.digest("hex").slice(0, 16);
831
831
  }
832
- function viewRootId(packagePath, file) {
833
- return import_node_path4.default.join(packagePath, import_node_path4.default.relative(packagePath, file));
832
+ function entryRootId(packagePath, file) {
833
+ const relative2 = import_node_path4.default.relative(packagePath, file).split(import_node_path4.default.sep).join(import_node_path4.default.posix.sep);
834
+ return `${import_node_path4.default.basename(packagePath)}${import_node_path4.default.posix.sep}${relative2}`;
834
835
  }
835
836
  function artifactUrl(project, artifact) {
836
837
  const address = devServer?.httpServer?.address();
@@ -927,14 +928,6 @@ function packageFor(file) {
927
928
  `no Package.swift above ${file}${stop === void 0 ? "" : ` (searched up to ${stop})`}; a .swift import needs a swiftpm package like the one in packages/sootsim-swift/example`
928
929
  );
929
930
  }
930
- function isViewPackage(packagePath) {
931
- const main = /@main\s+(?:\w+\s+)*(?:struct|class|enum|actor)\s+\w+[^{]*:\s*[^{]*\bRNXPackage\b/;
932
- for (const file of sourceFiles(packagePath)) {
933
- const text = import_node_fs3.default.readFileSync(file, "utf8").replace(/^\s*\/\/.*$/gm, "");
934
- if (main.test(text)) return true;
935
- }
936
- return false;
937
- }
938
931
  function swiftPlugin(options = {}) {
939
932
  return {
940
933
  name: "rnx-swift",
@@ -968,17 +961,9 @@ function swiftPlugin(options = {}) {
968
961
  this.warn(error instanceof Error ? error.message : String(error));
969
962
  artifact = project.artifact;
970
963
  }
971
- if (isViewPackage(packagePath)) {
972
- const rootId = viewRootId(packagePath, file);
973
- return [
974
- `import { createSwiftView } from 'rnxsim/swift'`,
975
- `export default createSwiftView({ url: ${JSON.stringify(artifactUrl(project, artifact))}, hash: ${JSON.stringify(artifact.hash)}, rootId: ${JSON.stringify(rootId)} })`,
976
- ""
977
- ].join("\n");
978
- }
979
964
  return [
980
- `import { createSwiftModule } from 'rnxsim/swift'`,
981
- `export default createSwiftModule({ url: ${JSON.stringify(artifactUrl(project, artifact))}, hash: ${JSON.stringify(artifact.hash)} })`,
965
+ `import { createSwiftEntry } from 'rnxsim/swift'`,
966
+ `export default createSwiftEntry({ url: ${JSON.stringify(artifactUrl(project, artifact))}, hash: ${JSON.stringify(artifact.hash)}, rootId: ${JSON.stringify(entryRootId(packagePath, file))} })`,
982
967
  ""
983
968
  ].join("\n");
984
969
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rnxsim",
3
- "version": "0.1.522",
3
+ "version": "0.1.523",
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",
package/src/swift.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  // the runtime the `.swift` vite transform emits its module against. the
2
2
  // implementation lives beside the toolchain it drives, in sootsim-swift.
3
3
  export {
4
- createSwiftModule,
5
- createSwiftView,
4
+ createSwiftEntry,
5
+ type SwiftEntryOptions,
6
6
  type SwiftModuleOptions,
7
- type SwiftViewOptions,
8
7
  } from '../../sootsim-swift/src/mount.tsx'
@@ -7,7 +7,7 @@
7
7
  // artifact. both share the build below, so the artifact is compiled once.
8
8
  //
9
9
  // the hash is the hash of the built wasm, so a new hash means a genuinely
10
- // different app: createSwiftModule moves the @State store across it instead of
10
+ // different app: createSwiftEntry moves the @State store across it instead of
11
11
  // remounting.
12
12
 
13
13
  import { execFile } from 'node:child_process'
@@ -108,8 +108,12 @@ export function linkedModuleRoots(packagePath: string): string[] {
108
108
  // the stamp covers the project plus the modules it links: a running dev
109
109
  // server rebuilds only when this moves, so leaving the linked sources out
110
110
  // would keep serving the artifact built before a SwiftUI module edit for as
111
- // long as the project's own sources stayed the same. mirrors the compile
112
- // service's artifact hash, which names the same closure.
111
+ // long as the project's own sources stayed the same. it names the same
112
+ // closure the compile service's artifact hash names, but it is not the same
113
+ // function: the stamp hashes mtimes, which is the cheap rebuild signal for a
114
+ // watcher, while the artifact address hashes content, which is what stays
115
+ // stable when a checkout restores byte-identical files. a restore rebuilds
116
+ // here and reuses the stored artifact there, by design.
113
117
  export function sourceStamp(packagePath: string): string {
114
118
  const hash = createHash('sha256')
115
119
  for (const root of [packagePath, ...linkedModuleRoots(packagePath)]) {
@@ -122,11 +126,15 @@ export function sourceStamp(packagePath: string): string {
122
126
  return hash.digest('hex').slice(0, 16)
123
127
  }
124
128
 
125
- // the registry slot for a view: the owning package plus the source within
126
- // it. two packages in one app can hold the same filename, and a bare
127
- // relative path would share one slot, one instance, and its state.
128
- export function viewRootId(packagePath: string, file: string): string {
129
- return path.join(packagePath, path.relative(packagePath, file))
129
+ // the registry slot for an entry: the owning package's own name plus the
130
+ // source within it. two packages in one app can hold the same filename, and
131
+ // a bare relative path would share one slot, one instance, and its state.
132
+ // the name travels instead of the path so identical source in two checkouts
133
+ // emits the identical module; two same-named packages sharing one app still
134
+ // collide, and take the rootId override for that.
135
+ export function entryRootId(packagePath: string, file: string): string {
136
+ const relative = path.relative(packagePath, file).split(path.sep).join(path.posix.sep)
137
+ return `${path.basename(packagePath)}${path.posix.sep}${relative}`
130
138
  }
131
139
 
132
140
  // the app fetches the artifact from a worker whose origin is the shell, so the
@@ -261,20 +269,6 @@ function packageFor(file: string): string {
261
269
  )
262
270
  }
263
271
 
264
- // whether the package mounts as a view: its @main type conforms to
265
- // RNXPackage instead of to App. the symbol graph is the exact read once the
266
- // transform emits one; until then the conformance on the @main declaration is
267
- // unambiguous, comments aside.
268
- function isViewPackage(packagePath: string): boolean {
269
- const main =
270
- /@main\s+(?:\w+\s+)*(?:struct|class|enum|actor)\s+\w+[^{]*:\s*[^{]*\bRNXPackage\b/
271
- for (const file of sourceFiles(packagePath)) {
272
- const text = fs.readFileSync(file, 'utf8').replace(/^\s*\/\/.*$/gm, '')
273
- if (main.test(text)) return true
274
- }
275
- return false
276
- }
277
-
278
272
  export interface SwiftPluginOptions {
279
273
  // swiftpm package that owns the project's .swift sources. defaults to the
280
274
  // nearest Package.swift above each imported file, which is the vite root
@@ -338,21 +332,13 @@ export function swiftPlugin(options: SwiftPluginOptions = {}): Plugin {
338
332
  this.warn(error instanceof Error ? error.message : String(error))
339
333
  artifact = project.artifact
340
334
  }
341
- // a view package mounts into its importer: the default export is the
342
- // view component, rooted by its package and source path so a hot reload
343
- // finds the same instance. an app package keeps the root component it
344
- // always had.
345
- if (isViewPackage(packagePath)) {
346
- const rootId = viewRootId(packagePath, file)
347
- return [
348
- `import { createSwiftView } from 'rnxsim/swift'`,
349
- `export default createSwiftView({ url: ${JSON.stringify(artifactUrl(project, artifact))}, hash: ${JSON.stringify(artifact.hash)}, rootId: ${JSON.stringify(rootId)} })`,
350
- '',
351
- ].join('\n')
352
- }
335
+ // every import mounts through the one entry: the artifact answers
336
+ // whether it is a view or an app root at runtime, so the transform
337
+ // never re-derives the conformance from source. the entry is rooted by
338
+ // its package and source path so a hot reload finds the same instance.
353
339
  return [
354
- `import { createSwiftModule } from 'rnxsim/swift'`,
355
- `export default createSwiftModule({ url: ${JSON.stringify(artifactUrl(project, artifact))}, hash: ${JSON.stringify(artifact.hash)} })`,
340
+ `import { createSwiftEntry } from 'rnxsim/swift'`,
341
+ `export default createSwiftEntry({ url: ${JSON.stringify(artifactUrl(project, artifact))}, hash: ${JSON.stringify(artifact.hash)}, rootId: ${JSON.stringify(entryRootId(packagePath, file))} })`,
356
342
  '',
357
343
  ].join('\n')
358
344
  },