peachsim 0.1.640 → 0.1.642

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 (67) hide show
  1. package/detox/index.ts +31 -11
  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-test-args.cjs +1 -1
  22. package/dist-lib/cloud-test-args.mjs +1 -1
  23. package/dist-lib/cloud.cjs +1 -1
  24. package/dist-lib/cloud.mjs +1 -1
  25. package/dist-lib/config.cjs +1 -1
  26. package/dist-lib/detox/index.cjs +24 -4
  27. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  28. package/dist-lib/home-paths.cjs +1 -1
  29. package/dist-lib/host/bridge-host.cjs +1 -1
  30. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  31. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  32. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  33. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  34. package/dist-lib/host/websocket-proxy.cjs +1 -1
  35. package/dist-lib/index.cjs +1 -1
  36. package/dist-lib/jump-to-source-babel.cjs +1 -1
  37. package/dist-lib/jump-to-source-native.cjs +1 -1
  38. package/dist-lib/kotlin-host.cjs +1 -1
  39. package/dist-lib/menu.cjs +1 -1
  40. package/dist-lib/menu.mjs +1 -1
  41. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  42. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  43. package/dist-lib/metro-production-bundle.cjs +1 -1
  44. package/dist-lib/metro-production-bundle.mjs +1 -1
  45. package/dist-lib/metro.cjs +1 -1
  46. package/dist-lib/native-app-identity.cjs +1 -1
  47. package/dist-lib/native-app-identity.mjs +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 +1 -1
  57. package/dist-lib/swift-compile.cjs +39 -12
  58. package/dist-lib/swift-compile.mjs +39 -12
  59. package/dist-lib/swift-package.cjs +1 -1
  60. package/dist-lib/swift-package.mjs +1 -1
  61. package/dist-lib/swift-submit.cjs +1 -1
  62. package/dist-lib/swift-submit.mjs +1 -1
  63. package/dist-lib/swift.cjs +1 -1
  64. package/dist-lib/vite-swift.cjs +40 -13
  65. package/dist-lib/vite.cjs +1 -1
  66. package/package.json +1 -1
  67. package/src/swift-compile.ts +55 -14
package/detox/index.ts CHANGED
@@ -2232,6 +2232,7 @@ export const device = {
2232
2232
  }
2233
2233
  lockstepCapture?: {
2234
2234
  begin: (fps: number) => Promise<{
2235
+ readonly initialFrame: FrameReceipt
2235
2236
  stepFrame: () => Promise<FrameReceipt>
2236
2237
  stepToOffset: (
2237
2238
  anchor: FrameReceipt,
@@ -2422,8 +2423,28 @@ export const device = {
2422
2423
  let detectedMeasurement: MotionChangeMeasurement | null = null
2423
2424
  let previousReceipt: FrameReceipt | null = null
2424
2425
  let previousBitmap: ImageBitmap | null = null
2426
+ // android can publish mount layout at p=0 before a clock step.
2427
+ if (input.platform === 'android') {
2428
+ const candidateBitmap = await captureBitmap()
2429
+ const bounds = boundsFor(candidateBitmap)
2430
+ const measurement = measureChange({
2431
+ baseline,
2432
+ candidate: regionPixels(candidateBitmap),
2433
+ definition: input.motionChangeDefinition,
2434
+ height: bounds.height,
2435
+ label: 'peach initial-frame visible-change detector',
2436
+ width: bounds.width,
2437
+ })
2438
+ if (measurement.passedMinimum) {
2439
+ visibleStart = controller.initialFrame
2440
+ detectedMeasurement = measurement
2441
+ keptFrames.set(visibleStart.frameIndex, candidateBitmap)
2442
+ } else {
2443
+ candidateBitmap.close()
2444
+ }
2445
+ }
2425
2446
  const detectionFrameLimit = Math.ceil((input.detectionTimeoutMs * 60) / 1000)
2426
- for (let frame = 0; frame < detectionFrameLimit; frame++) {
2447
+ for (let frame = 0; !visibleStart && frame < detectionFrameLimit; frame++) {
2427
2448
  if (state.cancelled) throw new Error('peach motion capture was cancelled')
2428
2449
  const receipt = await controller.stepFrame()
2429
2450
  await advanceHold(receipt)
@@ -2455,15 +2476,13 @@ export const device = {
2455
2476
  `peach motion had no visible change before ${input.detectionTimeoutMs}ms`,
2456
2477
  )
2457
2478
  }
2458
- // the drive started on the tick the tap landed, which renders no
2459
- // visible change: the transition opens at p=0 with the snapshot
2460
- // identical to the source view still underneath it, so the gate
2461
- // cannot trip before the morph's first tick. stages measure from
2462
- // that tap tick (or the change itself when the first stepped frame
2463
- // already moves). native's tap tick trips the gate on the touch
2464
- // highlight, so its onset frame is the same event tick: same
2465
- // event, per-leg rule, not same gate side.
2466
- const driveStart = previousReceipt ?? visibleStart
2479
+ // android screenrecord stages measure from the detected frame.
2480
+ // ios morphs retain the preceding event tick: the browser paints
2481
+ // p=0 unchanged while native's touch highlight trips its gate.
2482
+ const driveStart =
2483
+ input.platform === 'android'
2484
+ ? visibleStart
2485
+ : (previousReceipt ?? visibleStart)
2467
2486
  let currentReceipt = visibleStart
2468
2487
  const resolvedAnchors = new Map<string, FrameReceipt>()
2469
2488
  const anchorRecords: Array<{
@@ -2584,7 +2603,7 @@ export const device = {
2584
2603
  const stageFrameIndex =
2585
2604
  anchorReceipt.frameIndex + Math.ceil(stage.offsetMs / frameMs)
2586
2605
  const kept = keptFrames.get(stageFrameIndex)
2587
- if (kept && stageFrameIndex < currentReceipt.frameIndex) {
2606
+ if (kept && stageFrameIndex <= currentReceipt.frameIndex) {
2588
2607
  snapshots.push({
2589
2608
  actualMs: 0,
2590
2609
  anchorId,
@@ -2665,6 +2684,7 @@ export const device = {
2665
2684
  frame: options.frame ?? null,
2666
2685
  hold: options.hold ?? null,
2667
2686
  motionChangeDefinition: MOTION_CHANGE_DEFINITION,
2687
+ platform: device.getPlatform(),
2668
2688
  rootFrame: options.rootFrame ?? null,
2669
2689
  settleMs,
2670
2690
  stages,
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var REFUSED_PERFORM_STEP_TYPES = [
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/cloud-test-args.ts
4
4
  var CLOUD_TEST_ARGS_MAX_COUNT = 32;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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;
@@ -3707,8 +3707,27 @@ var device = {
3707
3707
  let detectedMeasurement = null;
3708
3708
  let previousReceipt = null;
3709
3709
  let previousBitmap = null;
3710
+ if (input.platform === "android") {
3711
+ const candidateBitmap = await captureBitmap();
3712
+ const bounds = boundsFor(candidateBitmap);
3713
+ const measurement = measureChange({
3714
+ baseline,
3715
+ candidate: regionPixels(candidateBitmap),
3716
+ definition: input.motionChangeDefinition,
3717
+ height: bounds.height,
3718
+ label: "peach initial-frame visible-change detector",
3719
+ width: bounds.width
3720
+ });
3721
+ if (measurement.passedMinimum) {
3722
+ visibleStart = controller.initialFrame;
3723
+ detectedMeasurement = measurement;
3724
+ keptFrames.set(visibleStart.frameIndex, candidateBitmap);
3725
+ } else {
3726
+ candidateBitmap.close();
3727
+ }
3728
+ }
3710
3729
  const detectionFrameLimit = Math.ceil(input.detectionTimeoutMs * 60 / 1e3);
3711
- for (let frame = 0; frame < detectionFrameLimit; frame++) {
3730
+ for (let frame = 0; !visibleStart && frame < detectionFrameLimit; frame++) {
3712
3731
  if (state.cancelled) throw new Error("peach motion capture was cancelled");
3713
3732
  const receipt = await controller.stepFrame();
3714
3733
  await advanceHold(receipt);
@@ -3740,7 +3759,7 @@ var device = {
3740
3759
  `peach motion had no visible change before ${input.detectionTimeoutMs}ms`
3741
3760
  );
3742
3761
  }
3743
- const driveStart = previousReceipt ?? visibleStart;
3762
+ const driveStart = input.platform === "android" ? visibleStart : previousReceipt ?? visibleStart;
3744
3763
  let currentReceipt = visibleStart;
3745
3764
  const resolvedAnchors = /* @__PURE__ */ new Map();
3746
3765
  const anchorRecords = [];
@@ -3832,7 +3851,7 @@ var device = {
3832
3851
  const { anchorId, receipt: anchorReceipt } = await resolveAnchor(stage);
3833
3852
  const stageFrameIndex = anchorReceipt.frameIndex + Math.ceil(stage.offsetMs / frameMs);
3834
3853
  const kept = keptFrames.get(stageFrameIndex);
3835
- if (kept && stageFrameIndex < currentReceipt.frameIndex) {
3854
+ if (kept && stageFrameIndex <= currentReceipt.frameIndex) {
3836
3855
  snapshots.push({
3837
3856
  actualMs: 0,
3838
3857
  anchorId,
@@ -3905,6 +3924,7 @@ var device = {
3905
3924
  frame: options.frame ?? null,
3906
3925
  hold: options.hold ?? null,
3907
3926
  motionChangeDefinition: import_motion_change.MOTION_CHANGE_DEFINITION,
3927
+ platform: device.getPlatform(),
3908
3928
  rootFrame: options.rootFrame ?? null,
3909
3929
  settleMs,
3910
3930
  stages,
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/public-brand.ts
4
4
  var name = "Peach";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/is-record.ts
4
4
  function isRecord(value) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/native-app-identity.ts
4
4
  var NATIVE_APP_IDENTITY_PREFIX = "globalThis.__sootsimNativeAppIdentity=";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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;
@@ -317,11 +317,12 @@ function swiftSiblingDependencies(files, targets) {
317
317
  return siblings;
318
318
  }
319
319
  var ONE_PRODUCT = '.product(name: "One", package: "sootsim-swift")';
320
+ var OBJC_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "PeachObjC"';
320
321
  var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"';
321
- var MULTI_MANIFEST_VERSION = 5;
322
+ var MULTI_MANIFEST_VERSION = 6;
322
323
  function swiftArtifactHash(input, release, moduleRoot) {
323
324
  const hash = (0, import_node_crypto2.createHash)("sha256");
324
- hash.update(`swift-compile/v3
325
+ hash.update(`swift-compile/v4
325
326
  ${release}
326
327
  `);
327
328
  if (input.oneModule) hash.update("one-module\n");
@@ -364,7 +365,7 @@ function emitSwiftPackageManifest(args) {
364
365
  if (!executable) throw new Error("swift-compile: no executable target to emit");
365
366
  const stanza = (target) => {
366
367
  const isolation = target.mainActorIsolation ? " .defaultIsolation(MainActor.self)," : "";
367
- const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${oneModule ? ONE_IMPLICIT_FLAGS : ""}])]`;
368
+ const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${OBJC_IMPLICIT_FLAGS}${oneModule ? ONE_IMPLICIT_FLAGS : ""}])]`;
368
369
  const deps = [
369
370
  '.product(name: "SwiftUI", package: "sootsim-swift")',
370
371
  ...oneModule ? [ONE_PRODUCT] : [],
@@ -423,18 +424,38 @@ function syncSwiftTree(base, files) {
423
424
  }
424
425
  var DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/;
425
426
  var OS_IOS = /\bos\(\s*iOS\s*\)/g;
427
+ var OBJC_ATTRIBUTE = /^@(?:objcMembers\b|objc\b(?:(\s*)\(([^()]*)\))?|IBAction\b)/;
428
+ var SELECTOR = /^#selector\b/;
426
429
  function swiftSourceAsIOS(source) {
427
- const code = swiftCodeLineStarts(source);
430
+ const { lineStarts, tokens } = swiftCodeScan(source);
428
431
  let offset = 0;
429
- return source.split("\n").map((line) => {
432
+ const conditioned = source.split("\n").map((line) => {
430
433
  const start = offset;
431
434
  offset += line.length + 1;
432
- if (!code.has(start) || !DIRECTIVE.test(line)) return line;
435
+ if (!lineStarts.has(start) || !DIRECTIVE.test(line)) return line;
433
436
  return line.replace(OS_IOS, (match) => "true".padEnd(match.length));
434
437
  }).join("\n");
438
+ let out = "";
439
+ let copied = 0;
440
+ for (const at of tokens) {
441
+ const rest = conditioned.slice(at, at + 200);
442
+ const selector = SELECTOR.exec(rest);
443
+ const match = selector ?? OBJC_ATTRIBUTE.exec(rest);
444
+ if (!match) continue;
445
+ let replacement = "@ObjC";
446
+ if (selector) replacement = "#Selector";
447
+ else if (match[0] === "@objcMembers") replacement = "@ObjCMembers";
448
+ else if (match[0] === "@IBAction") replacement = "@ObjC".padEnd(match[0].length);
449
+ else if (match[2] !== void 0)
450
+ replacement = `@ObjC${match[1]}("${match[2].trim()}")`;
451
+ out += conditioned.slice(copied, at) + replacement;
452
+ copied = at + match[0].length;
453
+ }
454
+ return out + conditioned.slice(copied);
435
455
  }
436
- function swiftCodeLineStarts(source) {
456
+ function swiftCodeScan(source) {
437
457
  const starts = /* @__PURE__ */ new Set();
458
+ const tokens = [];
438
459
  const stack = [{ kind: "code", parens: 0 }];
439
460
  const hashesAt = (at) => {
440
461
  let end = at;
@@ -499,7 +520,10 @@ function swiftCodeLineStarts(source) {
499
520
  } else if (hashes > 0 && source[at] === "/") {
500
521
  stack.push({ kind: "regex", hashes });
501
522
  i = at + 1;
502
- } else i = Math.max(at, i + 1);
523
+ } else {
524
+ if (hashes > 0) tokens.push(at - 1);
525
+ i = Math.max(at, i + 1);
526
+ }
503
527
  } else if (char === "(") {
504
528
  top.parens++;
505
529
  i++;
@@ -507,9 +531,12 @@ function swiftCodeLineStarts(source) {
507
531
  if (top.parens === 0 && stack.length > 1) stack.pop();
508
532
  else top.parens--;
509
533
  i++;
510
- } else i++;
534
+ } else {
535
+ if (char === "@") tokens.push(i);
536
+ i++;
537
+ }
511
538
  }
512
- return starts;
539
+ return { lineStarts: starts, tokens };
513
540
  }
514
541
  var compiledSource = (file, contents) => file.endsWith(".swift") ? swiftSourceAsIOS(contents) : contents;
515
542
  function writeSwiftProject(layout, input, moduleRoot) {
@@ -526,7 +553,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
526
553
  ).replaceAll("__SOOTSIM_SWIFT_PACKAGE__", moduleRoot);
527
554
  if (input.oneModule) {
528
555
  const product = '.product(name: "CoreLocation", package: "sootsim-swift"),';
529
- const flags = '"-Osize"';
556
+ const flags = `"-Osize"${OBJC_IMPLICIT_FLAGS}`;
530
557
  if (!manifest.includes(product) || !manifest.includes(flags)) {
531
558
  throw new Error(
532
559
  "scripts/contrast-app-Package.swift lost the lines the One module links at"
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-compile.ts
4
4
  import { execFile as execFile2 } from "node:child_process";
@@ -282,11 +282,12 @@ function swiftSiblingDependencies(files, targets) {
282
282
  return siblings;
283
283
  }
284
284
  var ONE_PRODUCT = '.product(name: "One", package: "sootsim-swift")';
285
+ var OBJC_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "PeachObjC"';
285
286
  var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"';
286
- var MULTI_MANIFEST_VERSION = 5;
287
+ var MULTI_MANIFEST_VERSION = 6;
287
288
  function swiftArtifactHash(input, release, moduleRoot) {
288
289
  const hash = createHash2("sha256");
289
- hash.update(`swift-compile/v3
290
+ hash.update(`swift-compile/v4
290
291
  ${release}
291
292
  `);
292
293
  if (input.oneModule) hash.update("one-module\n");
@@ -329,7 +330,7 @@ function emitSwiftPackageManifest(args) {
329
330
  if (!executable) throw new Error("swift-compile: no executable target to emit");
330
331
  const stanza = (target) => {
331
332
  const isolation = target.mainActorIsolation ? " .defaultIsolation(MainActor.self)," : "";
332
- const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${oneModule ? ONE_IMPLICIT_FLAGS : ""}])]`;
333
+ const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${OBJC_IMPLICIT_FLAGS}${oneModule ? ONE_IMPLICIT_FLAGS : ""}])]`;
333
334
  const deps = [
334
335
  '.product(name: "SwiftUI", package: "sootsim-swift")',
335
336
  ...oneModule ? [ONE_PRODUCT] : [],
@@ -388,18 +389,38 @@ function syncSwiftTree(base, files) {
388
389
  }
389
390
  var DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/;
390
391
  var OS_IOS = /\bos\(\s*iOS\s*\)/g;
392
+ var OBJC_ATTRIBUTE = /^@(?:objcMembers\b|objc\b(?:(\s*)\(([^()]*)\))?|IBAction\b)/;
393
+ var SELECTOR = /^#selector\b/;
391
394
  function swiftSourceAsIOS(source) {
392
- const code = swiftCodeLineStarts(source);
395
+ const { lineStarts, tokens } = swiftCodeScan(source);
393
396
  let offset = 0;
394
- return source.split("\n").map((line) => {
397
+ const conditioned = source.split("\n").map((line) => {
395
398
  const start = offset;
396
399
  offset += line.length + 1;
397
- if (!code.has(start) || !DIRECTIVE.test(line)) return line;
400
+ if (!lineStarts.has(start) || !DIRECTIVE.test(line)) return line;
398
401
  return line.replace(OS_IOS, (match) => "true".padEnd(match.length));
399
402
  }).join("\n");
403
+ let out = "";
404
+ let copied = 0;
405
+ for (const at of tokens) {
406
+ const rest = conditioned.slice(at, at + 200);
407
+ const selector = SELECTOR.exec(rest);
408
+ const match = selector ?? OBJC_ATTRIBUTE.exec(rest);
409
+ if (!match) continue;
410
+ let replacement = "@ObjC";
411
+ if (selector) replacement = "#Selector";
412
+ else if (match[0] === "@objcMembers") replacement = "@ObjCMembers";
413
+ else if (match[0] === "@IBAction") replacement = "@ObjC".padEnd(match[0].length);
414
+ else if (match[2] !== void 0)
415
+ replacement = `@ObjC${match[1]}("${match[2].trim()}")`;
416
+ out += conditioned.slice(copied, at) + replacement;
417
+ copied = at + match[0].length;
418
+ }
419
+ return out + conditioned.slice(copied);
400
420
  }
401
- function swiftCodeLineStarts(source) {
421
+ function swiftCodeScan(source) {
402
422
  const starts = /* @__PURE__ */ new Set();
423
+ const tokens = [];
403
424
  const stack = [{ kind: "code", parens: 0 }];
404
425
  const hashesAt = (at) => {
405
426
  let end = at;
@@ -464,7 +485,10 @@ function swiftCodeLineStarts(source) {
464
485
  } else if (hashes > 0 && source[at] === "/") {
465
486
  stack.push({ kind: "regex", hashes });
466
487
  i = at + 1;
467
- } else i = Math.max(at, i + 1);
488
+ } else {
489
+ if (hashes > 0) tokens.push(at - 1);
490
+ i = Math.max(at, i + 1);
491
+ }
468
492
  } else if (char === "(") {
469
493
  top.parens++;
470
494
  i++;
@@ -472,9 +496,12 @@ function swiftCodeLineStarts(source) {
472
496
  if (top.parens === 0 && stack.length > 1) stack.pop();
473
497
  else top.parens--;
474
498
  i++;
475
- } else i++;
499
+ } else {
500
+ if (char === "@") tokens.push(i);
501
+ i++;
502
+ }
476
503
  }
477
- return starts;
504
+ return { lineStarts: starts, tokens };
478
505
  }
479
506
  var compiledSource = (file, contents) => file.endsWith(".swift") ? swiftSourceAsIOS(contents) : contents;
480
507
  function writeSwiftProject(layout, input, moduleRoot) {
@@ -491,7 +518,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
491
518
  ).replaceAll("__SOOTSIM_SWIFT_PACKAGE__", moduleRoot);
492
519
  if (input.oneModule) {
493
520
  const product = '.product(name: "CoreLocation", package: "sootsim-swift"),';
494
- const flags = '"-Osize"';
521
+ const flags = `"-Osize"${OBJC_IMPLICIT_FLAGS}`;
495
522
  if (!manifest.includes(product) || !manifest.includes(flags)) {
496
523
  throw new Error(
497
524
  "scripts/contrast-app-Package.swift lost the lines the One module links at"
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-package.ts
4
4
  function isSwiftManifestFile(file) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-submit.ts
4
4
  var SWIFT_COMPILE_PATH = "/api/swift-compile";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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;
@@ -817,11 +817,12 @@ function swiftSiblingDependencies(files, targets) {
817
817
  return siblings;
818
818
  }
819
819
  var ONE_PRODUCT = '.product(name: "One", package: "sootsim-swift")';
820
+ var OBJC_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "PeachObjC"';
820
821
  var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"';
821
- var MULTI_MANIFEST_VERSION = 5;
822
+ var MULTI_MANIFEST_VERSION = 6;
822
823
  function swiftArtifactHash(input, release, moduleRoot) {
823
824
  const hash = (0, import_node_crypto2.createHash)("sha256");
824
- hash.update(`swift-compile/v3
825
+ hash.update(`swift-compile/v4
825
826
  ${release}
826
827
  `);
827
828
  if (input.oneModule) hash.update("one-module\n");
@@ -864,7 +865,7 @@ function emitSwiftPackageManifest(args) {
864
865
  if (!executable) throw new Error("swift-compile: no executable target to emit");
865
866
  const stanza = (target) => {
866
867
  const isolation = target.mainActorIsolation ? " .defaultIsolation(MainActor.self)," : "";
867
- const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${oneModule ? ONE_IMPLICIT_FLAGS : ""}])]`;
868
+ const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${OBJC_IMPLICIT_FLAGS}${oneModule ? ONE_IMPLICIT_FLAGS : ""}])]`;
868
869
  const deps = [
869
870
  '.product(name: "SwiftUI", package: "sootsim-swift")',
870
871
  ...oneModule ? [ONE_PRODUCT] : [],
@@ -923,18 +924,38 @@ function syncSwiftTree(base, files) {
923
924
  }
924
925
  var DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/;
925
926
  var OS_IOS = /\bos\(\s*iOS\s*\)/g;
927
+ var OBJC_ATTRIBUTE = /^@(?:objcMembers\b|objc\b(?:(\s*)\(([^()]*)\))?|IBAction\b)/;
928
+ var SELECTOR = /^#selector\b/;
926
929
  function swiftSourceAsIOS(source) {
927
- const code = swiftCodeLineStarts(source);
930
+ const { lineStarts, tokens } = swiftCodeScan(source);
928
931
  let offset = 0;
929
- return source.split("\n").map((line) => {
932
+ const conditioned = source.split("\n").map((line) => {
930
933
  const start = offset;
931
934
  offset += line.length + 1;
932
- if (!code.has(start) || !DIRECTIVE.test(line)) return line;
935
+ if (!lineStarts.has(start) || !DIRECTIVE.test(line)) return line;
933
936
  return line.replace(OS_IOS, (match) => "true".padEnd(match.length));
934
937
  }).join("\n");
935
- }
936
- function swiftCodeLineStarts(source) {
938
+ let out = "";
939
+ let copied = 0;
940
+ for (const at of tokens) {
941
+ const rest = conditioned.slice(at, at + 200);
942
+ const selector = SELECTOR.exec(rest);
943
+ const match = selector ?? OBJC_ATTRIBUTE.exec(rest);
944
+ if (!match) continue;
945
+ let replacement = "@ObjC";
946
+ if (selector) replacement = "#Selector";
947
+ else if (match[0] === "@objcMembers") replacement = "@ObjCMembers";
948
+ else if (match[0] === "@IBAction") replacement = "@ObjC".padEnd(match[0].length);
949
+ else if (match[2] !== void 0)
950
+ replacement = `@ObjC${match[1]}("${match[2].trim()}")`;
951
+ out += conditioned.slice(copied, at) + replacement;
952
+ copied = at + match[0].length;
953
+ }
954
+ return out + conditioned.slice(copied);
955
+ }
956
+ function swiftCodeScan(source) {
937
957
  const starts = /* @__PURE__ */ new Set();
958
+ const tokens = [];
938
959
  const stack = [{ kind: "code", parens: 0 }];
939
960
  const hashesAt = (at) => {
940
961
  let end = at;
@@ -999,7 +1020,10 @@ function swiftCodeLineStarts(source) {
999
1020
  } else if (hashes > 0 && source[at] === "/") {
1000
1021
  stack.push({ kind: "regex", hashes });
1001
1022
  i = at + 1;
1002
- } else i = Math.max(at, i + 1);
1023
+ } else {
1024
+ if (hashes > 0) tokens.push(at - 1);
1025
+ i = Math.max(at, i + 1);
1026
+ }
1003
1027
  } else if (char === "(") {
1004
1028
  top.parens++;
1005
1029
  i++;
@@ -1007,9 +1031,12 @@ function swiftCodeLineStarts(source) {
1007
1031
  if (top.parens === 0 && stack.length > 1) stack.pop();
1008
1032
  else top.parens--;
1009
1033
  i++;
1010
- } else i++;
1034
+ } else {
1035
+ if (char === "@") tokens.push(i);
1036
+ i++;
1037
+ }
1011
1038
  }
1012
- return starts;
1039
+ return { lineStarts: starts, tokens };
1013
1040
  }
1014
1041
  var compiledSource = (file, contents) => file.endsWith(".swift") ? swiftSourceAsIOS(contents) : contents;
1015
1042
  function writeSwiftProject(layout, input, moduleRoot) {
@@ -1026,7 +1053,7 @@ function writeSwiftProject(layout, input, moduleRoot) {
1026
1053
  ).replaceAll("__SOOTSIM_SWIFT_PACKAGE__", moduleRoot);
1027
1054
  if (input.oneModule) {
1028
1055
  const product = '.product(name: "CoreLocation", package: "sootsim-swift"),';
1029
- const flags = '"-Osize"';
1056
+ const flags = `"-Osize"${OBJC_IMPLICIT_FLAGS}`;
1030
1057
  if (!manifest.includes(product) || !manifest.includes(flags)) {
1031
1058
  throw new Error(
1032
1059
  "scripts/contrast-app-Package.swift lost the lines the One module links at"
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.640 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.642 | (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": "peachsim",
3
- "version": "0.1.640",
3
+ "version": "0.1.642",
4
4
  "description": "Vite and Metro plugins, testing drivers, and SDK exports for peach.",
5
5
  "author": "Tamagui LLC",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -213,10 +213,15 @@ function swiftSiblingDependencies(
213
213
  }
214
214
 
215
215
  const ONE_PRODUCT = '.product(name: "One", package: "sootsim-swift")'
216
+ // every iOS source sees the ObjectiveC module's selectors through Foundation;
217
+ // PeachObjC stands in for it, so a source that imports only Foundation still
218
+ // compiles `@objc` and `#selector`. scripts/contrast-app-Package.swift and
219
+ // example/Package.swift carry the same flags.
220
+ const OBJC_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "PeachObjC"'
216
221
  const ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"'
217
222
 
218
223
  /** bump with any change to the emitted multi-target manifest text. */
219
- export const MULTI_MANIFEST_VERSION = 5
224
+ export const MULTI_MANIFEST_VERSION = 6
220
225
 
221
226
  export function swiftArtifactHash(
222
227
  input: SwiftCompileInput,
@@ -224,8 +229,9 @@ export function swiftArtifactHash(
224
229
  moduleRoot: string,
225
230
  ): string {
226
231
  const hash = createHash('sha256')
227
- // v3: sources compile with os(iOS) true on code lines (swiftSourceAsIOS)
228
- hash.update(`swift-compile/v3\n${release}\n`)
232
+ // v4: sources compile through swiftSourceAsIOS (os(iOS) true on code
233
+ // lines, @objc and #selector as the module's macros)
234
+ hash.update(`swift-compile/v4\n${release}\n`)
229
235
  if (input.oneModule) hash.update('one-module\n')
230
236
  hash.update(linkedModuleDigest(moduleRoot))
231
237
  for (const file of Object.keys(input.files).sort()) {
@@ -277,7 +283,7 @@ export function emitSwiftPackageManifest(args: {
277
283
  const isolation = target.mainActorIsolation
278
284
  ? ' .defaultIsolation(MainActor.self),'
279
285
  : ''
280
- const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${oneModule ? ONE_IMPLICIT_FLAGS : ''}])]`
286
+ const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${OBJC_IMPLICIT_FLAGS}${oneModule ? ONE_IMPLICIT_FLAGS : ''}])]`
281
287
  const deps = [
282
288
  '.product(name: "SwiftUI", package: "sootsim-swift")',
283
289
  ...(oneModule ? [ONE_PRODUCT] : []),
@@ -349,24 +355,52 @@ function syncSwiftTree(base: string, files: Map<string, string>): void {
349
355
  // os(WASI) still holds for code written for wasm. only `#if` and `#elseif`
350
356
  // lines that begin in code change: a line inside a string literal or a block
351
357
  // comment is content. the artifact hash stays over the original text.
358
+ //
359
+ // wasm Swift has no ObjC runtime, so `@objc` and `#selector` do not compile.
360
+ // in code (never in a string, comment or regex) `@objc` becomes `@ObjC`,
361
+ // `@objcMembers` `@ObjCMembers`, `@IBAction` `@ObjC` padded, and `#selector(`
362
+ // `#Selector(`: the module's macros that expose a method to selector dispatch
363
+ // (plans/peach/uikit-shell.md, gate B). all keep their width except an
364
+ // explicit `@objc(name:)`, whose name becomes a string argument.
352
365
  const DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/
353
366
  const OS_IOS = /\bos\(\s*iOS\s*\)/g
367
+ const OBJC_ATTRIBUTE = /^@(?:objcMembers\b|objc\b(?:(\s*)\(([^()]*)\))?|IBAction\b)/
368
+ const SELECTOR = /^#selector\b/
354
369
  export function swiftSourceAsIOS(source: string): string {
355
- const code = swiftCodeLineStarts(source)
370
+ const { lineStarts, tokens } = swiftCodeScan(source)
356
371
  let offset = 0
357
- return source
372
+ // equal width, so every token offset still holds
373
+ const conditioned = source
358
374
  .split('\n')
359
375
  .map((line) => {
360
376
  const start = offset
361
377
  offset += line.length + 1
362
- if (!code.has(start) || !DIRECTIVE.test(line)) return line
378
+ if (!lineStarts.has(start) || !DIRECTIVE.test(line)) return line
363
379
  return line.replace(OS_IOS, (match) => 'true'.padEnd(match.length))
364
380
  })
365
381
  .join('\n')
382
+ let out = ''
383
+ let copied = 0
384
+ for (const at of tokens) {
385
+ const rest = conditioned.slice(at, at + 200)
386
+ const selector = SELECTOR.exec(rest)
387
+ const match = selector ?? OBJC_ATTRIBUTE.exec(rest)
388
+ if (!match) continue
389
+ let replacement = '@ObjC'
390
+ if (selector) replacement = '#Selector'
391
+ else if (match[0] === '@objcMembers') replacement = '@ObjCMembers'
392
+ else if (match[0] === '@IBAction') replacement = '@ObjC'.padEnd(match[0].length)
393
+ else if (match[2] !== undefined)
394
+ replacement = `@ObjC${match[1]}("${match[2].trim()}")`
395
+ out += conditioned.slice(copied, at) + replacement
396
+ copied = at + match[0].length
397
+ }
398
+ return out + conditioned.slice(copied)
366
399
  }
367
400
 
368
- // the offsets of the lines that begin in code, from a scan of Swift's lexical
369
- // contexts: nested block comments, line comments, string literals (single and
401
+ // the offsets of the lines that begin in code, and of every `@` and `#` that
402
+ // stands in code (an interpolation's code included), from a scan of Swift's
403
+ // lexical contexts: nested block comments, line comments, string literals (single and
370
404
  // multiline, raw with any number of #, interpolations holding code and
371
405
  // strings of their own) and #/ /# regex literals. a bare /regex/ literal
372
406
  // reads as code.
@@ -375,8 +409,9 @@ type Lexical =
375
409
  | { kind: 'block'; depth: number }
376
410
  | { kind: 'string'; hashes: number; multiline: boolean }
377
411
  | { kind: 'regex'; hashes: number }
378
- function swiftCodeLineStarts(source: string): Set<number> {
412
+ function swiftCodeScan(source: string): { lineStarts: Set<number>; tokens: number[] } {
379
413
  const starts = new Set<number>()
414
+ const tokens: number[] = []
380
415
  const stack: Lexical[] = [{ kind: 'code', parens: 0 }]
381
416
  const hashesAt = (at: number) => {
382
417
  let end = at
@@ -441,7 +476,10 @@ function swiftCodeLineStarts(source: string): Set<number> {
441
476
  } else if (hashes > 0 && source[at] === '/') {
442
477
  stack.push({ kind: 'regex', hashes })
443
478
  i = at + 1
444
- } else i = Math.max(at, i + 1)
479
+ } else {
480
+ if (hashes > 0) tokens.push(at - 1)
481
+ i = Math.max(at, i + 1)
482
+ }
445
483
  } else if (char === '(') {
446
484
  top.parens++
447
485
  i++
@@ -449,9 +487,12 @@ function swiftCodeLineStarts(source: string): Set<number> {
449
487
  if (top.parens === 0 && stack.length > 1) stack.pop()
450
488
  else top.parens--
451
489
  i++
452
- } else i++
490
+ } else {
491
+ if (char === '@') tokens.push(i)
492
+ i++
493
+ }
453
494
  }
454
- return starts
495
+ return { lineStarts: starts, tokens }
455
496
  }
456
497
 
457
498
  const compiledSource = (file: string, contents: string) =>
@@ -477,7 +518,7 @@ export function writeSwiftProject(
477
518
  // anchored on lines the template already has, so the template stays a
478
519
  // valid manifest for a compiler build that predates the One module
479
520
  const product = '.product(name: "CoreLocation", package: "sootsim-swift"),'
480
- const flags = '"-Osize"'
521
+ const flags = `"-Osize"${OBJC_IMPLICIT_FLAGS}`
481
522
  if (!manifest.includes(product) || !manifest.includes(flags)) {
482
523
  throw new Error(
483
524
  'scripts/contrast-app-Package.swift lost the lines the One module links at',