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;
@@ -2452,6 +2452,180 @@ var init_metroCloudArtifact = __esm({
2452
2452
  }
2453
2453
  });
2454
2454
 
2455
+ // ../sootsim-engine/src/metro-fingerprint-registry-client.ts
2456
+ function pointerUrl(options) {
2457
+ return options.pointerUrl ?? new URL(import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_POINTER_PATH, DEFAULT_REGISTRY_ORIGIN).toString();
2458
+ }
2459
+ async function sha256Hex(bytes) {
2460
+ const input = new Uint8Array(bytes.byteLength);
2461
+ input.set(bytes);
2462
+ const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", input.buffer));
2463
+ return [...digest].map((byte) => byte.toString(16).padStart(2, "0")).join("");
2464
+ }
2465
+ async function openRegistryCache() {
2466
+ if (typeof globalThis.caches?.open !== "function") return null;
2467
+ try {
2468
+ return await globalThis.caches.open(REGISTRY_CACHE_NAME);
2469
+ } catch {
2470
+ return null;
2471
+ }
2472
+ }
2473
+ function cacheKey(baseUrl, suffix) {
2474
+ const url = new URL(baseUrl);
2475
+ url.pathname = `${url.pathname.replace(/\/[^/]*$/, "")}/.rnx-fingerprint-cache/${suffix}`;
2476
+ url.search = "";
2477
+ url.hash = "";
2478
+ return new Request(url.toString());
2479
+ }
2480
+ async function parseRegistryBytes(args) {
2481
+ if (args.bytes.byteLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES) {
2482
+ throw new Error(
2483
+ `RNX Metro fingerprint registry exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES} bytes`
2484
+ );
2485
+ }
2486
+ const integrity = await sha256Hex(args.bytes);
2487
+ if (integrity !== args.expectedIntegrity) {
2488
+ throw new Error("RNX Metro fingerprint registry integrity mismatch");
2489
+ }
2490
+ let parsed;
2491
+ try {
2492
+ parsed = JSON.parse(new TextDecoder().decode(args.bytes));
2493
+ } catch {
2494
+ throw new Error("RNX Metro fingerprint registry is not valid JSON");
2495
+ }
2496
+ const registry = (0, import_metro_fingerprint_registry.parseRNXMetroFingerprintRegistry)(parsed);
2497
+ if (!registry) throw new Error("RNX Metro fingerprint registry is malformed");
2498
+ if (args.expectedRevision && registry.revision !== args.expectedRevision) {
2499
+ throw new Error("RNX Metro fingerprint registry revision does not match its pointer");
2500
+ }
2501
+ return { registry, integrity, source: args.source };
2502
+ }
2503
+ async function readCachedRegistry(cache, baseUrl, integrity, expectedRevision) {
2504
+ const response = await cache.match(cacheKey(baseUrl, integrity));
2505
+ if (!response?.ok) return null;
2506
+ try {
2507
+ return await parseRegistryBytes({
2508
+ bytes: new Uint8Array(await response.arrayBuffer()),
2509
+ expectedIntegrity: integrity,
2510
+ expectedRevision,
2511
+ source: "cache"
2512
+ });
2513
+ } catch {
2514
+ return null;
2515
+ }
2516
+ }
2517
+ async function readLastCachedRegistry(cache, baseUrl) {
2518
+ const memoryReceipt = memoryReceipts.get(baseUrl);
2519
+ if (!cache) return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
2520
+ const latest = await cache.match(cacheKey(baseUrl, "latest"));
2521
+ if (!latest?.ok) return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
2522
+ const integrity = latest.headers.get("x-rnx-registry-integrity");
2523
+ if (!integrity || !/^[a-f0-9]{64}$/.test(integrity)) {
2524
+ return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
2525
+ }
2526
+ return await readCachedRegistry(cache, baseUrl, integrity) ?? (memoryReceipt ? { ...memoryReceipt, source: "cache" } : null);
2527
+ }
2528
+ async function writeCachedRegistry(cache, baseUrl, bytes, receipt) {
2529
+ memoryReceipts.set(baseUrl, receipt);
2530
+ if (!cache) return;
2531
+ const headers = {
2532
+ "content-type": "application/json",
2533
+ "x-rnx-registry-integrity": receipt.integrity
2534
+ };
2535
+ try {
2536
+ await cache.put(
2537
+ cacheKey(baseUrl, receipt.integrity),
2538
+ new Response(bytes.slice(), { headers })
2539
+ );
2540
+ await cache.put(cacheKey(baseUrl, "latest"), new Response("", { headers }));
2541
+ } catch {
2542
+ }
2543
+ }
2544
+ async function readPointer(response) {
2545
+ const bytes = new Uint8Array(await response.arrayBuffer());
2546
+ if (bytes.byteLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_POINTER_BYTES) {
2547
+ throw new Error(
2548
+ `RNX Metro fingerprint pointer exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_POINTER_BYTES} bytes`
2549
+ );
2550
+ }
2551
+ let parsed;
2552
+ try {
2553
+ parsed = JSON.parse(new TextDecoder().decode(bytes));
2554
+ } catch {
2555
+ throw new Error("RNX Metro fingerprint pointer is not valid JSON");
2556
+ }
2557
+ const pointer = (0, import_metro_fingerprint_registry.parseRNXMetroFingerprintPointer)(parsed);
2558
+ if (!pointer) throw new Error("RNX Metro fingerprint pointer is malformed");
2559
+ return pointer;
2560
+ }
2561
+ async function loadMetroFingerprintRegistry(options = {}) {
2562
+ const baseUrl = pointerUrl(options);
2563
+ const request = options.fetch ?? globalThis.fetch;
2564
+ const cache = await openRegistryCache();
2565
+ let pointer;
2566
+ try {
2567
+ const response = await request(baseUrl, { cache: "no-store" });
2568
+ if (!response.ok) {
2569
+ throw new Error(`RNX Metro fingerprint pointer answered ${response.status}`);
2570
+ }
2571
+ pointer = await readPointer(response);
2572
+ } catch (error) {
2573
+ const fallback = await readLastCachedRegistry(cache, baseUrl);
2574
+ if (fallback) return fallback;
2575
+ throw error;
2576
+ }
2577
+ const memoryReceipt = memoryReceipts.get(baseUrl);
2578
+ if (memoryReceipt?.integrity === pointer.integrity && memoryReceipt.registry.revision === pointer.revision) {
2579
+ return { ...memoryReceipt, source: "cache" };
2580
+ }
2581
+ const cached3 = cache ? await readCachedRegistry(cache, baseUrl, pointer.integrity, pointer.revision) : null;
2582
+ if (cached3) {
2583
+ memoryReceipts.set(baseUrl, cached3);
2584
+ return cached3;
2585
+ }
2586
+ try {
2587
+ const payloadUrl = new URL(pointer.payloadUrl, baseUrl).toString();
2588
+ const response = await request(payloadUrl, { cache: "force-cache" });
2589
+ if (!response.ok) {
2590
+ throw new Error(`RNX Metro fingerprint registry answered ${response.status}`);
2591
+ }
2592
+ const declaredLength = Number(response.headers.get("content-length"));
2593
+ if (Number.isFinite(declaredLength) && declaredLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES) {
2594
+ throw new Error(
2595
+ `RNX Metro fingerprint registry exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES} bytes`
2596
+ );
2597
+ }
2598
+ const bytes = new Uint8Array(await response.arrayBuffer());
2599
+ if (bytes.byteLength !== pointer.bytes) {
2600
+ throw new Error(
2601
+ "RNX Metro fingerprint registry byte length does not match its pointer"
2602
+ );
2603
+ }
2604
+ const receipt = await parseRegistryBytes({
2605
+ bytes,
2606
+ expectedIntegrity: pointer.integrity,
2607
+ expectedRevision: pointer.revision,
2608
+ source: "network"
2609
+ });
2610
+ await writeCachedRegistry(cache, baseUrl, bytes, receipt);
2611
+ return receipt;
2612
+ } catch (error) {
2613
+ const fallback = await readLastCachedRegistry(cache, baseUrl);
2614
+ if (fallback) return fallback;
2615
+ throw error;
2616
+ }
2617
+ }
2618
+ var import_metro_fingerprint_registry, REGISTRY_CACHE_NAME, DEFAULT_REGISTRY_ORIGIN, memoryReceipts;
2619
+ var init_metro_fingerprint_registry_client = __esm({
2620
+ "../sootsim-engine/src/metro-fingerprint-registry-client.ts"() {
2621
+ "use strict";
2622
+ import_metro_fingerprint_registry = require("rnxsim/metro-fingerprint-registry");
2623
+ REGISTRY_CACHE_NAME = "rnx-metro-fingerprints-v1";
2624
+ DEFAULT_REGISTRY_ORIGIN = "https://contrast.dev";
2625
+ memoryReceipts = /* @__PURE__ */ new Map();
2626
+ }
2627
+ });
2628
+
2455
2629
  // ../compat/src/stub-manifest.ts
2456
2630
  var COMPAT_REACT_NATIVE_DEEP_STUBS;
2457
2631
  var init_stub_manifest = __esm({
@@ -2462,67 +2636,67 @@ var init_stub_manifest = __esm({
2462
2636
  specifier: "react-native/Libraries/Pressability/usePressability",
2463
2637
  stubFile: "rn-libraries/usePressability.ts",
2464
2638
  runtimeTier: "core",
2465
- buildResolvers: ["vite"]
2639
+ buildResolvers: ["vite", "dep-prebundle"]
2466
2640
  },
2467
2641
  pressability: {
2468
2642
  specifier: "react-native/Libraries/Pressability/Pressability",
2469
2643
  stubFile: "rn-libraries/Pressability.ts",
2470
2644
  runtimeTier: "core",
2471
- buildResolvers: ["vite"]
2645
+ buildResolvers: ["vite", "dep-prebundle"]
2472
2646
  },
2473
2647
  pressabilityDebug: {
2474
2648
  specifier: "react-native/Libraries/Pressability/PressabilityDebug",
2475
2649
  stubFile: "rn-libraries/PressabilityDebug.ts",
2476
2650
  runtimeTier: "core",
2477
- buildResolvers: ["vite"]
2651
+ buildResolvers: ["vite", "dep-prebundle"]
2478
2652
  },
2479
2653
  reactFabric: {
2480
2654
  specifier: "react-native/Libraries/Renderer/shims/ReactFabric",
2481
2655
  stubFile: "rn-libraries/ReactFabric.ts",
2482
2656
  runtimeTier: "core",
2483
- buildResolvers: ["vite"]
2657
+ buildResolvers: ["vite", "dep-prebundle"]
2484
2658
  },
2485
2659
  reactNativeRenderer: {
2486
2660
  specifier: "react-native/Libraries/Renderer/shims/ReactNative",
2487
2661
  stubFile: "rn-libraries/ReactNative.ts",
2488
2662
  runtimeTier: "core",
2489
- buildResolvers: ["vite"]
2663
+ buildResolvers: ["vite", "dep-prebundle"]
2490
2664
  },
2491
2665
  reactNativeViewConfigRegistry: {
2492
2666
  specifier: "react-native/Libraries/Renderer/shims/ReactNativeViewConfigRegistry",
2493
2667
  stubFile: "rn-libraries/ReactNativeViewConfigRegistry.ts",
2494
2668
  runtimeTier: "core",
2495
- buildResolvers: ["vite"]
2669
+ buildResolvers: ["vite", "dep-prebundle"]
2496
2670
  },
2497
2671
  appContainer: {
2498
2672
  specifier: "react-native/Libraries/ReactNative/AppContainer",
2499
2673
  stubFile: "rn-libraries/AppContainer.ts",
2500
2674
  runtimeTier: "core",
2501
- buildResolvers: ["vite"]
2675
+ buildResolvers: ["vite", "dep-prebundle"]
2502
2676
  },
2503
2677
  appRegistry: {
2504
2678
  specifier: "react-native/Libraries/ReactNative/AppRegistry",
2505
2679
  stubFile: "rn-libraries/AppRegistry.ts",
2506
2680
  runtimeTier: "core",
2507
- buildResolvers: ["vite"]
2681
+ buildResolvers: ["vite", "dep-prebundle"]
2508
2682
  },
2509
2683
  rendererImplementation: {
2510
2684
  specifier: "react-native/Libraries/ReactNative/RendererImplementation",
2511
2685
  stubFile: "rn-libraries/RendererImplementation.ts",
2512
2686
  runtimeTier: "core",
2513
- buildResolvers: ["vite"]
2687
+ buildResolvers: ["vite", "dep-prebundle"]
2514
2688
  },
2515
2689
  rendererProxy: {
2516
2690
  specifier: "react-native/Libraries/ReactNative/RendererProxy",
2517
2691
  stubFile: "rn-libraries/RendererProxy.ts",
2518
2692
  runtimeTier: "core",
2519
- buildResolvers: ["vite"]
2693
+ buildResolvers: ["vite", "dep-prebundle"]
2520
2694
  },
2521
2695
  getDevServer: {
2522
2696
  specifier: "react-native/Libraries/Core/Devtools/getDevServer",
2523
2697
  stubFile: "rn-libraries/getDevServer.ts",
2524
2698
  runtimeTier: "core",
2525
- buildResolvers: ["vite"]
2699
+ buildResolvers: ["vite", "dep-prebundle"]
2526
2700
  },
2527
2701
  codegenNativeCommands: {
2528
2702
  specifier: "react-native/Libraries/Utilities/codegenNativeCommands",
@@ -2540,19 +2714,19 @@ var init_stub_manifest = __esm({
2540
2714
  specifier: "react-native/Libraries/Image/resolveAssetSource",
2541
2715
  stubFile: "rn-libraries/resolveAssetSource.ts",
2542
2716
  runtimeTier: "core",
2543
- buildResolvers: ["vite"]
2717
+ buildResolvers: ["vite", "dep-prebundle"]
2544
2718
  },
2545
2719
  viewConfigIgnore: {
2546
2720
  specifier: "react-native/Libraries/NativeComponent/ViewConfigIgnore",
2547
2721
  stubFile: "rn-libraries/ViewConfigIgnore.ts",
2548
2722
  runtimeTier: "core",
2549
- buildResolvers: ["vite"]
2723
+ buildResolvers: ["vite", "dep-prebundle"]
2550
2724
  },
2551
2725
  nativeComponentRegistry: {
2552
2726
  specifier: "react-native/Libraries/NativeComponent/NativeComponentRegistry",
2553
2727
  stubFile: "rn-libraries/NativeComponentRegistry.ts",
2554
2728
  runtimeTier: "core",
2555
- buildResolvers: ["vite"]
2729
+ buildResolvers: ["vite", "dep-prebundle"]
2556
2730
  },
2557
2731
  // RN TurboModule spec for SourceCode. third-party libraries import
2558
2732
  // this directly to read `scriptURL`; without the deep-path stub the
@@ -2562,19 +2736,19 @@ var init_stub_manifest = __esm({
2562
2736
  specifier: "react-native/src/private/specs/modules/NativeSourceCode",
2563
2737
  stubFile: "rn-libraries/NativeSourceCode.ts",
2564
2738
  runtimeTier: "core",
2565
- buildResolvers: ["vite"]
2739
+ buildResolvers: ["vite", "dep-prebundle"]
2566
2740
  },
2567
2741
  nativeSourceCodeDeprecated: {
2568
2742
  specifier: "react-native/src/private/specs_DEPRECATED/modules/NativeSourceCode",
2569
2743
  stubFile: "rn-libraries/NativeSourceCode.ts",
2570
2744
  runtimeTier: "core",
2571
- buildResolvers: ["vite"]
2745
+ buildResolvers: ["vite", "dep-prebundle"]
2572
2746
  },
2573
2747
  nativeSourceCodeLibraries: {
2574
2748
  specifier: "react-native/Libraries/NativeModules/specs/NativeSourceCode",
2575
2749
  stubFile: "rn-libraries/NativeSourceCode.ts",
2576
2750
  runtimeTier: "core",
2577
- buildResolvers: ["vite"]
2751
+ buildResolvers: ["vite", "dep-prebundle"]
2578
2752
  },
2579
2753
  // RN TurboModule spec for the Android StatusBar. libraries import it
2580
2754
  // directly and `Object.assign` over its default export; the shim namespace
@@ -2583,13 +2757,13 @@ var init_stub_manifest = __esm({
2583
2757
  specifier: "react-native/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid",
2584
2758
  stubFile: "rn-libraries/NativeStatusBarManagerAndroid.ts",
2585
2759
  runtimeTier: "core",
2586
- buildResolvers: ["vite"]
2760
+ buildResolvers: ["vite", "dep-prebundle"]
2587
2761
  },
2588
2762
  nativeStatusBarManagerAndroidDeprecated: {
2589
2763
  specifier: "react-native/src/private/specs_DEPRECATED/modules/NativeStatusBarManagerAndroid",
2590
2764
  stubFile: "rn-libraries/NativeStatusBarManagerAndroid.ts",
2591
2765
  runtimeTier: "core",
2592
- buildResolvers: ["vite"]
2766
+ buildResolvers: ["vite", "dep-prebundle"]
2593
2767
  }
2594
2768
  };
2595
2769
  }
@@ -2792,7 +2966,7 @@ function metroFingerprintDiscriminators(input) {
2792
2966
  return { key: `${kind}:${fnv1a64(encoded)}`, cost: encoded.length };
2793
2967
  });
2794
2968
  }
2795
- async function sha256Hex(value) {
2969
+ async function sha256Hex2(value) {
2796
2970
  const bytes = new TextEncoder().encode(value);
2797
2971
  const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
2798
2972
  return [...digest].map((byte) => byte.toString(16).padStart(2, "0")).join("");
@@ -2844,7 +3018,7 @@ async function fingerprintBlindMetroBundle(source) {
2844
3018
  exports: exports2,
2845
3019
  literals,
2846
3020
  dependencyArity,
2847
- factoryDigest: await sha256Hex(canonicalFactoryForDigest(factory, literalTokens))
3021
+ factoryDigest: await sha256Hex2(canonicalFactoryForDigest(factory, literalTokens))
2848
3022
  };
2849
3023
  })
2850
3024
  );
@@ -3219,180 +3393,6 @@ var init_metro_fingerprint = __esm({
3219
3393
  }
3220
3394
  });
3221
3395
 
3222
- // ../sootsim-engine/src/metro-fingerprint-registry-client.ts
3223
- function pointerUrl(options) {
3224
- return options.pointerUrl ?? new URL(import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_POINTER_PATH, DEFAULT_REGISTRY_ORIGIN).toString();
3225
- }
3226
- async function sha256Hex2(bytes) {
3227
- const input = new Uint8Array(bytes.byteLength);
3228
- input.set(bytes);
3229
- const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", input.buffer));
3230
- return [...digest].map((byte) => byte.toString(16).padStart(2, "0")).join("");
3231
- }
3232
- async function openRegistryCache() {
3233
- if (typeof globalThis.caches?.open !== "function") return null;
3234
- try {
3235
- return await globalThis.caches.open(REGISTRY_CACHE_NAME);
3236
- } catch {
3237
- return null;
3238
- }
3239
- }
3240
- function cacheKey(baseUrl, suffix) {
3241
- const url = new URL(baseUrl);
3242
- url.pathname = `${url.pathname.replace(/\/[^/]*$/, "")}/.rnx-fingerprint-cache/${suffix}`;
3243
- url.search = "";
3244
- url.hash = "";
3245
- return new Request(url.toString());
3246
- }
3247
- async function parseRegistryBytes(args) {
3248
- if (args.bytes.byteLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES) {
3249
- throw new Error(
3250
- `RNX Metro fingerprint registry exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES} bytes`
3251
- );
3252
- }
3253
- const integrity = await sha256Hex2(args.bytes);
3254
- if (integrity !== args.expectedIntegrity) {
3255
- throw new Error("RNX Metro fingerprint registry integrity mismatch");
3256
- }
3257
- let parsed;
3258
- try {
3259
- parsed = JSON.parse(new TextDecoder().decode(args.bytes));
3260
- } catch {
3261
- throw new Error("RNX Metro fingerprint registry is not valid JSON");
3262
- }
3263
- const registry = (0, import_metro_fingerprint_registry.parseRNXMetroFingerprintRegistry)(parsed);
3264
- if (!registry) throw new Error("RNX Metro fingerprint registry is malformed");
3265
- if (args.expectedRevision && registry.revision !== args.expectedRevision) {
3266
- throw new Error("RNX Metro fingerprint registry revision does not match its pointer");
3267
- }
3268
- return { registry, integrity, source: args.source };
3269
- }
3270
- async function readCachedRegistry(cache, baseUrl, integrity, expectedRevision) {
3271
- const response = await cache.match(cacheKey(baseUrl, integrity));
3272
- if (!response?.ok) return null;
3273
- try {
3274
- return await parseRegistryBytes({
3275
- bytes: new Uint8Array(await response.arrayBuffer()),
3276
- expectedIntegrity: integrity,
3277
- expectedRevision,
3278
- source: "cache"
3279
- });
3280
- } catch {
3281
- return null;
3282
- }
3283
- }
3284
- async function readLastCachedRegistry(cache, baseUrl) {
3285
- const memoryReceipt = memoryReceipts.get(baseUrl);
3286
- if (!cache) return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
3287
- const latest = await cache.match(cacheKey(baseUrl, "latest"));
3288
- if (!latest?.ok) return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
3289
- const integrity = latest.headers.get("x-rnx-registry-integrity");
3290
- if (!integrity || !/^[a-f0-9]{64}$/.test(integrity)) {
3291
- return memoryReceipt ? { ...memoryReceipt, source: "cache" } : null;
3292
- }
3293
- return await readCachedRegistry(cache, baseUrl, integrity) ?? (memoryReceipt ? { ...memoryReceipt, source: "cache" } : null);
3294
- }
3295
- async function writeCachedRegistry(cache, baseUrl, bytes, receipt) {
3296
- memoryReceipts.set(baseUrl, receipt);
3297
- if (!cache) return;
3298
- const headers = {
3299
- "content-type": "application/json",
3300
- "x-rnx-registry-integrity": receipt.integrity
3301
- };
3302
- try {
3303
- await cache.put(
3304
- cacheKey(baseUrl, receipt.integrity),
3305
- new Response(bytes.slice(), { headers })
3306
- );
3307
- await cache.put(cacheKey(baseUrl, "latest"), new Response("", { headers }));
3308
- } catch {
3309
- }
3310
- }
3311
- async function readPointer(response) {
3312
- const bytes = new Uint8Array(await response.arrayBuffer());
3313
- if (bytes.byteLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_POINTER_BYTES) {
3314
- throw new Error(
3315
- `RNX Metro fingerprint pointer exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_POINTER_BYTES} bytes`
3316
- );
3317
- }
3318
- let parsed;
3319
- try {
3320
- parsed = JSON.parse(new TextDecoder().decode(bytes));
3321
- } catch {
3322
- throw new Error("RNX Metro fingerprint pointer is not valid JSON");
3323
- }
3324
- const pointer = (0, import_metro_fingerprint_registry.parseRNXMetroFingerprintPointer)(parsed);
3325
- if (!pointer) throw new Error("RNX Metro fingerprint pointer is malformed");
3326
- return pointer;
3327
- }
3328
- async function loadMetroFingerprintRegistry(options = {}) {
3329
- const baseUrl = pointerUrl(options);
3330
- const request = options.fetch ?? globalThis.fetch;
3331
- const cache = await openRegistryCache();
3332
- let pointer;
3333
- try {
3334
- const response = await request(baseUrl, { cache: "no-store" });
3335
- if (!response.ok) {
3336
- throw new Error(`RNX Metro fingerprint pointer answered ${response.status}`);
3337
- }
3338
- pointer = await readPointer(response);
3339
- } catch (error) {
3340
- const fallback = await readLastCachedRegistry(cache, baseUrl);
3341
- if (fallback) return fallback;
3342
- throw error;
3343
- }
3344
- const memoryReceipt = memoryReceipts.get(baseUrl);
3345
- if (memoryReceipt?.integrity === pointer.integrity && memoryReceipt.registry.revision === pointer.revision) {
3346
- return { ...memoryReceipt, source: "cache" };
3347
- }
3348
- const cached3 = cache ? await readCachedRegistry(cache, baseUrl, pointer.integrity, pointer.revision) : null;
3349
- if (cached3) {
3350
- memoryReceipts.set(baseUrl, cached3);
3351
- return cached3;
3352
- }
3353
- try {
3354
- const payloadUrl = new URL(pointer.payloadUrl, baseUrl).toString();
3355
- const response = await request(payloadUrl, { cache: "force-cache" });
3356
- if (!response.ok) {
3357
- throw new Error(`RNX Metro fingerprint registry answered ${response.status}`);
3358
- }
3359
- const declaredLength = Number(response.headers.get("content-length"));
3360
- if (Number.isFinite(declaredLength) && declaredLength > import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES) {
3361
- throw new Error(
3362
- `RNX Metro fingerprint registry exceeds ${import_metro_fingerprint_registry.RNX_METRO_FINGERPRINT_MAX_PAYLOAD_BYTES} bytes`
3363
- );
3364
- }
3365
- const bytes = new Uint8Array(await response.arrayBuffer());
3366
- if (bytes.byteLength !== pointer.bytes) {
3367
- throw new Error(
3368
- "RNX Metro fingerprint registry byte length does not match its pointer"
3369
- );
3370
- }
3371
- const receipt = await parseRegistryBytes({
3372
- bytes,
3373
- expectedIntegrity: pointer.integrity,
3374
- expectedRevision: pointer.revision,
3375
- source: "network"
3376
- });
3377
- await writeCachedRegistry(cache, baseUrl, bytes, receipt);
3378
- return receipt;
3379
- } catch (error) {
3380
- const fallback = await readLastCachedRegistry(cache, baseUrl);
3381
- if (fallback) return fallback;
3382
- throw error;
3383
- }
3384
- }
3385
- var import_metro_fingerprint_registry, REGISTRY_CACHE_NAME, DEFAULT_REGISTRY_ORIGIN, memoryReceipts;
3386
- var init_metro_fingerprint_registry_client = __esm({
3387
- "../sootsim-engine/src/metro-fingerprint-registry-client.ts"() {
3388
- "use strict";
3389
- import_metro_fingerprint_registry = require("rnxsim/metro-fingerprint-registry");
3390
- REGISTRY_CACHE_NAME = "rnx-metro-fingerprints-v1";
3391
- DEFAULT_REGISTRY_ORIGIN = "https://contrast.dev";
3392
- memoryReceipts = /* @__PURE__ */ new Map();
3393
- }
3394
- });
3395
-
3396
3396
  // src/cloud-contract.ts
3397
3397
  var RNX_CLOUD_MAX_ARTIFACT_BYTES, RNX_CLOUD_DESIGN_MAX_STORAGE_BYTES, RNX_CLOUD_COMMAND_TYPES, RNX_CLOUD_COMMAND_TYPE_SET;
3398
3398
  var init_cloud_contract = __esm({
@@ -4044,8 +4044,8 @@ var init_cloud_client = __esm({
4044
4044
  import_node_path15 = require("node:path");
4045
4045
  init_metroAssetArtifact();
4046
4046
  init_metroCloudArtifact();
4047
- init_metro_fingerprint();
4048
4047
  init_metro_fingerprint_registry_client();
4048
+ init_metro_fingerprint();
4049
4049
  init_backend_origin();
4050
4050
  init_cloud_contract();
4051
4051
  init_metro_production_bundle();
@@ -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;
@@ -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 __defProp = Object.defineProperty;
@@ -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
 
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.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;
@@ -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 __defProp = Object.defineProperty;
@@ -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;
@@ -503,13 +503,13 @@ function isDevBridgeLockfileFresh(lock, now = Date.now()) {
503
503
  }
504
504
  }
505
505
 
506
+ // ../sootsim-engine/src/metro-fingerprint-registry-client.ts
507
+ var import_metro_fingerprint_registry = require("rnxsim/metro-fingerprint-registry");
508
+
506
509
  // ../sootsim-engine/src/metro-fingerprint.ts
507
510
  var import_metro_production_bundle = require("rnxsim/metro-production-bundle");
508
511
  var import_react_native_host_modules = require("rnxsim/react-native-host-modules");
509
512
 
510
- // ../sootsim-engine/src/metro-fingerprint-registry-client.ts
511
- var import_metro_fingerprint_registry = require("rnxsim/metro-fingerprint-registry");
512
-
513
513
  // src/backend-origin.ts
514
514
  function normalizeHostname(hostname) {
515
515
  return hostname.replace(/^\[|\]$/g, "").toLowerCase();
@@ -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 __defProp = Object.defineProperty;
package/dist-lib/menu.cjs CHANGED
@@ -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 __defProp = Object.defineProperty;
@@ -178,6 +178,10 @@ function fileMenu(state, deviceChoices) {
178
178
  browserAccelerator: true,
179
179
  shortcutLabel: "start/stop recording",
180
180
  showInShortcutDocs: true
181
+ },
182
+ {
183
+ label: "Send to Box",
184
+ action: "send-to-box"
181
185
  }
182
186
  ]
183
187
  };
package/dist-lib/menu.mjs CHANGED
@@ -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
 
3
3
  // src/public-brand.ts
4
4
  var name = "rnx";
@@ -140,6 +140,10 @@ function fileMenu(state, deviceChoices) {
140
140
  browserAccelerator: true,
141
141
  shortcutLabel: "start/stop recording",
142
142
  showInShortcutDocs: true
143
+ },
144
+ {
145
+ label: "Send to Box",
146
+ action: "send-to-box"
143
147
  }
144
148
  ]
145
149
  };
@@ -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 __defProp = Object.defineProperty;
@@ -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
 
3
3
  // src/metro-fingerprint-registry.ts
4
4
  var RNX_METRO_FINGERPRINT_SCHEMA_VERSION = 2;
@@ -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 __defProp = Object.defineProperty;
@@ -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
 
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.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;