rnxsim 0.1.474 → 0.1.476

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 (55) hide show
  1. package/detox/index.ts +22 -4
  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 +27 -10
  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 +3 -35
  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 +33 -57
  52. package/dist-lib/vite.cjs +1 -1
  53. package/package.json +1 -1
  54. package/src/host/bridge-host.ts +4 -32
  55. package/src/vite-plugin.ts +13 -3
package/detox/index.ts CHANGED
@@ -519,8 +519,10 @@ async function getDefaultTapPoint(
519
519
  width: nodeInfo.layout?.width ?? 0,
520
520
  height: nodeInfo.layout?.height ?? 0,
521
521
  }
522
+ const viewport = await readSootsimInteractiveViewport(page)
522
523
  const fullFrameTolerance = 0.5
523
- const fullyVisible =
524
+ // the resolved center may belong to a descendant of the matched frame.
525
+ const canTapCenter =
524
526
  typeof nodeInfo.absolutePosition?.x === 'number' &&
525
527
  typeof nodeInfo.absolutePosition?.y === 'number' &&
526
528
  typeof nodeInfo.layout?.width === 'number' &&
@@ -528,10 +530,13 @@ async function getDefaultTapPoint(
528
530
  Math.abs(frame.x - nodeInfo.absolutePosition.x) <= fullFrameTolerance &&
529
531
  Math.abs(frame.y - nodeInfo.absolutePosition.y) <= fullFrameTolerance &&
530
532
  frame.width >= nodeInfo.layout.width - fullFrameTolerance &&
531
- frame.height >= nodeInfo.layout.height - fullFrameTolerance
532
- if (fullyVisible) return center
533
+ frame.height >= nodeInfo.layout.height - fullFrameTolerance &&
534
+ center.x >= 0 &&
535
+ center.y >= 0 &&
536
+ center.x < viewport.width &&
537
+ center.y < viewport.height
538
+ if (canTapCenter) return center
533
539
 
534
- const viewport = await readSootsimInteractiveViewport(page)
535
540
  const left = Math.max(0, frame.x)
536
541
  const top = Math.max(0, frame.y)
537
542
  const right = Math.min(viewport.width, frame.x + frame.width)
@@ -1556,6 +1561,7 @@ export const device = {
1556
1561
  // between, because no lockstep frame steps while it runs.
1557
1562
  hold?: { durationMs: number; x: number; y: number } | null
1558
1563
  rootFrame?: { height: number; width: number; x: number; y: number } | null
1564
+ settleMs?: number
1559
1565
  trigger?: () => unknown
1560
1566
  },
1561
1567
  ): Promise<{
@@ -1584,6 +1590,10 @@ export const device = {
1584
1590
  }> {
1585
1591
  const page = getPage()
1586
1592
  const token = `motion-${process.pid}-${Date.now()}-${Math.random()}`
1593
+ const settleMs = options.settleMs ?? 0
1594
+ if (!Number.isFinite(settleMs) || settleMs < 0) {
1595
+ throw new Error('rnx motion capture needs a non-negative settleMs')
1596
+ }
1587
1597
  await page.evaluate(measureMotionChange, {
1588
1598
  definition: MOTION_CHANGE_DEFINITION,
1589
1599
  installGlobal: true,
@@ -1854,6 +1864,13 @@ export const device = {
1854
1864
  virtualTimestampMs: receipt.virtualTimestampMs,
1855
1865
  })
1856
1866
  }
1867
+ if (input.settleMs > 0) {
1868
+ const maximumOffsetMs = input.stages.reduce(
1869
+ (maximum, stage) => Math.max(maximum, stage.offsetMs),
1870
+ 0,
1871
+ )
1872
+ await controller.stepToOffset(visibleStart, maximumOffsetMs + input.settleMs)
1873
+ }
1857
1874
  return {
1858
1875
  frames: snapshots.map(encode),
1859
1876
  visibleChangeDetection: {
@@ -1878,6 +1895,7 @@ export const device = {
1878
1895
  hold: options.hold ?? null,
1879
1896
  motionChangeDefinition: MOTION_CHANGE_DEFINITION,
1880
1897
  rootFrame: options.rootFrame ?? null,
1898
+ settleMs,
1881
1899
  stages,
1882
1900
  token,
1883
1901
  },
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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;
@@ -709,7 +709,7 @@ function softwareChromeLaunchOptions(opts) {
709
709
  }
710
710
  const callerArgs = Array.isArray(opts.args) ? opts.args.map(String) : [];
711
711
  const unmanagedCallerArgs = callerArgs.filter((arg) => {
712
- return !arg.startsWith("--use-angle=") && arg !== "--enable-gpu" && arg !== "--enable-gpu-rasterization" && arg !== "--enable-zero-copy" && arg !== "--ignore-gpu-blocklist" && arg !== "--disable-gpu-watchdog" && !/^--enable-unsafe-webgpu(?:=.*)?$/i.test(arg) && !/^--enable-unsafe-swiftshader(?:=.*)?$/i.test(arg);
712
+ return !arg.startsWith("--use-angle=") && arg !== "--enable-gpu" && arg !== "--enable-gpu-rasterization" && arg !== "--enable-zero-copy" && arg !== "--ignore-gpu-blocklist" && arg !== "--disable-gpu-watchdog" && arg !== "--enable-skia-graphite" && !/^--enable-unsafe-webgpu(?:=.*)?$/i.test(arg) && !/^--enable-unsafe-swiftshader(?:=.*)?$/i.test(arg);
713
713
  });
714
714
  const software = {
715
715
  ...opts,
@@ -723,12 +723,17 @@ function softwareChromeLaunchOptions(opts) {
723
723
  "--use-angle=swiftshader",
724
724
  "--enable-unsafe-swiftshader",
725
725
  "--enable-unsafe-webgpu",
726
+ // without Skia Graphite as chromium's own compositor, SwiftShader has no
727
+ // shared-image backing for a WebGPU canvas swap chain at any size: the
728
+ // first configured canvas fails "Could not find SharedImageBackingFactory"
729
+ // and chromium destroys the device mid-capture. compute-only WebGPU
730
+ // still works, so an adapter probe cannot see this.
731
+ "--enable-skia-graphite",
726
732
  // the GPU watchdog kills the GPU process when a task outlives its
727
- // timeout. SwiftShader precompiling Graphite pipelines on two CPU cores
728
- // legitimately outlives it, and the compositor then fails with "graphite
729
- // device was lost while precompiling pipelines" although nothing hung.
730
- // the cost: a genuinely wedged GPU process now holds its job until the
731
- // job's own timeout instead of dying fast.
733
+ // timeout, and SwiftShader precompiling Graphite pipelines on two CPU
734
+ // cores can legitimately outlive it. the cost: a genuinely wedged GPU
735
+ // process now holds its job until the job's own timeout instead of
736
+ // dying fast.
732
737
  "--disable-gpu-watchdog"
733
738
  ],
734
739
  ["Vulkan"]
@@ -2170,10 +2175,10 @@ async function getDefaultTapPoint(page, nodeInfo) {
2170
2175
  width: nodeInfo.layout?.width ?? 0,
2171
2176
  height: nodeInfo.layout?.height ?? 0
2172
2177
  };
2173
- const fullFrameTolerance = 0.5;
2174
- const fullyVisible = typeof nodeInfo.absolutePosition?.x === "number" && typeof nodeInfo.absolutePosition?.y === "number" && typeof nodeInfo.layout?.width === "number" && typeof nodeInfo.layout?.height === "number" && Math.abs(frame.x - nodeInfo.absolutePosition.x) <= fullFrameTolerance && Math.abs(frame.y - nodeInfo.absolutePosition.y) <= fullFrameTolerance && frame.width >= nodeInfo.layout.width - fullFrameTolerance && frame.height >= nodeInfo.layout.height - fullFrameTolerance;
2175
- if (fullyVisible) return center;
2176
2178
  const viewport = await readSootsimInteractiveViewport(page);
2179
+ const fullFrameTolerance = 0.5;
2180
+ const canTapCenter = typeof nodeInfo.absolutePosition?.x === "number" && typeof nodeInfo.absolutePosition?.y === "number" && typeof nodeInfo.layout?.width === "number" && typeof nodeInfo.layout?.height === "number" && Math.abs(frame.x - nodeInfo.absolutePosition.x) <= fullFrameTolerance && Math.abs(frame.y - nodeInfo.absolutePosition.y) <= fullFrameTolerance && frame.width >= nodeInfo.layout.width - fullFrameTolerance && frame.height >= nodeInfo.layout.height - fullFrameTolerance && center.x >= 0 && center.y >= 0 && center.x < viewport.width && center.y < viewport.height;
2181
+ if (canTapCenter) return center;
2177
2182
  const left = Math.max(0, frame.x);
2178
2183
  const top = Math.max(0, frame.y);
2179
2184
  const right = Math.min(viewport.width, frame.x + frame.width);
@@ -2907,6 +2912,10 @@ var device = {
2907
2912
  async takeScreenshotStagesFromVisibleChangeFast(namePrefix, stages, options) {
2908
2913
  const page = getPage();
2909
2914
  const token = `motion-${process.pid}-${Date.now()}-${Math.random()}`;
2915
+ const settleMs = options.settleMs ?? 0;
2916
+ if (!Number.isFinite(settleMs) || settleMs < 0) {
2917
+ throw new Error("rnx motion capture needs a non-negative settleMs");
2918
+ }
2910
2919
  await page.evaluate(import_motion_change.measureMotionChange, {
2911
2920
  definition: import_motion_change.MOTION_CHANGE_DEFINITION,
2912
2921
  installGlobal: true
@@ -3080,6 +3089,13 @@ var device = {
3080
3089
  virtualTimestampMs: receipt.virtualTimestampMs
3081
3090
  });
3082
3091
  }
3092
+ if (input.settleMs > 0) {
3093
+ const maximumOffsetMs = input.stages.reduce(
3094
+ (maximum, stage) => Math.max(maximum, stage.offsetMs),
3095
+ 0
3096
+ );
3097
+ await controller.stepToOffset(visibleStart, maximumOffsetMs + input.settleMs);
3098
+ }
3083
3099
  return {
3084
3100
  frames: snapshots.map(encode),
3085
3101
  visibleChangeDetection: {
@@ -3104,6 +3120,7 @@ var device = {
3104
3120
  hold: options.hold ?? null,
3105
3121
  motionChangeDefinition: import_motion_change.MOTION_CHANGE_DEFINITION,
3106
3122
  rootFrame: options.rootFrame ?? null,
3123
+ settleMs,
3107
3124
  stages,
3108
3125
  token
3109
3126
  }
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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;
@@ -10252,10 +10252,8 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
10252
10252
  }
10253
10253
  }
10254
10254
  if (httpServer) {
10255
- try {
10256
- httpServer.close();
10257
- } catch {
10258
- }
10255
+ httpServer.closeAllConnections();
10256
+ await new Promise((resolve5) => httpServer.close(() => resolve5()));
10259
10257
  }
10260
10258
  }
10261
10259
  describeSim(sim, viewerIdentityKey) {
@@ -10639,36 +10637,6 @@ var SootSimBridgeHost = class _SootSimBridgeHost {
10639
10637
  }
10640
10638
  }
10641
10639
  }
10642
- resetServerState() {
10643
- if (this.cliIdleTimer) {
10644
- clearInterval(this.cliIdleTimer);
10645
- this.cliIdleTimer = null;
10646
- }
10647
- if (this.wsHeartbeatTimer) {
10648
- clearInterval(this.wsHeartbeatTimer);
10649
- this.wsHeartbeatTimer = null;
10650
- }
10651
- if (this.runtimeUpdateTimer) {
10652
- clearInterval(this.runtimeUpdateTimer);
10653
- this.runtimeUpdateTimer = null;
10654
- }
10655
- const wss = this.wss;
10656
- const httpServer = this.httpServer;
10657
- this.wss = null;
10658
- this.httpServer = null;
10659
- if (wss) {
10660
- try {
10661
- wss.close();
10662
- } catch {
10663
- }
10664
- }
10665
- if (httpServer) {
10666
- try {
10667
- httpServer.close();
10668
- } catch {
10669
- }
10670
- }
10671
- }
10672
10640
  };
10673
10641
  // Annotate the CommonJS export names for ESM import in node:
10674
10642
  0 && (module.exports = {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (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;
@@ -483,7 +483,7 @@ function softwareChromeLaunchOptions(opts) {
483
483
  }
484
484
  const callerArgs = Array.isArray(opts.args) ? opts.args.map(String) : [];
485
485
  const unmanagedCallerArgs = callerArgs.filter((arg) => {
486
- return !arg.startsWith("--use-angle=") && arg !== "--enable-gpu" && arg !== "--enable-gpu-rasterization" && arg !== "--enable-zero-copy" && arg !== "--ignore-gpu-blocklist" && arg !== "--disable-gpu-watchdog" && !/^--enable-unsafe-webgpu(?:=.*)?$/i.test(arg) && !/^--enable-unsafe-swiftshader(?:=.*)?$/i.test(arg);
486
+ return !arg.startsWith("--use-angle=") && arg !== "--enable-gpu" && arg !== "--enable-gpu-rasterization" && arg !== "--enable-zero-copy" && arg !== "--ignore-gpu-blocklist" && arg !== "--disable-gpu-watchdog" && arg !== "--enable-skia-graphite" && !/^--enable-unsafe-webgpu(?:=.*)?$/i.test(arg) && !/^--enable-unsafe-swiftshader(?:=.*)?$/i.test(arg);
487
487
  });
488
488
  const software = {
489
489
  ...opts,
@@ -497,12 +497,17 @@ function softwareChromeLaunchOptions(opts) {
497
497
  "--use-angle=swiftshader",
498
498
  "--enable-unsafe-swiftshader",
499
499
  "--enable-unsafe-webgpu",
500
+ // without Skia Graphite as chromium's own compositor, SwiftShader has no
501
+ // shared-image backing for a WebGPU canvas swap chain at any size: the
502
+ // first configured canvas fails "Could not find SharedImageBackingFactory"
503
+ // and chromium destroys the device mid-capture. compute-only WebGPU
504
+ // still works, so an adapter probe cannot see this.
505
+ "--enable-skia-graphite",
500
506
  // the GPU watchdog kills the GPU process when a task outlives its
501
- // timeout. SwiftShader precompiling Graphite pipelines on two CPU cores
502
- // legitimately outlives it, and the compositor then fails with "graphite
503
- // device was lost while precompiling pipelines" although nothing hung.
504
- // the cost: a genuinely wedged GPU process now holds its job until the
505
- // job's own timeout instead of dying fast.
507
+ // timeout, and SwiftShader precompiling Graphite pipelines on two CPU
508
+ // cores can legitimately outlive it. the cost: a genuinely wedged GPU
509
+ // process now holds its job until the job's own timeout instead of
510
+ // dying fast.
506
511
  "--disable-gpu-watchdog"
507
512
  ],
508
513
  ["Vulkan"]
@@ -4447,13 +4452,13 @@ var init_capability_outcomes2 = __esm({
4447
4452
  assessed: 0
4448
4453
  },
4449
4454
  ios: {
4450
- passedWeight: 0,
4455
+ passedWeight: 27,
4451
4456
  failedWeight: 0,
4452
- unassessedWeight: 115,
4457
+ unassessedWeight: 88,
4453
4458
  totalWeight: 115,
4454
- assessedWeight: 0,
4455
- compatibility: null,
4456
- assessed: 0
4459
+ assessedWeight: 27,
4460
+ compatibility: 1,
4461
+ assessed: 0.23478260869565218
4457
4462
  }
4458
4463
  },
4459
4464
  usage: {
@@ -4467,18 +4472,21 @@ var init_capability_outcomes2 = __esm({
4467
4472
  assessed: 0
4468
4473
  },
4469
4474
  ios: {
4470
- passedWeight: 0,
4475
+ passedWeight: 691,
4471
4476
  failedWeight: 0,
4472
- unassessedWeight: 5540,
4477
+ unassessedWeight: 4849,
4473
4478
  totalWeight: 5540,
4474
- assessedWeight: 0,
4475
- compatibility: null,
4476
- assessed: 0
4479
+ assessedWeight: 691,
4480
+ compatibility: 1,
4481
+ assessed: 0.12472924187725631
4477
4482
  }
4478
4483
  }
4479
4484
  },
4480
4485
  capturedAt: "2026-09-08T05:40:18.932Z",
4481
- receipts: ["retained-essentials-react-native-svg-r22458-20260908"],
4486
+ receipts: [
4487
+ "retained-essentials-react-native-svg-r22458-20260908",
4488
+ "svg-geometry-2026-09-09-p40993-r2"
4489
+ ],
4482
4490
  sourceCommit: "ea3eb82eeea6f6925ae708b7028cb577ad37f36a"
4483
4491
  },
4484
4492
  unmatchedReferenceCount: 4459,
@@ -6069,14 +6077,14 @@ var init_registry = __esm({
6069
6077
  id: "filters-and-imperative-geometry",
6070
6078
  usage: 1,
6071
6079
  importance: 2,
6072
- estimate: 0.25,
6073
- rationale: "getTotalLength and getPointAtLength implement path metrics for paths and basic shapes, including curves, arcs, clamping and detached refs. This receives 25% of the grouped feature. Filters, native export, bounding boxes, matrices and point-in-fill/stroke remain unsupported; invalid-path points return zero where native returns NaN."
6080
+ estimate: 0.45,
6081
+ rationale: "getTotalLength, getPointAtLength, getBBox with its fill, stroke, markers and clipped options, getCTM, getScreenCTM, isPointInFill and isPointInStroke match 66 iOS-pinned calls within 1e-4 in a paired capture, covering curves, arcs, rounded-rect clamping, native stroke outlines and miter limits, clip bounds, invalid-path NaN points and detached refs. Native filters and toDataURL export remain unsupported, estimated as 55% of the grouped feature."
6074
6082
  }
6075
6083
  ],
6076
6084
  capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native-svg"],
6077
- note: "CanvasKit rendering for shapes, text, XML, gradients, references, masks, clipping, and images; path metrics are implemented; native SVG filters, export and other geometry queries remain unsupported",
6078
- working: "Svg, Path, Circle, Rect, Line, Ellipse, Polygon, Polyline, G, Text, TSpan, TextPath shaped glyphs along referenced paths, Defs, Pattern fills, Marker geometry on paths/lines/polylines/polygons, LinearGradient and RadialGradient with objectBoundingBox/userSpaceOnUse coordinates, focal points and gradientTransform, Stop, Mask, ClipPath, Image, Use and Symbol references, SvgXml, SvgUri, SvgAst, SvgFromXml, SvgCss, parse, fetchText, camelCase, getTotalLength and getPointAtLength for Path, Line, Rect including rounded corners, Circle, Ellipse, Polygon and Polyline, shape transforms, fill/stroke/opacity/dasharray, currentColor, viewBox scaling",
6079
- missing: "native SVG filter components and toDataURL, hit-testing, bounding-box, and matrix methods refuse calls; invalid-path points differ from native NaN; ForeignObject does not render; marker context paints remain unverified; TextPath advanced layout, per-glyph positioning and objectBoundingBox paints are unsupported; pattern non-scaling strokes use the tile matrix; no font or emoji fallback parity claim"
6085
+ note: "CanvasKit rendering for shapes, text, XML, gradients, references, masks, clipping, and images; path metrics, bounding boxes, matrices and point-in-fill/stroke queries match native; native SVG filters and export remain unsupported",
6086
+ working: "Svg, Path, Circle, Rect, Line, Ellipse, Polygon, Polyline, G, Text, TSpan, TextPath shaped glyphs along referenced paths, Defs, Pattern fills, Marker geometry on paths/lines/polylines/polygons, LinearGradient and RadialGradient with objectBoundingBox/userSpaceOnUse coordinates, focal points and gradientTransform, Stop, Mask, ClipPath, Image, Use and Symbol references, SvgXml, SvgUri, SvgAst, SvgFromXml, SvgCss, parse, fetchText, camelCase, getTotalLength and getPointAtLength for Path, Line, Rect including rounded corners, Circle, Ellipse, Polygon and Polyline, getBBox, getCTM, getScreenCTM, isPointInFill, isPointInStroke, shape transforms, fill/stroke/opacity/dasharray, currentColor, viewBox scaling",
6087
+ missing: "native SVG filter components and toDataURL refuse calls; ForeignObject does not render; marker context paints remain unverified; TextPath advanced layout, per-glyph positioning and objectBoundingBox paints are unsupported; pattern non-scaling strokes use the tile matrix; no font or emoji fallback parity claim"
6080
6088
  }
6081
6089
  ]
6082
6090
  },
@@ -30150,10 +30158,8 @@ var init_bridge_host = __esm({
30150
30158
  }
30151
30159
  }
30152
30160
  if (httpServer) {
30153
- try {
30154
- httpServer.close();
30155
- } catch {
30156
- }
30161
+ httpServer.closeAllConnections();
30162
+ await new Promise((resolve9) => httpServer.close(() => resolve9()));
30157
30163
  }
30158
30164
  }
30159
30165
  describeSim(sim, viewerIdentityKey) {
@@ -30537,36 +30543,6 @@ var init_bridge_host = __esm({
30537
30543
  }
30538
30544
  }
30539
30545
  }
30540
- resetServerState() {
30541
- if (this.cliIdleTimer) {
30542
- clearInterval(this.cliIdleTimer);
30543
- this.cliIdleTimer = null;
30544
- }
30545
- if (this.wsHeartbeatTimer) {
30546
- clearInterval(this.wsHeartbeatTimer);
30547
- this.wsHeartbeatTimer = null;
30548
- }
30549
- if (this.runtimeUpdateTimer) {
30550
- clearInterval(this.runtimeUpdateTimer);
30551
- this.runtimeUpdateTimer = null;
30552
- }
30553
- const wss = this.wss;
30554
- const httpServer = this.httpServer;
30555
- this.wss = null;
30556
- this.httpServer = null;
30557
- if (wss) {
30558
- try {
30559
- wss.close();
30560
- } catch {
30561
- }
30562
- }
30563
- if (httpServer) {
30564
- try {
30565
- httpServer.close();
30566
- } catch {
30567
- }
30568
- }
30569
- }
30570
30546
  };
30571
30547
  }
30572
30548
  });
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.474 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.476 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rnxsim",
3
- "version": "0.1.474",
3
+ "version": "0.1.476",
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",
@@ -2303,10 +2303,11 @@ export class SootSimBridgeHost {
2303
2303
  wss.close()
2304
2304
  } catch {}
2305
2305
  }
2306
+ // resolve only once the port is actually released, so a caller awaiting
2307
+ // close() can rebind or assert on it without polling.
2306
2308
  if (httpServer) {
2307
- try {
2308
- httpServer.close()
2309
- } catch {}
2309
+ httpServer.closeAllConnections()
2310
+ await new Promise<void>((resolve) => httpServer.close(() => resolve()))
2310
2311
  }
2311
2312
  }
2312
2313
 
@@ -2784,33 +2785,4 @@ export class SootSimBridgeHost {
2784
2785
  }
2785
2786
  }
2786
2787
  }
2787
-
2788
- private resetServerState() {
2789
- if (this.cliIdleTimer) {
2790
- clearInterval(this.cliIdleTimer)
2791
- this.cliIdleTimer = null
2792
- }
2793
- if (this.wsHeartbeatTimer) {
2794
- clearInterval(this.wsHeartbeatTimer)
2795
- this.wsHeartbeatTimer = null
2796
- }
2797
- if (this.runtimeUpdateTimer) {
2798
- clearInterval(this.runtimeUpdateTimer)
2799
- this.runtimeUpdateTimer = null
2800
- }
2801
- const wss = this.wss
2802
- const httpServer = this.httpServer
2803
- this.wss = null
2804
- this.httpServer = null
2805
- if (wss) {
2806
- try {
2807
- wss.close()
2808
- } catch {}
2809
- }
2810
- if (httpServer) {
2811
- try {
2812
- httpServer.close()
2813
- } catch {}
2814
- }
2815
- }
2816
2788
  }
@@ -842,9 +842,18 @@ export function wsBridgePlugin(options: { ownedBridgePort?: number } = {}): Plug
842
842
  options.ownedBridgePort === undefined
843
843
  ? null
844
844
  : Promise.resolve(options.ownedBridgePort)
845
+ // vite runs closeBundle inside server.close(), so awaiting the bridge here
846
+ // makes the port released by the time server.close() resolves. the http
847
+ // 'close' event is not a substitute: after a failed restart vite swaps in a
848
+ // replacement server that never listened, and closing it emits no 'close',
849
+ // which leaked the bridge for the life of the process.
850
+ let releaseBridge: (() => Promise<void>) | null = null
845
851
  return {
846
852
  name: 'sootsim-ws-bridge',
847
853
  apply: 'serve',
854
+ async closeBundle() {
855
+ await releaseBridge?.()
856
+ },
848
857
  configureServer(server) {
849
858
  if (!boundPort) {
850
859
  const preferredPort = resolveSootsimBridgePort({
@@ -898,12 +907,13 @@ export function wsBridgePlugin(options: { ownedBridgePort?: number } = {}): Plug
898
907
  viteBridgeProcesses.set(preferredPort, entry)
899
908
  }
900
909
 
901
- server.httpServer?.once('close', () => {
910
+ releaseBridge = async () => {
911
+ releaseBridge = null
902
912
  const entry = viteBridgeProcesses.get(preferredPort)
903
913
  if (!entry || !entry.owners.delete(owner) || entry.owners.size > 0) return
904
914
  viteBridgeProcesses.delete(preferredPort)
905
- void entry.close()
906
- })
915
+ await entry.close()
916
+ }
907
917
  }
908
918
 
909
919
  if (!boundPort) throw new Error('rnx bridge identity was not initialized')