rnxsim 0.1.443 → 0.1.445

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 (61) hide show
  1. package/cli/auth.ts +2 -2
  2. package/cli/cloud-client.ts +13 -13
  3. package/cli/cloud-session.ts +1 -1
  4. package/cli/outbound-endpoints.ts +2 -0
  5. package/cli/send-to-box.ts +7 -7
  6. package/detox/jest-setup-after-env.cjs +4 -0
  7. package/detox/record-block-execution.cjs +78 -0
  8. package/dist-lib/agent-daemon-client.cjs +1 -1
  9. package/dist-lib/agent-events.cjs +1 -1
  10. package/dist-lib/agent-identity.cjs +1 -1
  11. package/dist-lib/agent-sessions.cjs +1 -1
  12. package/dist-lib/attached-projects.cjs +1 -1
  13. package/dist-lib/auth/shared-session.cjs +1 -1
  14. package/dist-lib/backend-origin.cjs +1 -1
  15. package/dist-lib/beta.cjs +1 -1
  16. package/dist-lib/beta.mjs +1 -1
  17. package/dist-lib/bridge-constants.cjs +1 -1
  18. package/dist-lib/bridge-contract-input.cjs +1 -1
  19. package/dist-lib/bridge-contract-input.mjs +1 -1
  20. package/dist-lib/bridge-contract.cjs +1 -1
  21. package/dist-lib/bridge-contract.mjs +1 -1
  22. package/dist-lib/capture-contract.cjs +1 -1
  23. package/dist-lib/capture-contract.mjs +1 -1
  24. package/dist-lib/cli-constants.cjs +1 -1
  25. package/dist-lib/cloud-contract.cjs +1 -1
  26. package/dist-lib/cloud-contract.mjs +1 -1
  27. package/dist-lib/cloud.cjs +1 -1
  28. package/dist-lib/cloud.mjs +1 -1
  29. package/dist-lib/config.cjs +1 -1
  30. package/dist-lib/detox/index.cjs +1 -1
  31. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  32. package/dist-lib/home-paths.cjs +1 -1
  33. package/dist-lib/host/bridge-host.cjs +197 -197
  34. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  35. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  36. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  37. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  38. package/dist-lib/host/websocket-proxy.cjs +1 -1
  39. package/dist-lib/index.cjs +4 -4
  40. package/dist-lib/jump-to-source-babel.cjs +1 -1
  41. package/dist-lib/menu.cjs +5 -1
  42. package/dist-lib/menu.mjs +5 -1
  43. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  44. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  45. package/dist-lib/metro-production-bundle.cjs +1 -1
  46. package/dist-lib/metro-production-bundle.mjs +1 -1
  47. package/dist-lib/metro.cjs +1 -1
  48. package/dist-lib/profiles.cjs +1 -1
  49. package/dist-lib/public-brand.cjs +1 -1
  50. package/dist-lib/react-native-host-modules.cjs +1 -1
  51. package/dist-lib/react-native-host-modules.mjs +1 -1
  52. package/dist-lib/render-mode.cjs +1 -1
  53. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  54. package/dist-lib/sdk.cjs +1 -1
  55. package/dist-lib/sdk.mjs +1 -1
  56. package/dist-lib/skills.cjs +491 -253
  57. package/dist-lib/vite.cjs +1 -1
  58. package/package.json +1 -1
  59. package/src/auth/shared-session.ts +1 -1
  60. package/src/cloud-contract.ts +1 -1
  61. package/src/menu.ts +4 -0
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.443 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.445 | (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;
@@ -546,11 +546,58 @@ var init_reap_browser = __esm({
546
546
  }
547
547
  });
548
548
 
549
+ // ../compat/src/capability-outcomes.ts
550
+ function aggregateCompatibilityOutcomes(contributions) {
551
+ let total = 0;
552
+ let passing = 0;
553
+ let assessed = 0;
554
+ let estimated = 0;
555
+ let hasMeasured = false;
556
+ let hasEstimated = false;
557
+ for (const entry of contributions) {
558
+ if (!Number.isFinite(entry.weight) || entry.weight < 0)
559
+ throw new Error("invalid package weight");
560
+ total += entry.weight;
561
+ if (entry.source === "measured") {
562
+ hasMeasured = true;
563
+ if (!entry.assessment) throw new Error("measured contribution requires assessment");
564
+ const measure = entry.assessment;
565
+ if (measure.totalWeight > 0) {
566
+ passing += entry.weight * measure.passedWeight / measure.totalWeight;
567
+ assessed += entry.weight * measure.assessedWeight / measure.totalWeight;
568
+ }
569
+ } else if (entry.source === "estimated") {
570
+ hasEstimated = true;
571
+ if (entry.estimate !== null) {
572
+ if (!Number.isFinite(entry.estimate) || entry.estimate < 0 || entry.estimate > 1)
573
+ throw new Error("invalid compatibility estimate");
574
+ passing += entry.weight * entry.estimate;
575
+ estimated += entry.weight;
576
+ }
577
+ }
578
+ }
579
+ return {
580
+ compatibility: assessed + estimated === 0 ? null : passing / (assessed + estimated),
581
+ assessed: total === 0 ? 0 : assessed / total,
582
+ estimated: total === 0 ? 0 : estimated / total,
583
+ source: hasMeasured && hasEstimated ? "mixed" : hasEstimated ? "estimated" : "measured"
584
+ };
585
+ }
586
+ function formatCompatibilityPercent(percent) {
587
+ return percent > 0 && percent < 0.1 ? "<0.1" : String(Number(percent.toFixed(1)));
588
+ }
589
+ var init_capability_outcomes = __esm({
590
+ "../compat/src/capability-outcomes.ts"() {
591
+ "use strict";
592
+ }
593
+ });
594
+
549
595
  // ../compat/src/native-evidence.ts
550
596
  var UNKNOWN_RNX_SUPPORT;
551
597
  var init_native_evidence = __esm({
552
598
  "../compat/src/native-evidence.ts"() {
553
599
  "use strict";
600
+ init_capability_outcomes();
554
601
  UNKNOWN_RNX_SUPPORT = {
555
602
  level: "unknown",
556
603
  coverage: null,
@@ -570,25 +617,25 @@ var init_capability_inventory_coverage = __esm({
570
617
  "react-native": {
571
618
  combined: {
572
619
  raw: {
573
- covered: 0,
574
- ratio: 0,
620
+ covered: 7,
621
+ ratio: 0.00444162436548,
575
622
  total: 1576
576
623
  },
577
624
  weighted: {
578
- covered: 0,
579
- ratio: 0,
625
+ covered: 0.00692770149447,
626
+ ratio: 0.00140695129709,
580
627
  total: 4.92390995252
581
628
  }
582
629
  },
583
630
  semantic: {
584
631
  raw: {
585
- covered: 0,
586
- ratio: 0,
632
+ covered: 7,
633
+ ratio: 0.00623330365093,
587
634
  total: 1123
588
635
  },
589
636
  weighted: {
590
- covered: 0,
591
- ratio: 0,
637
+ covered: 0.00692770149447,
638
+ ratio: 0.00274128218603,
592
639
  total: 2.52717561504
593
640
  }
594
641
  },
@@ -646,25 +693,25 @@ var init_capability_inventory_coverage = __esm({
646
693
  ios: {
647
694
  combined: {
648
695
  raw: {
649
- covered: 0,
650
- ratio: 0,
696
+ covered: 213,
697
+ ratio: 0.153127246585,
651
698
  total: 1391
652
699
  },
653
700
  weighted: {
654
- covered: 0,
655
- ratio: 0,
701
+ covered: 1.38498343762,
702
+ ratio: 0.289659691768,
656
703
  total: 4.78141583721
657
704
  }
658
705
  },
659
706
  semantic: {
660
707
  raw: {
661
- covered: 0,
662
- ratio: 0,
708
+ covered: 213,
709
+ ratio: 0.213855421687,
663
710
  total: 996
664
711
  },
665
712
  weighted: {
666
- covered: 0,
667
- ratio: 0,
713
+ covered: 1.38498343762,
714
+ ratio: 0.578085386368,
668
715
  total: 2.39581119032
669
716
  }
670
717
  },
@@ -1267,12 +1314,165 @@ var init_capability_inventory_coverage = __esm({
1267
1314
  }
1268
1315
  });
1269
1316
 
1317
+ // ../compat/src/generated/capability-outcomes.ts
1318
+ var CAPABILITY_PACKAGE_OUTCOMES;
1319
+ var init_capability_outcomes2 = __esm({
1320
+ "../compat/src/generated/capability-outcomes.ts"() {
1321
+ "use strict";
1322
+ CAPABILITY_PACKAGE_OUTCOMES = {
1323
+ "react-native": {
1324
+ exactTestedVersion: "0.86.2",
1325
+ supportedVersionRange: "0.86.x",
1326
+ byPlatform: {
1327
+ android: {
1328
+ passedWeight: 0,
1329
+ failedWeight: 0,
1330
+ unassessedWeight: 0.9703987341344257,
1331
+ totalWeight: 0.9703987341344257,
1332
+ assessedWeight: 0,
1333
+ compatibility: null,
1334
+ assessed: 0
1335
+ },
1336
+ ios: {
1337
+ passedWeight: 0,
1338
+ failedWeight: 0,
1339
+ unassessedWeight: 0.957145688695477,
1340
+ totalWeight: 0.957145688695477,
1341
+ assessedWeight: 0,
1342
+ compatibility: null,
1343
+ assessed: 0
1344
+ }
1345
+ }
1346
+ },
1347
+ "react-native-gesture-handler": {
1348
+ exactTestedVersion: "2.32.0",
1349
+ supportedVersionRange: ">=2.30.0",
1350
+ byPlatform: {
1351
+ android: {
1352
+ passedWeight: 0,
1353
+ failedWeight: 0,
1354
+ unassessedWeight: 0.9999999999997249,
1355
+ totalWeight: 0.9999999999997249,
1356
+ assessedWeight: 0,
1357
+ compatibility: null,
1358
+ assessed: 0
1359
+ },
1360
+ ios: {
1361
+ passedWeight: 0,
1362
+ failedWeight: 0,
1363
+ unassessedWeight: 0.9999999999997249,
1364
+ totalWeight: 0.9999999999997249,
1365
+ assessedWeight: 0,
1366
+ compatibility: null,
1367
+ assessed: 0
1368
+ }
1369
+ }
1370
+ },
1371
+ "react-native-keyboard-controller": {
1372
+ exactTestedVersion: "1.21.11",
1373
+ supportedVersionRange: ">=1.0.0",
1374
+ byPlatform: {
1375
+ android: {
1376
+ passedWeight: 0,
1377
+ failedWeight: 0,
1378
+ unassessedWeight: 0.9999999999999856,
1379
+ totalWeight: 0.9999999999999856,
1380
+ assessedWeight: 0,
1381
+ compatibility: null,
1382
+ assessed: 0
1383
+ },
1384
+ ios: {
1385
+ passedWeight: 0,
1386
+ failedWeight: 0,
1387
+ unassessedWeight: 0.9999999999999856,
1388
+ totalWeight: 0.9999999999999856,
1389
+ assessedWeight: 0,
1390
+ compatibility: null,
1391
+ assessed: 0
1392
+ }
1393
+ }
1394
+ },
1395
+ "react-native-reanimated": {
1396
+ exactTestedVersion: "4.5.1",
1397
+ supportedVersionRange: ">=4.0.0",
1398
+ byPlatform: {
1399
+ android: {
1400
+ passedWeight: 0,
1401
+ failedWeight: 0,
1402
+ unassessedWeight: 0.9999999999999165,
1403
+ totalWeight: 0.9999999999999165,
1404
+ assessedWeight: 0,
1405
+ compatibility: null,
1406
+ assessed: 0
1407
+ },
1408
+ ios: {
1409
+ passedWeight: 0,
1410
+ failedWeight: 0,
1411
+ unassessedWeight: 0.9999999999999165,
1412
+ totalWeight: 0.9999999999999165,
1413
+ assessedWeight: 0,
1414
+ compatibility: null,
1415
+ assessed: 0
1416
+ }
1417
+ }
1418
+ },
1419
+ "react-native-screens": {
1420
+ exactTestedVersion: "4.26.2",
1421
+ supportedVersionRange: ">=4.0.0",
1422
+ byPlatform: {
1423
+ android: {
1424
+ passedWeight: 0,
1425
+ failedWeight: 0,
1426
+ unassessedWeight: 0.9999999999996853,
1427
+ totalWeight: 0.9999999999996853,
1428
+ assessedWeight: 0,
1429
+ compatibility: null,
1430
+ assessed: 0
1431
+ },
1432
+ ios: {
1433
+ passedWeight: 0,
1434
+ failedWeight: 0,
1435
+ unassessedWeight: 0.9999999999996853,
1436
+ totalWeight: 0.9999999999996853,
1437
+ assessedWeight: 0,
1438
+ compatibility: null,
1439
+ assessed: 0
1440
+ }
1441
+ }
1442
+ },
1443
+ "react-native-svg": {
1444
+ exactTestedVersion: "15.15.4",
1445
+ supportedVersionRange: ">=13.0.0",
1446
+ byPlatform: {
1447
+ android: {
1448
+ passedWeight: 0,
1449
+ failedWeight: 0,
1450
+ unassessedWeight: 0.9999999999999477,
1451
+ totalWeight: 0.9999999999999477,
1452
+ assessedWeight: 0,
1453
+ compatibility: null,
1454
+ assessed: 0
1455
+ },
1456
+ ios: {
1457
+ passedWeight: 0,
1458
+ failedWeight: 0,
1459
+ unassessedWeight: 0.9999999999999477,
1460
+ totalWeight: 0.9999999999999477,
1461
+ assessedWeight: 0,
1462
+ compatibility: null,
1463
+ assessed: 0
1464
+ }
1465
+ }
1466
+ }
1467
+ };
1468
+ }
1469
+ });
1470
+
1270
1471
  // ../compat/src/generated/react-native-root-export-coverage.ts
1271
- var REACT_NATIVE_ROOT_EXPORT_WILL_IT_WORK_COVERAGE, REACT_NATIVE_ROOT_EXPORT_STRICT_COVERAGE;
1472
+ var REACT_NATIVE_ROOT_EXPORT_STRICT_COVERAGE;
1272
1473
  var init_react_native_root_export_coverage = __esm({
1273
1474
  "../compat/src/generated/react-native-root-export-coverage.ts"() {
1274
1475
  "use strict";
1275
- REACT_NATIVE_ROOT_EXPORT_WILL_IT_WORK_COVERAGE = 0.99;
1276
1476
  REACT_NATIVE_ROOT_EXPORT_STRICT_COVERAGE = 0.765;
1277
1477
  }
1278
1478
  });
@@ -1440,7 +1640,7 @@ var init_supported_native_packages = __esm({
1440
1640
  "expo-document-picker",
1441
1641
  // preset+coverage
1442
1642
  "expo-file-system",
1443
- // coverage
1643
+ // preset+coverage
1444
1644
  "expo-font",
1445
1645
  // preset+coverage
1446
1646
  "expo-gl",
@@ -1548,7 +1748,7 @@ var init_supported_native_packages = __esm({
1548
1748
  "posthog-react-native-session-replay",
1549
1749
  // preset+coverage
1550
1750
  "react-native",
1551
- // preset+visual-proof+coverage
1751
+ // preset+visual-proof
1552
1752
  "react-native-actions-shortcuts",
1553
1753
  // coverage
1554
1754
  "react-native-adjust",
@@ -1594,7 +1794,7 @@ var init_supported_native_packages = __esm({
1594
1794
  "react-native-fs",
1595
1795
  // coverage
1596
1796
  "react-native-gesture-handler",
1597
- // preset+visual-proof+coverage
1797
+ // preset
1598
1798
  "react-native-get-device-locale",
1599
1799
  // coverage
1600
1800
  "react-native-get-location",
@@ -1672,7 +1872,7 @@ var init_supported_native_packages = __esm({
1672
1872
  "react-native-randombytes",
1673
1873
  // coverage
1674
1874
  "react-native-reanimated",
1675
- // preset+visual-proof+coverage
1875
+ // preset+visual-proof
1676
1876
  "react-native-restart",
1677
1877
  // coverage
1678
1878
  "react-native-restart-newarch",
@@ -1684,7 +1884,7 @@ var init_supported_native_packages = __esm({
1684
1884
  "react-native-screen-corner-radius",
1685
1885
  // coverage
1686
1886
  "react-native-screens",
1687
- // preset+visual-proof+coverage
1887
+ // preset+visual-proof
1688
1888
  "react-native-securerandom",
1689
1889
  // coverage
1690
1890
  "react-native-settings",
@@ -1798,6 +1998,7 @@ var init_registry = __esm({
1798
1998
  "../compat/src/registry.ts"() {
1799
1999
  "use strict";
1800
2000
  init_capability_inventory_coverage();
2001
+ init_capability_outcomes2();
1801
2002
  init_react_native_root_export_coverage();
1802
2003
  init_react_native_webview_coverage();
1803
2004
  init_unsupported_packages();
@@ -1832,14 +2033,12 @@ var init_registry = __esm({
1832
2033
  versions: [
1833
2034
  {
1834
2035
  range: ">=0.86.0 <0.87.0",
1835
- // generated from audited RN 0.86.2 root exports. coverage answers whether
1836
- // measured real-app use works; strictCoverage gives every export equal
1837
- // weight. regenerate both with
1838
- // `bun scripts/measure-capability-usage.ts --root-exports`. neither changes
1839
- // proofCoverage, which measures how much proof exists.
1840
- coverage: REACT_NATIVE_ROOT_EXPORT_WILL_IT_WORK_COVERAGE,
2036
+ // outcomes measure declared scenarios; strictCoverage remains an
2037
+ // independent equal-export implementation estimate.
2038
+ coverage: CAPABILITY_PACKAGE_OUTCOMES["react-native"].byPlatform.ios.compatibility,
1841
2039
  strictCoverage: REACT_NATIVE_ROOT_EXPORT_STRICT_COVERAGE,
1842
- coverageSource: "estimated",
2040
+ coverageSource: "measured",
2041
+ outcomes: CAPABILITY_PACKAGE_OUTCOMES["react-native"],
1843
2042
  capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native"],
1844
2043
  note: "React Native 0.86 root surface with useful core rendering, input, scrolling, animation, list, platform, and native-module behavior",
1845
2044
  working: "all 99 React Native 0.86.2 public runtime root export names; flex and absolute layout, text shaping and wrapping, image loading and resize modes, touch and responder routing, controlled text input and keyboard presentation, vertical and horizontal scrolling with paging/snapping/sticky and maintained content, windowed/inverted/horizontal lists, common Animated graphs and composition, core LayoutAnimation create/update/delete geometry, alerts and action sheets, live platform/dimension/appearance state, and explicit native-module lookup",
@@ -1860,8 +2059,9 @@ var init_registry = __esm({
1860
2059
  },
1861
2060
  {
1862
2061
  range: ">=4.0.0 <5.0.0",
1863
- coverage: 0.97,
1864
- coverageSource: "estimated",
2062
+ coverage: CAPABILITY_PACKAGE_OUTCOMES["react-native-reanimated"].byPlatform.ios.compatibility,
2063
+ coverageSource: "measured",
2064
+ outcomes: CAPABILITY_PACKAGE_OUTCOMES["react-native-reanimated"],
1865
2065
  capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native-reanimated"],
1866
2066
  note: "core animations, gestures, scroll, layout transitions, common CSS opacity, transform, and processed-color transitions and keyframes, keyboard, sensors, reduced motion, native view property reads, and direct static style snapshots",
1867
2067
  working: "useSharedValue, useAnimatedStyle/Props/Reaction, useDerivedValue, useAnimatedScrollHandler, useScrollViewOffset, useFrameCallback, useAnimatedRef, useAnimatedKeyboard, useAnimatedSensor, useReducedMotion, entering/exiting/layout transitions, css/createCSSAnimatedComponent with cubicBezier/linear/steps timing for common opacity and transform transitions, opacity and transform keyframes with retained forwards fill, withTiming/Spring/Decay/Delay/Sequence/Repeat/Clamp, interpolate, interpolateColor, runOnJS/UI, measure, scrollTo, getViewProp (layout, opacity, zIndex, backgroundColor, boxShadow), direct setViewStyle snapshots, Easing, createAnimatedComponent, Animated.View/Text/Image/ScrollView/FlatList",
@@ -1877,8 +2077,9 @@ var init_registry = __esm({
1877
2077
  { range: ">=2.0.0 <2.30.0", coverage: 0.7, note: "tap, pan, long press" },
1878
2078
  {
1879
2079
  range: ">=2.30.0 <3.0.0",
1880
- coverage: 0.9,
1881
- coverageSource: "estimated",
2080
+ coverage: CAPABILITY_PACKAGE_OUTCOMES["react-native-gesture-handler"].byPlatform.ios.compatibility,
2081
+ coverageSource: "measured",
2082
+ outcomes: CAPABILITY_PACKAGE_OUTCOMES["react-native-gesture-handler"],
1882
2083
  capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native-gesture-handler"],
1883
2084
  note: "tap, pan, pinch, rotation, fling, long press, race, manual, simultaneous, force touch unavailable-hardware parity",
1884
2085
  working: "GestureDetector, Gesture.Tap/Pan/Pinch/Rotation/Fling/LongPress/ForceTouch/Manual/Race/Simultaneous/Exclusive/Hover, ForceTouchGestureHandler unavailable-hardware fallback (children render, forceTouchAvailable false, no force events), simultaneousWithExternalGesture/requireExternalGestureToFail/blocksExternalGesture, ScrollView/FlatList, Switch/RefreshControl, Pressable/Text, Touchables, BaseButton/RawButton/RectButton/BorderlessButton/PureNativeButton, Swipeable, ReanimatedSwipeable, DrawerLayout (the upstream component running on this seam: renderNavigationView, drawerPosition/drawerType/drawerWidth/edgeWidth, openDrawer/closeDrawer, edge-swipe drag, onDrawerOpen/onDrawerClose/onDrawerStateChanged), GestureHandlerRootView, createNativeWrapper, gestureHandlerRootHOC, PointerType/MouseButton/HoverEffect exports, velocity tracking, activeOffsets, multi-tap"
@@ -1893,12 +2094,13 @@ var init_registry = __esm({
1893
2094
  { range: ">=3.0.0 <4.0.0", coverage: 0.6, note: "basic screen container" },
1894
2095
  {
1895
2096
  range: ">=4.0.0",
1896
- coverage: 0.9,
1897
- coverageSource: "estimated",
2097
+ coverage: CAPABILITY_PACKAGE_OUTCOMES["react-native-screens"].byPlatform.ios.compatibility,
2098
+ coverageSource: "measured",
2099
+ outcomes: CAPABILITY_PACKAGE_OUTCOMES["react-native-screens"],
1898
2100
  capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native-screens"],
1899
2101
  note: "screen container, stack, header config, search bar, navigation props",
1900
- working: "Screen, ScreenContainer, ScreenStack, enableFreeze/freezeEnabled with delayed React freeze, Android modal/pageSheet push fallback, Android statusBarHidden/statusBarStyle/navigationBarHidden traits, push/pop slide, replaceAnimation push/pop direction, zoom/fade/fade_from_bottom transitions, edge swipe-back, parallax behind-screen, large title collapse, header (back button, inline/large title, custom left/center/right/search bar subviews, native header bar buttons/menus/badges, crossfade), formSheet custom initial detents/corner radius/grabber/undimmed range and stacked sheets, useHeaderHeight, useTransitionProgress, FullWindowOverlay, SearchBar, Tabs.Host/Screen, lifecycle callbacks (onAppear/onDisappear/onWillAppear/onWillDisappear), onDismissed",
1901
- missing: "interactive drag between formSheet detents, integrated search bar placements"
2102
+ working: "Screen, ScreenContainer, ScreenStack, enableFreeze/freezeEnabled with delayed React freeze, Android modal/pageSheet push fallback, Android statusBarHidden/statusBarStyle/navigationBarHidden traits, push/pop slide, replaceAnimation push/pop direction, zoom/fade/fade_from_bottom transitions, edge swipe-back, parallax behind-screen, large title collapse, header (back button, inline/large title, custom left/center/right/search bar subviews, native header bar buttons/menus/badges, crossfade), formSheet custom initial detents/corner radius/grabber/undimmed range and stacked sheets, useHeaderHeight, useTransitionProgress, FullWindowOverlay, SearchBar with stacked and iOS 26 automatic/inline/integrated/integratedCentered/integratedButton toolbar placement, Tabs.Host/Screen, lifecycle callbacks (onAppear/onDisappear/onWillAppear/onWillDisappear), onDismissed",
2103
+ missing: "interactive drag between formSheet detents"
1902
2104
  }
1903
2105
  ]
1904
2106
  },
@@ -1923,11 +2125,12 @@ var init_registry = __esm({
1923
2125
  versions: [
1924
2126
  {
1925
2127
  range: ">=13.0.0",
1926
- coverage: 0.85,
1927
- coverageSource: "estimated",
2128
+ coverage: CAPABILITY_PACKAGE_OUTCOMES["react-native-svg"].byPlatform.ios.compatibility,
2129
+ coverageSource: "measured",
2130
+ outcomes: CAPABILITY_PACKAGE_OUTCOMES["react-native-svg"],
1928
2131
  capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native-svg"],
1929
2132
  note: "full CanvasKit rendering for shapes, text, XML, gradients, references, masks, clipping, and images; SVG filter elements skipped",
1930
- working: "Svg, Path, Circle, Rect, Line, Ellipse, Polygon, Polyline, G, Text, TSpan, Defs, LinearGradient and RadialGradient with objectBoundingBox/userSpaceOnUse coordinates, focal points and gradientTransform, Stop, Mask, ClipPath, Image, Use and Symbol references, SvgXml, SvgUri, SvgFromXml, SvgCss, shape transforms, fill/stroke/opacity/dasharray, currentColor, viewBox scaling",
2133
+ working: "Svg, Path, Circle, Rect, Line, Ellipse, Polygon, Polyline, G, Text, TSpan, Defs, 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, shape transforms, fill/stroke/opacity/dasharray, currentColor, viewBox scaling",
1931
2134
  missing: "SVG filter primitives (Filter, FeBlend, FeColorMatrix, FeGaussianBlur, FeComposite, etc), Pattern, Marker, ForeignObject, and TextPath are skipped by the renderer"
1932
2135
  }
1933
2136
  ]
@@ -2040,8 +2243,9 @@ var init_registry = __esm({
2040
2243
  versions: [
2041
2244
  {
2042
2245
  range: ">=1.0.0",
2043
- coverage: 0.88,
2044
- coverageSource: "estimated",
2246
+ coverage: CAPABILITY_PACKAGE_OUTCOMES["react-native-keyboard-controller"].byPlatform.ios.compatibility,
2247
+ coverageSource: "measured",
2248
+ outcomes: CAPABILITY_PACKAGE_OUTCOMES["react-native-keyboard-controller"],
2045
2249
  capabilityCoverage: CAPABILITY_INVENTORY_PACKAGE_COVERAGE["react-native-keyboard-controller"],
2046
2250
  note: "native bindings stubbed (KeyboardControllerNative, KeyboardEvents, FocusedInputEvents, WindowDimensionsEvents, KeyboardControllerView + sibling native views); upstream pure-JS components, hooks, animated module, and KeyboardAvoidingView resolve from node_modules unchanged",
2047
2251
  working: "every upstream JS export runs through reanimated worklets; Android KeyboardGestureArea drives the existing keyboard owner through drag progress, velocity/distance settling, cancellation, focus retention, and cleanup; supported exports include KeyboardProvider, KeyboardAvoidingView, KeyboardStickyView, KeyboardAwareScrollView, KeyboardToolbar, KeyboardGestureArea, useReanimatedKeyboardAnimation, useKeyboardAnimation, useKeyboardHandler, useGenericKeyboardHandler, useKeyboardController, useKeyboardState, useKeyboardContext, useReanimatedFocusedInput, useFocusedInputHandler, useResizeMode, useWindowDimensions, KeyboardEvents, FocusedInputEvents, WindowDimensionsEvents resize events, KeyboardController (dismiss/setFocusTo/isVisible/state/preload/setInputMode/setDefaultMode), KeyboardControllerView, OverKeyboardView, KeyboardBackgroundView, KeyboardExtender, ClippingScrollView, KeyboardToolbarGroupView, and AndroidSoftInputModes",
@@ -14098,6 +14302,8 @@ function matchCompatVersion(entry, declaredVersion) {
14098
14302
  return {
14099
14303
  ...resolution,
14100
14304
  coverage: selected.coverage,
14305
+ coverageSource: selected.coverageSource ?? "estimated",
14306
+ ...selected.outcomes ? { outcomes: selected.outcomes } : {},
14101
14307
  note: selected.note,
14102
14308
  ...selected.working ? { working: selected.working } : {},
14103
14309
  ...selected.missing ? { missing: selected.missing } : {}
@@ -14124,6 +14330,7 @@ function rnxSupportForPackage(name2, version, data) {
14124
14330
  return {
14125
14331
  level: "unsupported",
14126
14332
  coverage: 0,
14333
+ coverageSource: "estimated",
14127
14334
  note: unsupported?.note ?? UNSUPPORTED_NATIVE_PACKAGE_NOTE,
14128
14335
  recovery: unsupported?.recovery ?? null,
14129
14336
  source: "unsupported-list"
@@ -14150,9 +14357,12 @@ function rnxSupportForPackage(name2, version, data) {
14150
14357
  source: "compat-registry"
14151
14358
  };
14152
14359
  }
14360
+ const coverage = match.coverageSource === "measured" ? match.outcomes?.byPlatform.ios.compatibility ?? null : match.coverage;
14153
14361
  return {
14154
- level: match.coverage >= 0.9 ? "full" : "partial",
14155
- coverage: match.coverage,
14362
+ level: coverage === null ? "stubbed" : coverage >= 0.9 ? "full" : "partial",
14363
+ coverage,
14364
+ coverageSource: match.coverageSource,
14365
+ ...match.outcomes ? { outcomes: match.outcomes } : {},
14156
14366
  note: match.note,
14157
14367
  ...match.working ? { working: match.working } : {},
14158
14368
  ...match.missing ? { missing: match.missing } : {},
@@ -14160,6 +14370,20 @@ function rnxSupportForPackage(name2, version, data) {
14160
14370
  source: "compat-registry"
14161
14371
  };
14162
14372
  }
14373
+ function summarizeScanPackages(packages) {
14374
+ return {
14375
+ ...aggregateCompatibilityOutcomes(
14376
+ packages.filter((pkg) => pkg.status !== "not-relevant").map((pkg) => ({
14377
+ weight: 1,
14378
+ assessment: pkg.rnx.outcomes?.byPlatform.ios ?? null,
14379
+ estimate: pkg.coverage,
14380
+ source: pkg.rnx.coverageSource === "measured" ? "measured" : pkg.coverage === null ? "unassessed" : "estimated"
14381
+ }))
14382
+ ),
14383
+ platform: "ios",
14384
+ weighting: "dependency-usage"
14385
+ };
14386
+ }
14163
14387
  function detectFramework(deps) {
14164
14388
  if (deps["one"]) return "one";
14165
14389
  if (deps["expo"]) return "expo";
@@ -14199,7 +14423,7 @@ function scanDepsWithData(pkg, data) {
14199
14423
  packages.push({
14200
14424
  name: name2,
14201
14425
  version,
14202
- coverage: 0.3,
14426
+ coverage: null,
14203
14427
  status: "auto-stub",
14204
14428
  note: "not yet verified; it may work through rnx's generic native seam",
14205
14429
  rnx
@@ -14210,7 +14434,7 @@ function scanDepsWithData(pkg, data) {
14210
14434
  packages.push({
14211
14435
  name: name2,
14212
14436
  version,
14213
- coverage: 0.3,
14437
+ coverage: null,
14214
14438
  status: "auto-stub",
14215
14439
  note: rnx.note ?? "not yet verified for this version",
14216
14440
  rnx
@@ -14221,27 +14445,27 @@ function scanDepsWithData(pkg, data) {
14221
14445
  packages.push({
14222
14446
  name: name2,
14223
14447
  version,
14224
- coverage: rnx.coverage ?? 0.3,
14448
+ coverage: rnx.coverage,
14225
14449
  status: buildOnly ? "not-relevant" : rnx.level === "full" ? "full" : "partial",
14226
14450
  note: rnx.note ?? "",
14227
14451
  rnx
14228
14452
  });
14229
14453
  }
14230
- const scored = packages.filter((p) => p.status !== "not-relevant");
14231
- const total = scored.length;
14232
- const overallScore = total === 0 ? 1 : scored.reduce((sum, p) => sum + p.coverage, 0) / total;
14454
+ const scoreSummary = summarizeScanPackages(packages);
14233
14455
  return {
14234
14456
  projectName: pkg.name || "unknown",
14235
14457
  rnVersion,
14236
14458
  framework,
14237
14459
  packages,
14238
- overallScore: Math.round(overallScore * 100) / 100
14460
+ overallScore: scoreSummary.compatibility,
14461
+ scoreSummary
14239
14462
  };
14240
14463
  }
14241
14464
  var NON_RN_PACKAGES;
14242
14465
  var init_scan = __esm({
14243
14466
  "../compat/src/scan.ts"() {
14244
14467
  "use strict";
14468
+ init_capability_outcomes();
14245
14469
  init_native_evidence();
14246
14470
  init_registry();
14247
14471
  init_unsupported_packages();
@@ -14306,14 +14530,25 @@ function countScanResults(result) {
14306
14530
  }
14307
14531
  function formatScanCounts(result) {
14308
14532
  const counts = countScanResults(result);
14309
- return [
14533
+ const countsText = [
14310
14534
  `${counts.supported} supported`,
14311
14535
  `${counts.partial} partial`,
14312
14536
  `${counts.unsupported} unsupported`,
14313
14537
  `${counts.notYetVerified} not yet verified`
14314
14538
  ].join(", ");
14539
+ const summary = result.scoreSummary;
14540
+ const score = summary.compatibility === null ? "unassessed" : `${Math.round(summary.compatibility * 100)}% compatibility (${summary.source})`;
14541
+ return `${countsText}; ${score}; iOS measured: ${formatCompatibilityPercent(summary.assessed * 100)}% assessed dependency usage; ${Math.round(summary.estimated * 100)}% estimated dependency usage`;
14315
14542
  }
14316
14543
  function formatPackageStatus(pkg) {
14544
+ if (pkg.rnx.coverageSource === "measured") {
14545
+ const outcome = pkg.rnx.outcomes?.byPlatform.ios;
14546
+ const score = pkg.coverage === null ? "unassessed" : `${Math.round(pkg.coverage * 100)}% compatibility`;
14547
+ return `iOS measured: ${score}, ${formatCompatibilityPercent((outcome?.assessed ?? 0) * 100)}% assessed usage`;
14548
+ }
14549
+ if (pkg.coverage !== null && pkg.status !== "not-relevant") {
14550
+ return `${pkg.status === "full" ? "supported" : pkg.status} (estimated ${Math.round(pkg.coverage * 100)}%)`;
14551
+ }
14317
14552
  switch (pkg.status) {
14318
14553
  case "full":
14319
14554
  return "supported";
@@ -14330,7 +14565,7 @@ function formatPackageStatus(pkg) {
14330
14565
  function formatDetailedScanLines(result) {
14331
14566
  const lines = [];
14332
14567
  const actionable = result.packages.filter(
14333
- (pkg) => pkg.status === "partial" || pkg.status === "unsupported"
14568
+ (pkg) => pkg.status === "partial" || pkg.status === "unsupported" || pkg.status === "full" && pkg.rnx.coverageSource === "measured"
14334
14569
  );
14335
14570
  for (const pkg of actionable) {
14336
14571
  lines.push(`${formatPackageStatus(pkg)}: ${pkg.name}@${pkg.version} \u2014 ${pkg.note}`);
@@ -14339,7 +14574,9 @@ function formatDetailedScanLines(result) {
14339
14574
  if (unknown.length > 0) {
14340
14575
  lines.push("Not yet verified:");
14341
14576
  for (const pkg of unknown) {
14342
- lines.push(` ${pkg.name}@${pkg.version} \u2014 ${pkg.note}`);
14577
+ lines.push(
14578
+ ` ${pkg.name}@${pkg.version} \u2014 ${formatPackageStatus(pkg)}; ${pkg.note}`
14579
+ );
14343
14580
  }
14344
14581
  lines.push(
14345
14582
  "SootSim may still work. The simulator will report a concrete runtime error if it finds a gap."
@@ -14351,7 +14588,8 @@ var COMPAT_RESULT_CAVEAT;
14351
14588
  var init_scan_summary = __esm({
14352
14589
  "../compat/src/scan-summary.ts"() {
14353
14590
  "use strict";
14354
- COMPAT_RESULT_CAVEAT = "This is a dependency-level estimate, not a guarantee that every app path works.";
14591
+ init_capability_outcomes();
14592
+ COMPAT_RESULT_CAVEAT = "Measured iOS results cover assessed API scenarios. Legacy contributions are estimates; unassessed usage remains unknown. App paths may exercise additional behavior.";
14355
14593
  }
14356
14594
  });
14357
14595
 
@@ -21798,6 +22036,180 @@ var init_metroCloudArtifact = __esm({
21798
22036
  }
21799
22037
  });
21800
22038
 
22039
+ // ../sootsim-engine/src/metro-fingerprint-registry-client.ts
22040
+ function pointerUrl(options) {
22041
+ return options.pointerUrl ?? new URL(import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_POINTER_PATH, DEFAULT_REGISTRY_ORIGIN).toString();
22042
+ }
22043
+ async function sha256Hex(bytes) {
22044
+ const input = new Uint8Array(bytes.byteLength);
22045
+ input.set(bytes);
22046
+ const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", input.buffer));
22047
+ return [...digest].map((byte) => byte.toString(16).padStart(2, "0")).join("");
22048
+ }
22049
+ async function openRegistryCache() {
22050
+ if (typeof globalThis.caches?.open !== "function") return null;
22051
+ try {
22052
+ return await globalThis.caches.open(REGISTRY_CACHE_NAME);
22053
+ } catch {
22054
+ return null;
22055
+ }
22056
+ }
22057
+ function cacheKey(baseUrl, suffix) {
22058
+ const url = new URL(baseUrl);
22059
+ url.pathname = `${url.pathname.replace(/\/[^/]*$/, "")}/.rnx-fingerprint-cache/${suffix}`;
22060
+ url.search = "";
22061
+ url.hash = "";
22062
+ return new Request(url.toString());
22063
+ }
22064
+ async function parseRegistryBytes(args) {
22065
+ if (args.bytes.byteLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES) {
22066
+ throw new Error(
22067
+ `RNX Metro fingerprint registry exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES} bytes`
22068
+ );
22069
+ }
22070
+ const integrity = await sha256Hex(args.bytes);
22071
+ if (integrity !== args.expectedIntegrity) {
22072
+ throw new Error("RNX Metro fingerprint registry integrity mismatch");
22073
+ }
22074
+ let parsed;
22075
+ try {
22076
+ parsed = JSON.parse(new TextDecoder().decode(args.bytes));
22077
+ } catch {
22078
+ throw new Error("RNX Metro fingerprint registry is not valid JSON");
22079
+ }
22080
+ const registry = (0, import_metro_fingerprint_registry.parseRNXMetroFingerprintRegistry)(parsed);
22081
+ if (!registry) throw new Error("RNX Metro fingerprint registry is malformed");
22082
+ if (args.expectedRevision && registry.revision !== args.expectedRevision) {
22083
+ throw new Error("RNX Metro fingerprint registry revision does not match its pointer");
22084
+ }
22085
+ return { registry, integrity, source: args.source };
22086
+ }
22087
+ async function readCachedRegistry(cache, baseUrl, integrity, expectedRevision) {
22088
+ const response = await cache.match(cacheKey(baseUrl, integrity));
22089
+ if (!response?.ok) return null;
22090
+ try {
22091
+ return await parseRegistryBytes({
22092
+ bytes: new Uint8Array(await response.arrayBuffer()),
22093
+ expectedIntegrity: integrity,
22094
+ expectedRevision,
22095
+ source: "cache"
22096
+ });
22097
+ } catch {
22098
+ return null;
22099
+ }
22100
+ }
22101
+ async function readLastCachedRegistry(cache, baseUrl) {
22102
+ const memoryReceipt = memoryReceipts.get(baseUrl);
22103
+ if (!cache) return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
22104
+ const latest = await cache.match(cacheKey(baseUrl, "latest"));
22105
+ if (!latest?.ok) return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
22106
+ const integrity = latest.headers.get("x-rnx-registry-integrity");
22107
+ if (!integrity || !/^[a-f0-9]{64}$/.test(integrity)) {
22108
+ return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
22109
+ }
22110
+ return await readCachedRegistry(cache, baseUrl, integrity) ?? (memoryReceipt ? { ...memoryReceipt, source: "cache" } : null);
22111
+ }
22112
+ async function writeCachedRegistry(cache, baseUrl, bytes, receipt) {
22113
+ memoryReceipts.set(baseUrl, receipt);
22114
+ if (!cache) return;
22115
+ const headers = {
22116
+ "content-type": "application/json",
22117
+ "x-rnx-registry-integrity": receipt.integrity
22118
+ };
22119
+ try {
22120
+ await cache.put(
22121
+ cacheKey(baseUrl, receipt.integrity),
22122
+ new Response(bytes.slice(), { headers })
22123
+ );
22124
+ await cache.put(cacheKey(baseUrl, "latest"), new Response("", { headers }));
22125
+ } catch {
22126
+ }
22127
+ }
22128
+ async function readPointer(response) {
22129
+ const bytes = new Uint8Array(await response.arrayBuffer());
22130
+ if (bytes.byteLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_POINTER_BYTES) {
22131
+ throw new Error(
22132
+ `RNX Metro fingerprint pointer exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_POINTER_BYTES} bytes`
22133
+ );
22134
+ }
22135
+ let parsed;
22136
+ try {
22137
+ parsed = JSON.parse(new TextDecoder().decode(bytes));
22138
+ } catch {
22139
+ throw new Error("RNX Metro fingerprint pointer is not valid JSON");
22140
+ }
22141
+ const pointer = (0, import_metro_fingerprint_registry.parseRNXMetroFingerprintPointer)(parsed);
22142
+ if (!pointer) throw new Error("RNX Metro fingerprint pointer is malformed");
22143
+ return pointer;
22144
+ }
22145
+ async function loadMetroFingerprintRegistry(options = {}) {
22146
+ const baseUrl = pointerUrl(options);
22147
+ const request = options.fetch ?? globalThis.fetch;
22148
+ const cache = await openRegistryCache();
22149
+ let pointer;
22150
+ try {
22151
+ const response = await request(baseUrl, { cache: "no-store" });
22152
+ if (!response.ok) {
22153
+ throw new Error(`RNX Metro fingerprint pointer answered ${response.status}`);
22154
+ }
22155
+ pointer = await readPointer(response);
22156
+ } catch (error) {
22157
+ const fallback = await readLastCachedRegistry(cache, baseUrl);
22158
+ if (fallback) return fallback;
22159
+ throw error;
22160
+ }
22161
+ const memoryReceipt = memoryReceipts.get(baseUrl);
22162
+ if (memoryReceipt?.integrity === pointer.integrity && memoryReceipt.registry.revision === pointer.revision) {
22163
+ return { ...memoryReceipt, source: "cache" };
22164
+ }
22165
+ const cached4 = cache ? await readCachedRegistry(cache, baseUrl, pointer.integrity, pointer.revision) : null;
22166
+ if (cached4) {
22167
+ memoryReceipts.set(baseUrl, cached4);
22168
+ return cached4;
22169
+ }
22170
+ try {
22171
+ const payloadUrl = new URL(pointer.payloadUrl, baseUrl).toString();
22172
+ const response = await request(payloadUrl, { cache: "force-cache" });
22173
+ if (!response.ok) {
22174
+ throw new Error(`RNX Metro fingerprint registry answered ${response.status}`);
22175
+ }
22176
+ const declaredLength = Number(response.headers.get("content-length"));
22177
+ if (Number.isFinite(declaredLength) && declaredLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES) {
22178
+ throw new Error(
22179
+ `RNX Metro fingerprint registry exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES} bytes`
22180
+ );
22181
+ }
22182
+ const bytes = new Uint8Array(await response.arrayBuffer());
22183
+ if (bytes.byteLength !== pointer.bytes) {
22184
+ throw new Error(
22185
+ "RNX Metro fingerprint registry byte length does not match its pointer"
22186
+ );
22187
+ }
22188
+ const receipt = await parseRegistryBytes({
22189
+ bytes,
22190
+ expectedIntegrity: pointer.integrity,
22191
+ expectedRevision: pointer.revision,
22192
+ source: "network"
22193
+ });
22194
+ await writeCachedRegistry(cache, baseUrl, bytes, receipt);
22195
+ return receipt;
22196
+ } catch (error) {
22197
+ const fallback = await readLastCachedRegistry(cache, baseUrl);
22198
+ if (fallback) return fallback;
22199
+ throw error;
22200
+ }
22201
+ }
22202
+ var import_metro_fingerprint_registry, REGISTRY_CACHE_NAME, DEFAULT_REGISTRY_ORIGIN, memoryReceipts;
22203
+ var init_metro_fingerprint_registry_client = __esm({
22204
+ "../sootsim-engine/src/metro-fingerprint-registry-client.ts"() {
22205
+ "use strict";
22206
+ import_metro_fingerprint_registry = require("rnxsim/metro-fingerprint-registry");
22207
+ REGISTRY_CACHE_NAME = "rnx-metro-fingerprints-v1";
22208
+ DEFAULT_REGISTRY_ORIGIN = "https://contrast.dev";
22209
+ memoryReceipts = /* @__PURE__ */ new Map();
22210
+ }
22211
+ });
22212
+
21801
22213
  // ../compat/src/stub-manifest.ts
21802
22214
  var COMPAT_REACT_NATIVE_DEEP_STUBS;
21803
22215
  var init_stub_manifest = __esm({
@@ -21808,67 +22220,67 @@ var init_stub_manifest = __esm({
21808
22220
  specifier: "react-native/Libraries/Pressability/usePressability",
21809
22221
  stubFile: "rn-libraries/usePressability.ts",
21810
22222
  runtimeTier: "core",
21811
- buildResolvers: ["vite"]
22223
+ buildResolvers: ["vite", "dep-prebundle"]
21812
22224
  },
21813
22225
  pressability: {
21814
22226
  specifier: "react-native/Libraries/Pressability/Pressability",
21815
22227
  stubFile: "rn-libraries/Pressability.ts",
21816
22228
  runtimeTier: "core",
21817
- buildResolvers: ["vite"]
22229
+ buildResolvers: ["vite", "dep-prebundle"]
21818
22230
  },
21819
22231
  pressabilityDebug: {
21820
22232
  specifier: "react-native/Libraries/Pressability/PressabilityDebug",
21821
22233
  stubFile: "rn-libraries/PressabilityDebug.ts",
21822
22234
  runtimeTier: "core",
21823
- buildResolvers: ["vite"]
22235
+ buildResolvers: ["vite", "dep-prebundle"]
21824
22236
  },
21825
22237
  reactFabric: {
21826
22238
  specifier: "react-native/Libraries/Renderer/shims/ReactFabric",
21827
22239
  stubFile: "rn-libraries/ReactFabric.ts",
21828
22240
  runtimeTier: "core",
21829
- buildResolvers: ["vite"]
22241
+ buildResolvers: ["vite", "dep-prebundle"]
21830
22242
  },
21831
22243
  reactNativeRenderer: {
21832
22244
  specifier: "react-native/Libraries/Renderer/shims/ReactNative",
21833
22245
  stubFile: "rn-libraries/ReactNative.ts",
21834
22246
  runtimeTier: "core",
21835
- buildResolvers: ["vite"]
22247
+ buildResolvers: ["vite", "dep-prebundle"]
21836
22248
  },
21837
22249
  reactNativeViewConfigRegistry: {
21838
22250
  specifier: "react-native/Libraries/Renderer/shims/ReactNativeViewConfigRegistry",
21839
22251
  stubFile: "rn-libraries/ReactNativeViewConfigRegistry.ts",
21840
22252
  runtimeTier: "core",
21841
- buildResolvers: ["vite"]
22253
+ buildResolvers: ["vite", "dep-prebundle"]
21842
22254
  },
21843
22255
  appContainer: {
21844
22256
  specifier: "react-native/Libraries/ReactNative/AppContainer",
21845
22257
  stubFile: "rn-libraries/AppContainer.ts",
21846
22258
  runtimeTier: "core",
21847
- buildResolvers: ["vite"]
22259
+ buildResolvers: ["vite", "dep-prebundle"]
21848
22260
  },
21849
22261
  appRegistry: {
21850
22262
  specifier: "react-native/Libraries/ReactNative/AppRegistry",
21851
22263
  stubFile: "rn-libraries/AppRegistry.ts",
21852
22264
  runtimeTier: "core",
21853
- buildResolvers: ["vite"]
22265
+ buildResolvers: ["vite", "dep-prebundle"]
21854
22266
  },
21855
22267
  rendererImplementation: {
21856
22268
  specifier: "react-native/Libraries/ReactNative/RendererImplementation",
21857
22269
  stubFile: "rn-libraries/RendererImplementation.ts",
21858
22270
  runtimeTier: "core",
21859
- buildResolvers: ["vite"]
22271
+ buildResolvers: ["vite", "dep-prebundle"]
21860
22272
  },
21861
22273
  rendererProxy: {
21862
22274
  specifier: "react-native/Libraries/ReactNative/RendererProxy",
21863
22275
  stubFile: "rn-libraries/RendererProxy.ts",
21864
22276
  runtimeTier: "core",
21865
- buildResolvers: ["vite"]
22277
+ buildResolvers: ["vite", "dep-prebundle"]
21866
22278
  },
21867
22279
  getDevServer: {
21868
22280
  specifier: "react-native/Libraries/Core/Devtools/getDevServer",
21869
22281
  stubFile: "rn-libraries/getDevServer.ts",
21870
22282
  runtimeTier: "core",
21871
- buildResolvers: ["vite"]
22283
+ buildResolvers: ["vite", "dep-prebundle"]
21872
22284
  },
21873
22285
  codegenNativeCommands: {
21874
22286
  specifier: "react-native/Libraries/Utilities/codegenNativeCommands",
@@ -21886,19 +22298,19 @@ var init_stub_manifest = __esm({
21886
22298
  specifier: "react-native/Libraries/Image/resolveAssetSource",
21887
22299
  stubFile: "rn-libraries/resolveAssetSource.ts",
21888
22300
  runtimeTier: "core",
21889
- buildResolvers: ["vite"]
22301
+ buildResolvers: ["vite", "dep-prebundle"]
21890
22302
  },
21891
22303
  viewConfigIgnore: {
21892
22304
  specifier: "react-native/Libraries/NativeComponent/ViewConfigIgnore",
21893
22305
  stubFile: "rn-libraries/ViewConfigIgnore.ts",
21894
22306
  runtimeTier: "core",
21895
- buildResolvers: ["vite"]
22307
+ buildResolvers: ["vite", "dep-prebundle"]
21896
22308
  },
21897
22309
  nativeComponentRegistry: {
21898
22310
  specifier: "react-native/Libraries/NativeComponent/NativeComponentRegistry",
21899
22311
  stubFile: "rn-libraries/NativeComponentRegistry.ts",
21900
22312
  runtimeTier: "core",
21901
- buildResolvers: ["vite"]
22313
+ buildResolvers: ["vite", "dep-prebundle"]
21902
22314
  },
21903
22315
  // RN TurboModule spec for SourceCode. third-party libraries import
21904
22316
  // this directly to read `scriptURL`; without the deep-path stub the
@@ -21908,19 +22320,19 @@ var init_stub_manifest = __esm({
21908
22320
  specifier: "react-native/src/private/specs/modules/NativeSourceCode",
21909
22321
  stubFile: "rn-libraries/NativeSourceCode.ts",
21910
22322
  runtimeTier: "core",
21911
- buildResolvers: ["vite"]
22323
+ buildResolvers: ["vite", "dep-prebundle"]
21912
22324
  },
21913
22325
  nativeSourceCodeDeprecated: {
21914
22326
  specifier: "react-native/src/private/specs_DEPRECATED/modules/NativeSourceCode",
21915
22327
  stubFile: "rn-libraries/NativeSourceCode.ts",
21916
22328
  runtimeTier: "core",
21917
- buildResolvers: ["vite"]
22329
+ buildResolvers: ["vite", "dep-prebundle"]
21918
22330
  },
21919
22331
  nativeSourceCodeLibraries: {
21920
22332
  specifier: "react-native/Libraries/NativeModules/specs/NativeSourceCode",
21921
22333
  stubFile: "rn-libraries/NativeSourceCode.ts",
21922
22334
  runtimeTier: "core",
21923
- buildResolvers: ["vite"]
22335
+ buildResolvers: ["vite", "dep-prebundle"]
21924
22336
  },
21925
22337
  // RN TurboModule spec for the Android StatusBar. libraries import it
21926
22338
  // directly and `Object.assign` over its default export; the shim namespace
@@ -21929,13 +22341,13 @@ var init_stub_manifest = __esm({
21929
22341
  specifier: "react-native/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid",
21930
22342
  stubFile: "rn-libraries/NativeStatusBarManagerAndroid.ts",
21931
22343
  runtimeTier: "core",
21932
- buildResolvers: ["vite"]
22344
+ buildResolvers: ["vite", "dep-prebundle"]
21933
22345
  },
21934
22346
  nativeStatusBarManagerAndroidDeprecated: {
21935
22347
  specifier: "react-native/src/private/specs_DEPRECATED/modules/NativeStatusBarManagerAndroid",
21936
22348
  stubFile: "rn-libraries/NativeStatusBarManagerAndroid.ts",
21937
22349
  runtimeTier: "core",
21938
- buildResolvers: ["vite"]
22350
+ buildResolvers: ["vite", "dep-prebundle"]
21939
22351
  }
21940
22352
  };
21941
22353
  }
@@ -22138,7 +22550,7 @@ function metroFingerprintDiscriminators(input) {
22138
22550
  return { key: `${kind}:${fnv1a64(encoded)}`, cost: encoded.length };
22139
22551
  });
22140
22552
  }
22141
- async function sha256Hex(value) {
22553
+ async function sha256Hex2(value) {
22142
22554
  const bytes = new TextEncoder().encode(value);
22143
22555
  const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
22144
22556
  return [...digest].map((byte) => byte.toString(16).padStart(2, "0")).join("");
@@ -22190,7 +22602,7 @@ async function fingerprintBlindMetroBundle(source) {
22190
22602
  exports: exports2,
22191
22603
  literals,
22192
22604
  dependencyArity,
22193
- factoryDigest: await sha256Hex(canonicalFactoryForDigest(factory, literalTokens))
22605
+ factoryDigest: await sha256Hex2(canonicalFactoryForDigest(factory, literalTokens))
22194
22606
  };
22195
22607
  })
22196
22608
  );
@@ -22565,180 +22977,6 @@ var init_metro_fingerprint = __esm({
22565
22977
  }
22566
22978
  });
22567
22979
 
22568
- // ../sootsim-engine/src/metro-fingerprint-registry-client.ts
22569
- function pointerUrl(options) {
22570
- return options.pointerUrl ?? new URL(import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_POINTER_PATH, DEFAULT_REGISTRY_ORIGIN).toString();
22571
- }
22572
- async function sha256Hex2(bytes) {
22573
- const input = new Uint8Array(bytes.byteLength);
22574
- input.set(bytes);
22575
- const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", input.buffer));
22576
- return [...digest].map((byte) => byte.toString(16).padStart(2, "0")).join("");
22577
- }
22578
- async function openRegistryCache() {
22579
- if (typeof globalThis.caches?.open !== "function") return null;
22580
- try {
22581
- return await globalThis.caches.open(REGISTRY_CACHE_NAME);
22582
- } catch {
22583
- return null;
22584
- }
22585
- }
22586
- function cacheKey(baseUrl, suffix) {
22587
- const url = new URL(baseUrl);
22588
- url.pathname = `${url.pathname.replace(/\/[^/]*$/, "")}/.rnx-fingerprint-cache/${suffix}`;
22589
- url.search = "";
22590
- url.hash = "";
22591
- return new Request(url.toString());
22592
- }
22593
- async function parseRegistryBytes(args) {
22594
- if (args.bytes.byteLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES) {
22595
- throw new Error(
22596
- `RNX Metro fingerprint registry exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES} bytes`
22597
- );
22598
- }
22599
- const integrity = await sha256Hex2(args.bytes);
22600
- if (integrity !== args.expectedIntegrity) {
22601
- throw new Error("RNX Metro fingerprint registry integrity mismatch");
22602
- }
22603
- let parsed;
22604
- try {
22605
- parsed = JSON.parse(new TextDecoder().decode(args.bytes));
22606
- } catch {
22607
- throw new Error("RNX Metro fingerprint registry is not valid JSON");
22608
- }
22609
- const registry = (0, import_metro_fingerprint_registry.parseRNXMetroFingerprintRegistry)(parsed);
22610
- if (!registry) throw new Error("RNX Metro fingerprint registry is malformed");
22611
- if (args.expectedRevision && registry.revision !== args.expectedRevision) {
22612
- throw new Error("RNX Metro fingerprint registry revision does not match its pointer");
22613
- }
22614
- return { registry, integrity, source: args.source };
22615
- }
22616
- async function readCachedRegistry(cache, baseUrl, integrity, expectedRevision) {
22617
- const response = await cache.match(cacheKey(baseUrl, integrity));
22618
- if (!response?.ok) return null;
22619
- try {
22620
- return await parseRegistryBytes({
22621
- bytes: new Uint8Array(await response.arrayBuffer()),
22622
- expectedIntegrity: integrity,
22623
- expectedRevision,
22624
- source: "cache"
22625
- });
22626
- } catch {
22627
- return null;
22628
- }
22629
- }
22630
- async function readLastCachedRegistry(cache, baseUrl) {
22631
- const memoryReceipt = memoryReceipts.get(baseUrl);
22632
- if (!cache) return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
22633
- const latest = await cache.match(cacheKey(baseUrl, "latest"));
22634
- if (!latest?.ok) return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
22635
- const integrity = latest.headers.get("x-rnx-registry-integrity");
22636
- if (!integrity || !/^[a-f0-9]{64}$/.test(integrity)) {
22637
- return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
22638
- }
22639
- return await readCachedRegistry(cache, baseUrl, integrity) ?? (memoryReceipt ? { ...memoryReceipt, source: "cache" } : null);
22640
- }
22641
- async function writeCachedRegistry(cache, baseUrl, bytes, receipt) {
22642
- memoryReceipts.set(baseUrl, receipt);
22643
- if (!cache) return;
22644
- const headers = {
22645
- "content-type": "application/json",
22646
- "x-rnx-registry-integrity": receipt.integrity
22647
- };
22648
- try {
22649
- await cache.put(
22650
- cacheKey(baseUrl, receipt.integrity),
22651
- new Response(bytes.slice(), { headers })
22652
- );
22653
- await cache.put(cacheKey(baseUrl, "latest"), new Response("", { headers }));
22654
- } catch {
22655
- }
22656
- }
22657
- async function readPointer(response) {
22658
- const bytes = new Uint8Array(await response.arrayBuffer());
22659
- if (bytes.byteLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_POINTER_BYTES) {
22660
- throw new Error(
22661
- `RNX Metro fingerprint pointer exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_POINTER_BYTES} bytes`
22662
- );
22663
- }
22664
- let parsed;
22665
- try {
22666
- parsed = JSON.parse(new TextDecoder().decode(bytes));
22667
- } catch {
22668
- throw new Error("RNX Metro fingerprint pointer is not valid JSON");
22669
- }
22670
- const pointer = (0, import_metro_fingerprint_registry.parseRNXMetroFingerprintPointer)(parsed);
22671
- if (!pointer) throw new Error("RNX Metro fingerprint pointer is malformed");
22672
- return pointer;
22673
- }
22674
- async function loadMetroFingerprintRegistry(options = {}) {
22675
- const baseUrl = pointerUrl(options);
22676
- const request = options.fetch ?? globalThis.fetch;
22677
- const cache = await openRegistryCache();
22678
- let pointer;
22679
- try {
22680
- const response = await request(baseUrl, { cache: "no-store" });
22681
- if (!response.ok) {
22682
- throw new Error(`RNX Metro fingerprint pointer answered ${response.status}`);
22683
- }
22684
- pointer = await readPointer(response);
22685
- } catch (error) {
22686
- const fallback = await readLastCachedRegistry(cache, baseUrl);
22687
- if (fallback) return fallback;
22688
- throw error;
22689
- }
22690
- const memoryReceipt = memoryReceipts.get(baseUrl);
22691
- if (memoryReceipt?.integrity === pointer.integrity && memoryReceipt.registry.revision === pointer.revision) {
22692
- return { ...memoryReceipt, source: "cache" };
22693
- }
22694
- const cached4 = cache ? await readCachedRegistry(cache, baseUrl, pointer.integrity, pointer.revision) : null;
22695
- if (cached4) {
22696
- memoryReceipts.set(baseUrl, cached4);
22697
- return cached4;
22698
- }
22699
- try {
22700
- const payloadUrl = new URL(pointer.payloadUrl, baseUrl).toString();
22701
- const response = await request(payloadUrl, { cache: "force-cache" });
22702
- if (!response.ok) {
22703
- throw new Error(`RNX Metro fingerprint registry answered ${response.status}`);
22704
- }
22705
- const declaredLength = Number(response.headers.get("content-length"));
22706
- if (Number.isFinite(declaredLength) && declaredLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES) {
22707
- throw new Error(
22708
- `RNX Metro fingerprint registry exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES} bytes`
22709
- );
22710
- }
22711
- const bytes = new Uint8Array(await response.arrayBuffer());
22712
- if (bytes.byteLength !== pointer.bytes) {
22713
- throw new Error(
22714
- "RNX Metro fingerprint registry byte length does not match its pointer"
22715
- );
22716
- }
22717
- const receipt = await parseRegistryBytes({
22718
- bytes,
22719
- expectedIntegrity: pointer.integrity,
22720
- expectedRevision: pointer.revision,
22721
- source: "network"
22722
- });
22723
- await writeCachedRegistry(cache, baseUrl, bytes, receipt);
22724
- return receipt;
22725
- } catch (error) {
22726
- const fallback = await readLastCachedRegistry(cache, baseUrl);
22727
- if (fallback) return fallback;
22728
- throw error;
22729
- }
22730
- }
22731
- var import_metro_fingerprint_registry, REGISTRY_CACHE_NAME, DEFAULT_REGISTRY_ORIGIN, memoryReceipts;
22732
- var init_metro_fingerprint_registry_client = __esm({
22733
- "../sootsim-engine/src/metro-fingerprint-registry-client.ts"() {
22734
- "use strict";
22735
- import_metro_fingerprint_registry = require("rnxsim/metro-fingerprint-registry");
22736
- REGISTRY_CACHE_NAME = "rnx-metro-fingerprints-v1";
22737
- DEFAULT_REGISTRY_ORIGIN = "https://contrast.dev";
22738
- memoryReceipts = /* @__PURE__ */ new Map();
22739
- }
22740
- });
22741
-
22742
22980
  // src/cloud-contract.ts
22743
22981
  function isRnxCloudCommandType(value) {
22744
22982
  return RNX_CLOUD_COMMAND_TYPE_SET.has(value);
@@ -23486,8 +23724,8 @@ var init_cloud_client = __esm({
23486
23724
  import_node_path15 = require("node:path");
23487
23725
  init_metroAssetArtifact();
23488
23726
  init_metroCloudArtifact();
23489
- init_metro_fingerprint();
23490
23727
  init_metro_fingerprint_registry_client();
23728
+ init_metro_fingerprint();
23491
23729
  init_backend_origin();
23492
23730
  init_cloud_contract();
23493
23731
  init_metro_production_bundle();