peachsim 0.1.939 → 0.1.1399

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 (396) hide show
  1. package/README.md +28 -22
  2. package/cli/app-catalog.ts +29 -14
  3. package/cli/app-fonts.ts +5 -3
  4. package/cli/bridge-flow-runner.ts +40 -29
  5. package/cli/cloud-client.ts +57 -21
  6. package/cli/cloud-test-tunnel.ts +12 -18
  7. package/cli/commands/agent.ts +1 -1
  8. package/cli/commands/app-fonts.ts +3 -3
  9. package/cli/commands/assert.ts +8 -8
  10. package/cli/commands/auth.ts +8 -3
  11. package/cli/commands/box/bundle-plane.ts +13 -1
  12. package/cli/commands/box.ts +16 -5
  13. package/cli/commands/compat.ts +1 -1
  14. package/cli/commands/config.ts +2 -2
  15. package/cli/commands/control.ts +125 -71
  16. package/cli/commands/cpu-profile.ts +45 -1
  17. package/cli/commands/daemon.ts +131 -33
  18. package/cli/commands/debug.ts +24 -17
  19. package/cli/commands/desktop.ts +7 -1
  20. package/cli/commands/detect.ts +101 -0
  21. package/cli/commands/detox.ts +6 -6
  22. package/cli/commands/device.ts +12 -12
  23. package/cli/commands/electron.ts +32 -14
  24. package/cli/commands/flow.ts +49 -41
  25. package/cli/commands/guest-host.ts +39 -1
  26. package/cli/commands/inspect/core.ts +14 -8
  27. package/cli/commands/inspect/list.ts +1 -1
  28. package/cli/commands/inspect/settle.ts +5 -3
  29. package/cli/commands/inspect/settling.ts +229 -44
  30. package/cli/commands/inspect/wait-idle.ts +3 -2
  31. package/cli/commands/inspect.ts +105 -93
  32. package/cli/commands/install-cli.ts +36 -15
  33. package/cli/commands/install-desktop.ts +68 -195
  34. package/cli/commands/kotlin.ts +6 -5
  35. package/cli/commands/login.ts +5 -5
  36. package/cli/commands/maestro-compare.ts +554 -0
  37. package/cli/commands/maestro-generate.ts +6 -3
  38. package/cli/commands/maestro.ts +22 -0
  39. package/cli/commands/mode.ts +2 -2
  40. package/cli/commands/no-bridge-hint.ts +6 -2
  41. package/cli/commands/platform.ts +35 -6
  42. package/cli/commands/preview.ts +6 -0
  43. package/cli/commands/project-report.ts +10 -12
  44. package/cli/commands/record.ts +37 -37
  45. package/cli/commands/runtime.ts +9 -9
  46. package/cli/commands/screenshot-layers.ts +4 -4
  47. package/cli/commands/screenshot-mode.ts +2 -2
  48. package/cli/commands/screenshot.ts +8 -8
  49. package/cli/commands/screenshots-capture.ts +2 -2
  50. package/cli/commands/serve.ts +9 -12
  51. package/cli/commands/setup.ts +29 -14
  52. package/cli/commands/shell-boolean-mode.ts +2 -2
  53. package/cli/commands/show-touches-mode.ts +2 -2
  54. package/cli/commands/skills.ts +11 -11
  55. package/cli/commands/swift.ts +29 -11
  56. package/cli/commands/telemetry.ts +2 -2
  57. package/cli/commands/test.ts +5 -0
  58. package/cli/commands/three-mode.ts +3 -3
  59. package/cli/commands/timeline.ts +4 -4
  60. package/cli/commands/upgrade.ts +2 -2
  61. package/cli/commands/upload.ts +15 -15
  62. package/cli/commands/what-happened.ts +2 -2
  63. package/cli/current-sim.ts +6 -3
  64. package/cli/desktop-companion.ts +55 -149
  65. package/cli/dev-build-freshness.ts +2 -2
  66. package/cli/drivers/desktop.ts +17 -9
  67. package/cli/drivers/electron.ts +1 -2
  68. package/cli/drivers/playwright-sim-host.ts +11 -2
  69. package/cli/drivers/playwright.ts +35 -2
  70. package/cli/drivers/types.ts +8 -0
  71. package/cli/maestro-compare.ts +670 -0
  72. package/cli/outbound-endpoints.ts +46 -8
  73. package/cli/recording-access.ts +6 -6
  74. package/cli/run-registry.ts +1 -1
  75. package/cli/runtime-compat.ts +5 -1
  76. package/cli/send-to-box.ts +3 -3
  77. package/cli/shell-init.ts +2 -1
  78. package/cli/ws-bridge.ts +9 -5
  79. package/detox/element-types.ts +1 -0
  80. package/detox/gestures.ts +3 -3
  81. package/detox/index.ts +67 -38
  82. package/detox/navigation-lifecycle.ts +9 -6
  83. package/detox/proof-frame.cjs +6 -4
  84. package/dist-lib/agent-daemon-client.cjs +1 -1
  85. package/dist-lib/agent-events.cjs +1 -1
  86. package/dist-lib/attached-projects.cjs +1 -1
  87. package/dist-lib/auth/shared-session.cjs +1 -1
  88. package/dist-lib/backend-origin.cjs +1 -1
  89. package/dist-lib/beta.cjs +1 -1
  90. package/dist-lib/beta.mjs +1 -1
  91. package/dist-lib/bridge-constants.cjs +1 -1
  92. package/dist-lib/bridge-contract-input.cjs +42 -17
  93. package/dist-lib/bridge-contract-input.mjs +41 -16
  94. package/dist-lib/bridge-contract.cjs +1 -4
  95. package/dist-lib/bridge-contract.mjs +1 -3
  96. package/dist-lib/bundle-channel.cjs +2918 -550
  97. package/dist-lib/capture-contract.cjs +65 -24
  98. package/dist-lib/capture-contract.mjs +63 -24
  99. package/dist-lib/cloud-contract.cjs +2 -2
  100. package/dist-lib/cloud-contract.mjs +2 -2
  101. package/dist-lib/cloud-test-args.cjs +1 -1
  102. package/dist-lib/cloud-test-args.mjs +1 -1
  103. package/dist-lib/cloud.cjs +3 -3
  104. package/dist-lib/cloud.mjs +3 -3
  105. package/dist-lib/config.cjs +15 -5
  106. package/dist-lib/config.mjs +154 -0
  107. package/dist-lib/detox/index.cjs +495 -139
  108. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  109. package/dist-lib/expo-swift-bundle.cjs +1168 -238
  110. package/dist-lib/expo-swift-metadata.cjs +34 -23
  111. package/dist-lib/expo-swift-metadata.mjs +32 -23
  112. package/dist-lib/home-paths.cjs +2 -2
  113. package/dist-lib/host/bridge-host.cjs +2938 -654
  114. package/dist-lib/host/fetch-proxy-handler.cjs +14 -1
  115. package/dist-lib/host/fetch-proxy-overrides.cjs +7 -1
  116. package/dist-lib/host/fetch-proxy-overrides.mjs +5 -1
  117. package/dist-lib/host/replacement-module-handler.cjs +2 -2
  118. package/dist-lib/host/websocket-proxy.cjs +1 -1
  119. package/dist-lib/index.cjs +999 -353
  120. package/dist-lib/jump-to-source-babel.cjs +1 -1
  121. package/dist-lib/jump-to-source-native.cjs +1 -1
  122. package/dist-lib/kotlin-host.cjs +332 -19
  123. package/dist-lib/menu.cjs +1 -1
  124. package/dist-lib/menu.mjs +1 -1
  125. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  126. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  127. package/dist-lib/metro-production-bundle.cjs +7 -7
  128. package/dist-lib/metro-production-bundle.mjs +5 -5
  129. package/dist-lib/metro.cjs +688 -250
  130. package/dist-lib/native-app-identity-project.cjs +2647 -0
  131. package/dist-lib/native-app-identity-project.mjs +1257 -0
  132. package/dist-lib/native-app-identity.cjs +325 -25
  133. package/dist-lib/native-app-identity.mjs +323 -25
  134. package/dist-lib/native-firebase-metadata.cjs +1 -1
  135. package/dist-lib/native-firebase-metadata.mjs +1 -1
  136. package/dist-lib/plist.cjs +1 -1
  137. package/dist-lib/plist.mjs +1 -1
  138. package/dist-lib/profiles.cjs +1 -1
  139. package/dist-lib/public-brand.cjs +1 -1
  140. package/dist-lib/react-native-host-modules.cjs +5 -1
  141. package/dist-lib/react-native-host-modules.mjs +5 -1
  142. package/dist-lib/scripts/dev-server-scanner.cjs +57 -32
  143. package/dist-lib/sdk.cjs +231 -51
  144. package/dist-lib/sdk.mjs +231 -51
  145. package/dist-lib/skills.cjs +4107 -1374
  146. package/dist-lib/swift-compile.cjs +290 -30
  147. package/dist-lib/swift-compile.mjs +290 -30
  148. package/dist-lib/swift-package.cjs +143 -12
  149. package/dist-lib/swift-package.mjs +137 -11
  150. package/dist-lib/swift-submit.cjs +47 -5
  151. package/dist-lib/swift-submit.mjs +42 -5
  152. package/dist-lib/swift-toolchain.cjs +7 -2
  153. package/dist-lib/swift.cjs +1 -1
  154. package/dist-lib/vite-swift.cjs +1392 -458
  155. package/dist-lib/vite.cjs +13 -17
  156. package/dist-lib/worklet-executable.cjs +248 -33
  157. package/dist-lib/worklet-executable.mjs +248 -33
  158. package/install.sh +10 -1
  159. package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Resources.kt +9 -9
  160. package/kotlin/AndroidViewSources/android/graphics/Canvas.kt +20 -0
  161. package/kotlin/AndroidViewSources/android/view/View.kt +211 -0
  162. package/kotlin/AndroidViewSources/android/widget/FrameLayout.kt +61 -0
  163. package/kotlin/AndroidViewSources/android/widget/LinearLayout.kt +49 -0
  164. package/kotlin/AppSources/android/view/Window.kt +36 -0
  165. package/kotlin/AppSources/android/view/WindowInsets.kt +9 -0
  166. package/kotlin/AppSources/android/view/WindowInsetsController.kt +5 -0
  167. package/kotlin/AppSources/android/window/OnBackInvokedDispatcher.kt +48 -0
  168. package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcher.kt +20 -5
  169. package/kotlin/AppSources/androidx/compose/foundation/layout/WindowInsets.kt +15 -0
  170. package/kotlin/AppSources/androidx/compose/ui/platform/ComposeView.kt +2 -1
  171. package/kotlin/AppSources/dev/peach/app/PeachApp.kt +42 -50
  172. package/kotlin/ComposeSources/PeachComposeHost.kt +200 -84
  173. package/kotlin/ExpoComposeSources/PeachAndroidView.kt +87 -0
  174. package/kotlin/ExpoComposeSources/PeachExpoViewMount.kt +24 -0
  175. package/kotlin/ExpoComposeSources/dev/peach/expo/PeachExpoCompose.kt +28 -0
  176. package/kotlin/ExpoComposeSources/expo/modules/kotlin/views/ExpoComposeView.kt +70 -0
  177. package/kotlin/ExpoSources/dev/peach/expo/PeachExpoRuntime.kt +513 -0
  178. package/kotlin/ExpoSources/dev/peach/expo/PeachExpoTypes.kt +173 -0
  179. package/kotlin/ExpoSources/expo/modules/kotlin/AppContext.kt +20 -0
  180. package/kotlin/ExpoSources/expo/modules/kotlin/Promise.kt +19 -0
  181. package/kotlin/ExpoSources/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +198 -0
  182. package/kotlin/ExpoSources/expo/modules/kotlin/exception/CodedException.kt +126 -0
  183. package/kotlin/ExpoSources/expo/modules/kotlin/functions/Functions.kt +132 -0
  184. package/kotlin/ExpoSources/expo/modules/kotlin/jni/JavaScriptTypedArray.kt +81 -0
  185. package/kotlin/ExpoSources/expo/modules/kotlin/modules/Module.kt +98 -0
  186. package/kotlin/ExpoSources/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +236 -0
  187. package/kotlin/ExpoSources/expo/modules/kotlin/records/Record.kt +12 -0
  188. package/kotlin/ExpoSources/expo/modules/kotlin/runtime/Runtime.kt +9 -0
  189. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObject.kt +50 -0
  190. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +57 -0
  191. package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedRef.kt +19 -0
  192. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/ConcreteTypedArrays.kt +158 -0
  193. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/GenericTypedArray.kt +8 -0
  194. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArray.kt +29 -0
  195. package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArrayIterator.kt +9 -0
  196. package/kotlin/ExpoSources/expo/modules/kotlin/types/AnyType.kt +155 -0
  197. package/kotlin/ExpoSources/expo/modules/kotlin/types/Either.kt +91 -0
  198. package/kotlin/ExpoSources/expo/modules/kotlin/types/Enumerable.kt +6 -0
  199. package/kotlin/ExpoSources/expo/modules/kotlin/viewevent/ViewEvent.kt +54 -0
  200. package/kotlin/ExpoSources/expo/modules/kotlin/views/ExpoView.kt +23 -0
  201. package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +71 -0
  202. package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewProps.kt +35 -0
  203. package/kotlin/README.md +13 -3
  204. package/kotlin/Sources/android/os/Build.kt +17 -0
  205. package/kotlin/Sources/android/os/Handler.kt +35 -0
  206. package/kotlin/Sources/android/os/Looper.kt +17 -0
  207. package/kotlin/Sources/android/os/MessageQueue.kt +56 -0
  208. package/kotlin/Sources/android/os/SystemClock.kt +14 -0
  209. package/kotlin/Sources/android/util/Log.kt +64 -0
  210. package/kotlin/Sources/java/security/MessageDigest.kt +114 -0
  211. package/kotlin/Sources/kotlin/text/StringFormat.kt +9 -0
  212. package/kotlin/Sources/org/json/JSON.kt +44 -0
  213. package/kotlin/fixtures/counter/Counter.d.kt.ts +1 -0
  214. package/kotlin/fixtures/counter/Counter.kt +10 -3
  215. package/kotlin/fixtures/counter/CounterApp.native.tsx +1 -1
  216. package/kotlin/fixtures/counter/vite.config.ts +2 -2
  217. package/kotlin/fixtures/headless-counter/Headless.kt +7 -6
  218. package/kotlin/fixtures/import-animation/Animation.d.kt.ts +7 -0
  219. package/kotlin/fixtures/import-animation/Animation.kt +80 -0
  220. package/kotlin/fixtures/import-animation/ImportAnimation.native.tsx +13 -0
  221. package/kotlin/fixtures/import-animation/README.md +24 -0
  222. package/kotlin/fixtures/import-animation/app/_layout.tsx +4 -0
  223. package/kotlin/fixtures/import-animation/app/index+spa.tsx +1 -0
  224. package/kotlin/fixtures/import-animation/app/routes.d.ts +18 -0
  225. package/kotlin/fixtures/import-animation/package.json +23 -0
  226. package/kotlin/fixtures/import-animation/tsconfig.json +20 -0
  227. package/kotlin/fixtures/import-animation/vite.config.ts +20 -0
  228. package/kotlin/fixtures/import-editor/Editor.d.kt.ts +7 -0
  229. package/kotlin/fixtures/import-editor/Editor.kt +59 -0
  230. package/kotlin/fixtures/import-editor/ImportEditor.native.tsx +23 -0
  231. package/kotlin/fixtures/import-editor/README.md +27 -0
  232. package/kotlin/fixtures/import-editor/app/_layout.tsx +4 -0
  233. package/kotlin/fixtures/import-editor/app/index+spa.tsx +1 -0
  234. package/kotlin/fixtures/import-editor/package.json +23 -0
  235. package/kotlin/fixtures/import-editor/tsconfig.json +20 -0
  236. package/kotlin/fixtures/import-editor/vite.config.ts +20 -0
  237. package/kotlin/fixtures/import-effects/Effects.d.kt.ts +7 -0
  238. package/kotlin/fixtures/import-effects/Effects.kt +87 -0
  239. package/kotlin/fixtures/import-effects/ImportEffects.native.tsx +13 -0
  240. package/kotlin/fixtures/import-effects/README.md +19 -0
  241. package/kotlin/fixtures/import-effects/app/_layout.tsx +4 -0
  242. package/kotlin/fixtures/import-effects/app/index+spa.tsx +1 -0
  243. package/kotlin/fixtures/import-effects/package.json +23 -0
  244. package/kotlin/fixtures/import-effects/tsconfig.json +20 -0
  245. package/kotlin/fixtures/import-effects/vite.config.ts +20 -0
  246. package/kotlin/fixtures/import-layout/ImportLayout.native.tsx +13 -0
  247. package/kotlin/fixtures/import-layout/Layout.d.kt.ts +7 -0
  248. package/kotlin/fixtures/import-layout/Layout.kt +72 -0
  249. package/kotlin/fixtures/import-layout/README.md +24 -0
  250. package/kotlin/fixtures/import-layout/app/_layout.tsx +4 -0
  251. package/kotlin/fixtures/import-layout/app/index+spa.tsx +1 -0
  252. package/kotlin/fixtures/import-layout/package.json +23 -0
  253. package/kotlin/fixtures/import-layout/tsconfig.json +20 -0
  254. package/kotlin/fixtures/import-layout/vite.config.ts +20 -0
  255. package/kotlin/fixtures/import-navigation/ImportNavigation.native.tsx +18 -0
  256. package/kotlin/fixtures/import-navigation/Navigation.d.kt.ts +7 -0
  257. package/kotlin/fixtures/import-navigation/Navigation.kt +104 -0
  258. package/kotlin/fixtures/import-navigation/README.md +31 -0
  259. package/kotlin/fixtures/import-navigation/app/_layout.tsx +4 -0
  260. package/kotlin/fixtures/import-navigation/app/index+spa.tsx +1 -0
  261. package/kotlin/fixtures/import-navigation/package.json +23 -0
  262. package/kotlin/fixtures/import-navigation/tsconfig.json +20 -0
  263. package/kotlin/fixtures/import-navigation/vite.config.ts +20 -0
  264. package/kotlin/fixtures/import-overlays/ImportOverlays.native.tsx +29 -0
  265. package/kotlin/fixtures/import-overlays/Overlays.d.kt.ts +7 -0
  266. package/kotlin/fixtures/import-overlays/Overlays.kt +93 -0
  267. package/kotlin/fixtures/import-overlays/README.md +34 -0
  268. package/kotlin/fixtures/import-overlays/app/_layout.tsx +4 -0
  269. package/kotlin/fixtures/import-overlays/app/index+spa.tsx +1 -0
  270. package/kotlin/fixtures/import-overlays/package.json +23 -0
  271. package/kotlin/fixtures/import-overlays/tsconfig.json +20 -0
  272. package/kotlin/fixtures/import-overlays/vite.config.ts +20 -0
  273. package/kotlin/fixtures/import-scroll/ImportScroll.native.tsx +13 -0
  274. package/kotlin/fixtures/import-scroll/README.md +23 -0
  275. package/kotlin/fixtures/import-scroll/Scroll.d.kt.ts +7 -0
  276. package/kotlin/fixtures/import-scroll/Scroll.kt +91 -0
  277. package/kotlin/fixtures/import-scroll/app/_layout.tsx +4 -0
  278. package/kotlin/fixtures/import-scroll/app/index+spa.tsx +1 -0
  279. package/kotlin/fixtures/import-scroll/package.json +23 -0
  280. package/kotlin/fixtures/import-scroll/tsconfig.json +20 -0
  281. package/kotlin/fixtures/import-scroll/vite.config.ts +20 -0
  282. package/kotlin/fixtures/import-selection/ImportSelection.native.tsx +44 -0
  283. package/kotlin/fixtures/import-selection/README.md +32 -0
  284. package/kotlin/fixtures/import-selection/Selection.d.kt.ts +8 -0
  285. package/kotlin/fixtures/import-selection/Selection.kt +78 -0
  286. package/kotlin/fixtures/import-selection/app/_layout.tsx +4 -0
  287. package/kotlin/fixtures/import-selection/app/index+spa.tsx +1 -0
  288. package/kotlin/fixtures/import-selection/package.json +23 -0
  289. package/kotlin/fixtures/import-selection/tsconfig.json +20 -0
  290. package/kotlin/fixtures/import-selection/vite.config.ts +20 -0
  291. package/kotlin/fixtures/import-surfaces/ImportSurfaces.native.tsx +13 -0
  292. package/kotlin/fixtures/import-surfaces/README.md +22 -0
  293. package/kotlin/fixtures/import-surfaces/Surfaces.d.kt.ts +7 -0
  294. package/kotlin/fixtures/import-surfaces/Surfaces.kt +64 -0
  295. package/kotlin/fixtures/import-surfaces/app/_layout.tsx +4 -0
  296. package/kotlin/fixtures/import-surfaces/app/index+spa.tsx +1 -0
  297. package/kotlin/fixtures/import-surfaces/package.json +23 -0
  298. package/kotlin/fixtures/import-surfaces/tsconfig.json +20 -0
  299. package/kotlin/fixtures/import-surfaces/vite.config.ts +20 -0
  300. package/kotlin/fixtures/import-values/ImportValues.native.tsx +35 -0
  301. package/kotlin/fixtures/import-values/README.md +23 -0
  302. package/kotlin/fixtures/import-values/Values.d.kt.ts +11 -0
  303. package/kotlin/fixtures/import-values/Values.kt +66 -0
  304. package/kotlin/fixtures/import-values/app/_layout.tsx +4 -0
  305. package/kotlin/fixtures/import-values/app/index+spa.tsx +1 -0
  306. package/kotlin/fixtures/import-values/package.json +23 -0
  307. package/kotlin/fixtures/import-values/tsconfig.json +20 -0
  308. package/kotlin/fixtures/import-values/vite.config.ts +20 -0
  309. package/kotlin/fixtures/kotlin-app-variants/BarBehavior.kt +38 -0
  310. package/kotlin/fixtures/kotlin-app-variants/BarVisibility.kt +36 -0
  311. package/kotlin/fixtures/kotlin-app-variants/Ime.kt +3 -1
  312. package/kotlin/fixtures/kotlin-app-variants/TransientInsets.kt +50 -0
  313. package/kotlin/fork/NOTICE +6 -1
  314. package/kotlin/fork/README.md +15 -7
  315. package/kotlin/fork/build.sh +2 -0
  316. package/kotlin/fork/compose-worker-globals.patch +186 -4
  317. package/kotlin/fork/fork.json +2 -2
  318. package/kotlin/fork/skiko-worker-clock.patch +12 -0
  319. package/kotlin/toolchain.json +12 -12
  320. package/kotlin/tools/expo-types.main.kts +115 -0
  321. package/package.json +17 -23
  322. package/scripts/dev-server-scanner.ts +92 -66
  323. package/skills/contrast/SKILL.md +2 -2
  324. package/skills/peach-debug/SKILL.md +1 -1
  325. package/skills/peach-perf/SKILL.md +1 -1
  326. package/skills/peach-setup/SKILL.md +2 -1
  327. package/skills/peach-test/SKILL.md +8 -0
  328. package/src/assetCatalogContract.ts +43 -1
  329. package/src/bridge-contract-input.ts +46 -19
  330. package/src/bridge-contract.ts +0 -1
  331. package/src/bundle-channel.mjs +197 -84
  332. package/src/bundleGlobalFooter.ts +38 -0
  333. package/src/capture-contract.ts +107 -33
  334. package/src/cloud-contract.ts +5 -1
  335. package/src/cloud.ts +5 -2
  336. package/src/config.ts +22 -3
  337. package/src/configured-bundle-producer.ts +1 -1
  338. package/src/desktop-host-delivery.ts +95 -1
  339. package/src/expo-kotlin-bundle.ts +29 -0
  340. package/src/expo-kotlin-host.ts +201 -0
  341. package/src/expo-swift-host.ts +96 -76
  342. package/src/expoKotlinContract.ts +70 -0
  343. package/src/expoSwiftContract.ts +4 -25
  344. package/src/home-paths.ts +7 -4
  345. package/src/host/bridge-host.ts +23 -3
  346. package/src/host/fetch-proxy-handler.ts +13 -0
  347. package/src/host/fetch-proxy-overrides.ts +11 -0
  348. package/src/host/replacement-module-handler.ts +5 -2
  349. package/src/index.ts +3 -1
  350. package/src/kotlin-host.ts +463 -19
  351. package/src/metro-plugin.ts +56 -28
  352. package/src/metro-production-bundle.ts +2 -2
  353. package/src/native-app-identity-project.ts +190 -0
  354. package/src/native-app-identity.ts +398 -34
  355. package/src/native-firebase-config.ts +69 -15
  356. package/src/native-seam-manifest.ts +6 -0
  357. package/src/one-widget-discovery.ts +2 -1
  358. package/src/openstep-plist.ts +107 -0
  359. package/src/react-native-host-modules.ts +4 -0
  360. package/src/runtime-assets.ts +2 -2
  361. package/src/sim-client.ts +2 -2
  362. package/src/swift-binary-modules.ts +3 -1
  363. package/src/swift-compile.ts +286 -38
  364. package/src/swift-distribution-contract.ts +4 -0
  365. package/src/swift-distribution.lock.json +123 -12
  366. package/src/swift-distribution.ts +7 -3
  367. package/src/swift-host.ts +298 -83
  368. package/src/swift-package-manifest.ts +29 -2
  369. package/src/swift-package.ts +180 -10
  370. package/src/swift-packages.ts +4 -0
  371. package/src/swift-standin-emit.ts +4 -1
  372. package/src/swift-standins.ts +274 -15
  373. package/src/swift-submit.ts +62 -7
  374. package/src/swift-toolchain.ts +6 -1
  375. package/src/swiftContract.ts +126 -3
  376. package/src/vite-plugin-one.ts +13 -16
  377. package/src/vite-plugin-swift.ts +4 -5
  378. package/src/vite-plugin.ts +360 -144
  379. package/src/vite.d.ts +1 -1
  380. package/src/worker-system-chunks.ts +221 -0
  381. package/src/worklet-executable.ts +348 -38
  382. package/src/worklets-babel.ts +1 -1
  383. package/src/xcode-project.ts +243 -127
  384. package/dist-lib/agent-identity.cjs +0 -39
  385. package/dist-lib/agent-sessions.cjs +0 -760
  386. package/dist-lib/cli-constants.cjs +0 -32
  387. package/dist-lib/render-mode.cjs +0 -44
  388. package/kotlin/AppSources/android/view/View.kt +0 -74
  389. package/kotlin/AppSources/android/widget/FrameLayout.kt +0 -6
  390. package/src/render-mode.ts +0 -15
  391. /package/kotlin/{AppSources → AndroidViewSources}/android/content/Context.kt +0 -0
  392. /package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Configuration.kt +0 -0
  393. /package/kotlin/{AppSources → AndroidViewSources}/android/graphics/Color.kt +0 -0
  394. /package/kotlin/{AppSources → AndroidViewSources}/android/util/DisplayMetrics.kt +0 -0
  395. /package/kotlin/{AppSources → AndroidViewSources}/dev/peach/app/JavaFormat.kt +0 -0
  396. /package/kotlin/{AppSources → Sources}/java/lang/Runnable.kt +0 -0
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.939 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! peach v0.1.1399 | (c) 2026 Tamagui LLC | Proprietary; see LICENSE */
2
2
  let __sootsim_import_meta_url = '', __sootsim_import_meta_dirname = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; __sootsim_import_meta_dirname = __dirname; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1476,7 +1476,7 @@ function parseSwiftDistributionManifest(value) {
1476
1476
  };
1477
1477
  }
1478
1478
  function parseSwiftDistributionLock(value) {
1479
- if (!isRecord(value) || typeof value.id !== "string" || !/^[a-f0-9]{16}$/.test(value.id) || typeof value.release !== "string" || typeof value.wasmSdkId !== "string" || typeof value.wasmSdkUrl !== "string" || typeof value.wasmSdkChecksum !== "string" || typeof value.source !== "string" || !isRecord(value.hosts)) {
1479
+ if (!isRecord(value) || typeof value.id !== "string" || !/^[a-f0-9]{16}$/.test(value.id) || typeof value.release !== "string" || typeof value.wasmSdkId !== "string" || typeof value.wasmSdkUrl !== "string" || typeof value.wasmSdkChecksum !== "string" || typeof value.source !== "string" || !isStrings(value.targets) || !isRecord(value.hosts)) {
1480
1480
  throw new Error("invalid Swift distribution lock");
1481
1481
  }
1482
1482
  const hosts = value.hosts;
@@ -1494,6 +1494,7 @@ function parseSwiftDistributionLock(value) {
1494
1494
  wasmSdkUrl: value.wasmSdkUrl,
1495
1495
  wasmSdkChecksum: value.wasmSdkChecksum,
1496
1496
  source: value.source,
1497
+ targets: value.targets,
1497
1498
  hosts: {
1498
1499
  "darwin-arm64": entry("darwin-arm64"),
1499
1500
  "linux-x64": entry("linux-x64"),
@@ -1625,7 +1626,10 @@ var MANIFEST_DECLARATIONS = [
1625
1626
  function manifestCalls(manifest, kinds) {
1626
1627
  const code = manifest.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"])\/\/[^\n]*/g, "$1");
1627
1628
  const calls = [];
1628
- const pattern = new RegExp(`\\.(${MANIFEST_DECLARATIONS.join("|")})\\s*\\(`, "g");
1629
+ const pattern = new RegExp(
1630
+ `(?:\\.(${MANIFEST_DECLARATIONS.join("|")})|\\b(Package))\\s*\\(`,
1631
+ "g"
1632
+ );
1629
1633
  let match;
1630
1634
  while ((match = pattern.exec(code)) !== null) {
1631
1635
  let depth = 1;
@@ -1655,22 +1659,59 @@ function manifestCalls(manifest, kinds) {
1655
1659
  }
1656
1660
  i++;
1657
1661
  }
1658
- if (kinds.includes(match[1]))
1659
- calls.push({ kind: match[1], flat, call: code.slice(start, i) });
1662
+ const kind = match[1] ?? match[2];
1663
+ if (kinds.includes(kind)) calls.push({ kind, flat, call: code.slice(start, i) });
1664
+ else if (kind === "Package") {
1665
+ calls.push(...manifestCalls(code.slice(start, i - 1), kinds));
1666
+ }
1660
1667
  pattern.lastIndex = i;
1661
1668
  }
1662
1669
  return calls;
1663
1670
  }
1671
+ function splitManifestArguments(source) {
1672
+ const arguments_ = [];
1673
+ let start = 0;
1674
+ let parentheses = 0;
1675
+ let brackets = 0;
1676
+ let braces = 0;
1677
+ let inString = false;
1678
+ let escaped = false;
1679
+ for (let index = 0; index < source.length; index++) {
1680
+ const character = source[index];
1681
+ if (inString) {
1682
+ if (escaped) escaped = false;
1683
+ else if (character === "\\") escaped = true;
1684
+ else if (character === '"') inString = false;
1685
+ } else if (character === '"') inString = true;
1686
+ else if (character === "(") parentheses++;
1687
+ else if (character === ")") parentheses--;
1688
+ else if (character === "[") brackets++;
1689
+ else if (character === "]") brackets--;
1690
+ else if (character === "{") braces++;
1691
+ else if (character === "}") braces--;
1692
+ else if (character === "," && parentheses === 0 && brackets === 0 && braces === 0) {
1693
+ arguments_.push(source.slice(start, index).trim());
1694
+ start = index + 1;
1695
+ }
1696
+ }
1697
+ const final = source.slice(start).trim();
1698
+ if (final) arguments_.push(final);
1699
+ return arguments_;
1700
+ }
1664
1701
  function swiftPackageIdentity(url) {
1665
1702
  return (url.split("/").pop() ?? url).replace(/\.git$/, "").toLowerCase();
1666
1703
  }
1667
1704
  function swiftManifestTargets(manifest, resourcePaths = []) {
1668
1705
  const implicitResources = swiftImplicitResourcePaths(resourcePaths);
1669
1706
  const targets = [];
1670
- for (const { kind, flat, call } of manifestCalls(manifest, [
1671
- "executableTarget",
1672
- "target"
1673
- ])) {
1707
+ const declarations = manifestCalls(manifest, ["executableTarget", "target"]);
1708
+ const targetNames = new Set(
1709
+ declarations.flatMap(({ flat }) => {
1710
+ const name2 = /\bname\s*:\s*"([^"]+)"/.exec(flat)?.[1];
1711
+ return name2 ? [name2] : [];
1712
+ })
1713
+ );
1714
+ for (const { kind, flat, call } of declarations) {
1674
1715
  const executable = kind === "executableTarget";
1675
1716
  const name2 = /\bname\s*:\s*"([^"]+)"/.exec(flat)?.[1];
1676
1717
  if (!name2) continue;
@@ -1680,6 +1721,12 @@ function swiftManifestTargets(manifest, resourcePaths = []) {
1680
1721
  /\.swiftLanguageMode\(\s*\.v(\d+)\s*\)/.exec(call)?.[1] ?? "5"
1681
1722
  );
1682
1723
  const mainActorIsolation = /\.defaultIsolation\(\s*MainActor\.self\s*\)/.test(call);
1724
+ const cxxInterop = /\.interoperabilityMode\(\s*\.Cxx\s*\)/.test(
1725
+ call.replace(/"(?:\\.|[^"\\])*"/g, "")
1726
+ );
1727
+ const defines = [
1728
+ ...call.matchAll(/\.define\(\s*"([A-Za-z_][A-Za-z0-9_]*)"\s*\)/g)
1729
+ ].map((match) => match[1]);
1683
1730
  const excluded = [
1684
1731
  ...(/\bexclude\s*:\s*\[([^\]]*)\]/.exec(flat)?.[1] ?? "").matchAll(/"([^"]+)"/g)
1685
1732
  ].map((match) => match[1].replace(/^\.\//, "").replace(/\/+$/, ""));
@@ -1693,20 +1740,118 @@ function swiftManifestTargets(manifest, resourcePaths = []) {
1693
1740
  return false;
1694
1741
  return true;
1695
1742
  });
1743
+ const targetArguments = splitManifestArguments(call.slice(0, -1));
1744
+ const dependencyArgument = targetArguments.find(
1745
+ (argument) => /^dependencies\s*:/.test(argument)
1746
+ );
1747
+ const dependencyList = dependencyArgument?.replace(/^dependencies\s*:\s*/, "").trim();
1748
+ const dependencyNames = /* @__PURE__ */ new Set();
1749
+ if (dependencyList?.startsWith("[") && dependencyList.endsWith("]")) {
1750
+ for (const dependency of splitManifestArguments(dependencyList.slice(1, -1))) {
1751
+ const dependencyName = /^"([^"]+)"$/.exec(dependency)?.[1] ?? /^\.(?:target|byName)\s*\(\s*name\s*:\s*"([^"]+)"/.exec(dependency)?.[1];
1752
+ if (dependencyName && targetNames.has(dependencyName))
1753
+ dependencyNames.add(dependencyName);
1754
+ }
1755
+ }
1756
+ const dependencies = [...dependencyNames].map((name3) => ({
1757
+ kind: "target",
1758
+ name: name3
1759
+ }));
1696
1760
  targets.push({
1697
1761
  name: name2,
1698
1762
  path: targetPath,
1699
1763
  executable,
1700
1764
  languageMode,
1701
1765
  mainActorIsolation,
1702
- resources
1766
+ ...cxxInterop ? { cxxInterop: true } : {},
1767
+ ...defines.length === 0 ? {} : { defines },
1768
+ resources,
1769
+ ...dependencies.length === 0 ? {} : { dependencies },
1770
+ ...excluded.length === 0 ? {} : { exclude: excluded }
1703
1771
  });
1704
1772
  }
1705
1773
  return targets;
1706
1774
  }
1775
+ function swiftManifestCxxLanguageStandard(manifest) {
1776
+ const declaration = manifestCalls(manifest, ["Package"])[0];
1777
+ if (!declaration) return void 0;
1778
+ const code = declaration.flat.replace(/"(?:\\.|[^"\\])*"/g, "");
1779
+ return /\bcxxLanguageStandard\s*:\s*\.(\w+)/.exec(code)?.[1];
1780
+ }
1781
+ function swiftResourceBundles(files2, resourcePaths = []) {
1782
+ const manifest = files2["Package.swift"] ?? "";
1783
+ const targets = swiftManifestTargets(manifest, resourcePaths).filter(
1784
+ (target) => target.resources
1785
+ );
1786
+ if (targets.length === 0) return [];
1787
+ const declaration = manifestCalls(manifest, ["Package"])[0];
1788
+ const packageName = declaration && /\bname\s*:\s*"([^"/\\]+)"/.exec(declaration.flat)?.[1];
1789
+ if (!packageName)
1790
+ throw new Error("swift resource bundles require the original package name");
1791
+ return targets.map((target) => ({
1792
+ target: target.name,
1793
+ sourcePath: target.path,
1794
+ path: `${packageName}_${target.name}.bundle`
1795
+ }));
1796
+ }
1797
+ function swiftResourceBundleForFile(bundles, file) {
1798
+ let owner;
1799
+ for (const bundle of bundles) {
1800
+ const prefix = bundle.sourcePath === "." ? "" : `${bundle.sourcePath}/`;
1801
+ if (file.startsWith(prefix) && (!owner || bundle.sourcePath.length > owner.sourcePath.length))
1802
+ owner = bundle;
1803
+ }
1804
+ return owner;
1805
+ }
1806
+ function swiftResourceBundleInfoPlist(bundle) {
1807
+ const name2 = bundle.path.split("/").pop().replace(/\.(bundle|framework)$/, "");
1808
+ const escaped = name2.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
1809
+ return `<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>CFBundleName</key><string>${escaped}</string><key>CFBundlePackageType</key><string>${bundle.path.endsWith(".framework") ? "FMWK" : "BNDL"}</string></dict></plist>`;
1810
+ }
1811
+ function swiftMetalSourceFiles(files2) {
1812
+ const sources = Object.entries(files2).filter(([file]) => file.endsWith(".metal"));
1813
+ if (sources.length === 0) return {};
1814
+ const targets = swiftManifestTargets(files2["Package.swift"] ?? "");
1815
+ return Object.fromEntries(
1816
+ sources.filter(([file]) => {
1817
+ if (targets.length === 0) return true;
1818
+ return targets.some((target) => {
1819
+ const prefix = target.path === "." ? "" : `${target.path}/`;
1820
+ if (!file.startsWith(prefix)) return false;
1821
+ const relative = file.slice(prefix.length);
1822
+ return !(target.exclude ?? []).some(
1823
+ (excluded) => relative === excluded || relative.startsWith(`${excluded}/`)
1824
+ );
1825
+ });
1826
+ })
1827
+ );
1828
+ }
1707
1829
  function swiftPackagePartition(manifest, resourcePaths = []) {
1708
1830
  const targets = swiftManifestTargets(manifest, resourcePaths);
1709
- return targets.length === 1 && targets[0].executable && targets[0].path === "." ? [] : targets;
1831
+ return targets.length === 1 && targets[0].executable && targets[0].path === "." && targets[0].languageMode === 5 && !targets[0].mainActorIsolation && !targets[0].defines?.length && !targets[0].cxxInterop && !swiftManifestCxxLanguageStandard(manifest) ? [] : targets;
1832
+ }
1833
+
1834
+ // src/swiftContract.ts
1835
+ function isSwiftResourcePath(value) {
1836
+ return typeof value === "string" && value.length <= 4096 && !value.startsWith("/") && !value.includes("\\") && !value.includes("\0") && value.split("/").every((part) => part !== "" && part !== "." && part !== "..");
1837
+ }
1838
+ function isSwiftBundlePath(value) {
1839
+ return typeof value === "string" && (value === "." || isSwiftResourcePath(value) && /\.(bundle|framework)$/.test(value));
1840
+ }
1841
+ function isSwiftResourceBundles(value) {
1842
+ return Array.isArray(value) && value.length <= 128 && value.every(
1843
+ (bundle) => typeof bundle === "object" && bundle !== null && typeof bundle.target === "string" && /^[A-Za-z_][A-Za-z0-9_-]*$/.test(bundle.target) && (bundle.sourcePath === "." || isSwiftResourcePath(bundle.sourcePath)) && isSwiftBundlePath(bundle.path)
1844
+ ) && new Set(value.map((bundle) => bundle.target)).size === value.length && new Set(value.map((bundle) => bundle.path)).size === value.length;
1845
+ }
1846
+ function isSwiftMetalSources(value) {
1847
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.entries(value).every(
1848
+ ([file, source]) => file.endsWith(".metal") && isSwiftResourcePath(file) && typeof source === "object" && source !== null && !Array.isArray(source) && "url" in source && typeof source.url === "string" && "sha256" in source && typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256)
1849
+ );
1850
+ }
1851
+ function isSwiftMetalLibrarySources(value) {
1852
+ return isSwiftMetalSources(value) && Object.values(value).every(
1853
+ (source) => "bundlePath" in source && isSwiftBundlePath(source.bundlePath)
1854
+ );
1710
1855
  }
1711
1856
 
1712
1857
  // src/swift-compile.ts
@@ -1739,6 +1884,7 @@ function swiftModuleInputFiles(root) {
1739
1884
  "Package.swift",
1740
1885
  "scripts/contrast-app-Package.swift",
1741
1886
  "scripts/build-distribution.ts",
1887
+ "scripts/distribution-clang.ts",
1742
1888
  "scripts/build-distribution-plugins.sh",
1743
1889
  "scripts/build-preview-plugin.sh",
1744
1890
  "toolchain.json"
@@ -1763,6 +1909,10 @@ function swiftMacroPlugins(moduleRoot) {
1763
1909
  stale: false
1764
1910
  };
1765
1911
  const dir = import_node_path2.default.join(moduleRoot, ".build/host/RnxPreviewMacros");
1912
+ const release = JSON.parse(
1913
+ (0, import_node_fs2.readFileSync)(import_node_path2.default.join(moduleRoot, "toolchain.json"), "utf8")
1914
+ ).release;
1915
+ const compilerStamp = import_node_path2.default.join(dir, "compiler-release");
1766
1916
  const ext = process.platform === "darwin" ? "dylib" : "so";
1767
1917
  const plugins = [
1768
1918
  {
@@ -1776,12 +1926,12 @@ function swiftMacroPlugins(moduleRoot) {
1776
1926
  ];
1777
1927
  return {
1778
1928
  libraries: plugins.map(({ library }) => library),
1779
- stale: plugins.some(
1929
+ stale: !(0, import_node_fs2.existsSync)(compilerStamp) || (0, import_node_fs2.readFileSync)(compilerStamp, "utf8").trim() !== release || plugins.some(
1780
1930
  ({ library, source }) => !(0, import_node_fs2.existsSync)(library) || (0, import_node_fs2.statSync)(source).mtimeMs > (0, import_node_fs2.statSync)(library).mtimeMs
1781
1931
  )
1782
1932
  };
1783
1933
  }
1784
- async function ensureMacroPlugins(moduleRoot, toolchainBin) {
1934
+ async function ensureMacroPlugins(moduleRoot, toolchainBin, release) {
1785
1935
  const { libraries, stale } = swiftMacroPlugins(moduleRoot);
1786
1936
  if (stale) {
1787
1937
  await run2("sh", [
@@ -1789,6 +1939,11 @@ async function ensureMacroPlugins(moduleRoot, toolchainBin) {
1789
1939
  toolchainBin,
1790
1940
  libraries[0]
1791
1941
  ]);
1942
+ (0, import_node_fs2.writeFileSync)(
1943
+ import_node_path2.default.join(import_node_path2.default.dirname(libraries[0]), "compiler-release"),
1944
+ `${release}
1945
+ `
1946
+ );
1792
1947
  }
1793
1948
  return libraries;
1794
1949
  }
@@ -1850,6 +2005,7 @@ var OPTIONAL_FRAMEWORK_DEPENDENCIES = {
1850
2005
  TikTokBusinessSDK: [],
1851
2006
  nSure: [],
1852
2007
  Statsig: [],
2008
+ TOCropViewController: [],
1853
2009
  RiveRuntime: ["MetalKit"],
1854
2010
  MetalKit: [],
1855
2011
  DatadogCore: [],
@@ -1864,6 +2020,7 @@ var OPTIONAL_FRAMEWORK_DEPENDENCIES = {
1864
2020
  Intercom: [],
1865
2021
  FirebaseCore: [],
1866
2022
  FirebaseSharedSwift: ["FirebaseCore"],
2023
+ FirebaseRemoteConfig: ["FirebaseCore", "FirebaseSharedSwift"],
1867
2024
  FirebaseFirestoreInternal: ["FirebaseCore"],
1868
2025
  FirebaseAnalytics: ["FirebaseCore"],
1869
2026
  FirebaseAppCheck: ["FirebaseCore"],
@@ -1871,6 +2028,7 @@ var OPTIONAL_FRAMEWORK_DEPENDENCIES = {
1871
2028
  FirebaseCrashlytics: ["FirebaseCore"],
1872
2029
  FirebaseFirestore: ["FirebaseCore", "FirebaseSharedSwift", "FirebaseFirestoreInternal"],
1873
2030
  FirebaseStorage: ["FirebaseCore"],
2031
+ GoogleMobileAds: [],
1874
2032
  FBAudienceNetwork: []
1875
2033
  };
1876
2034
  var OPTIONAL_FRAMEWORKS = new Set(Object.keys(OPTIONAL_FRAMEWORK_DEPENDENCIES));
@@ -2014,7 +2172,11 @@ function swiftTargetDependencies(files2, targets) {
2014
2172
  const siblings = /* @__PURE__ */ new Map();
2015
2173
  for (const target of targets) {
2016
2174
  const prefix = target.path === "." ? "" : `${target.path}/`;
2017
- const deps = /* @__PURE__ */ new Set();
2175
+ const deps = new Set(
2176
+ (target.dependencies ?? []).flatMap(
2177
+ (dependency) => dependency.kind === "target" && dependency.name !== target.name && names.has(dependency.name) ? [dependency.name] : []
2178
+ )
2179
+ );
2018
2180
  for (const [file, contents] of Object.entries(files2)) {
2019
2181
  if (file === "Package.swift" || !file.startsWith(prefix)) continue;
2020
2182
  if (targets.some(
@@ -2038,17 +2200,17 @@ var FOUNDATION_IMPLICIT_MODULES = [
2038
2200
  "PeachObjC",
2039
2201
  "Dispatch",
2040
2202
  "FoundationNetworking",
2041
- "WASILibc",
2042
- "wasi_pthread"
2203
+ "PeachFoundationCombine",
2204
+ "Darwin"
2043
2205
  ];
2044
2206
  var FOUNDATION_IMPLICIT_FLAGS = FOUNDATION_IMPLICIT_MODULES.map(
2045
2207
  (module2) => `, "-Xfrontend", "-import-module", "-Xfrontend", "${module2}"`
2046
2208
  ).join("");
2047
2209
  var ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"';
2048
- var MULTI_MANIFEST_VERSION = 12;
2210
+ var MULTI_MANIFEST_VERSION = 18;
2049
2211
  function swiftArtifactHash(input, release, moduleRoot) {
2050
2212
  const hash = (0, import_node_crypto2.createHash)("sha256");
2051
- hash.update(`swift-compile/v20
2213
+ hash.update(`swift-compile/v23
2052
2214
  ${release}
2053
2215
  `);
2054
2216
  if (input.oneModule) hash.update("one-module\n");
@@ -2057,6 +2219,13 @@ ${release}
2057
2219
  hash.update((0, import_node_crypto2.createHash)("sha256").update(file).digest());
2058
2220
  hash.update((0, import_node_crypto2.createHash)("sha256").update(input.files[file]).digest());
2059
2221
  }
2222
+ for (const file of Object.keys(input.metalSources ?? {}).sort()) {
2223
+ hash.update("metal-source\n");
2224
+ hash.update((0, import_node_crypto2.createHash)("sha256").update(file).digest());
2225
+ hash.update(
2226
+ (0, import_node_crypto2.createHash)("sha256").update(input.metalSources?.[file] ?? "").digest()
2227
+ );
2228
+ }
2060
2229
  for (const base of Object.keys(input.resources ?? {}).sort()) {
2061
2230
  hash.update((0, import_node_crypto2.createHash)("sha256").update(base).digest());
2062
2231
  hash.update(
@@ -2074,6 +2243,19 @@ ${release}
2074
2243
  hash.update("resource-path\n");
2075
2244
  hash.update((0, import_node_crypto2.createHash)("sha256").update(file).digest());
2076
2245
  }
2246
+ hash.update(
2247
+ JSON.stringify(
2248
+ [...input.resourceBundles ?? []].sort((a, b) => a.target.localeCompare(b.target))
2249
+ )
2250
+ );
2251
+ for (const target of Object.keys(input.libraries ?? {}).sort()) {
2252
+ hash.update(`library
2253
+ ${target}
2254
+ `);
2255
+ hash.update(
2256
+ (0, import_node_crypto2.createHash)("sha256").update(input.libraries?.[target] ?? "").digest()
2257
+ );
2258
+ }
2077
2259
  const targets = compileTargets(input);
2078
2260
  if (targets.length > 0) {
2079
2261
  hash.update(`swift-multi/v${MULTI_MANIFEST_VERSION}
@@ -2109,10 +2291,22 @@ function emitSwiftPackageManifest(args) {
2109
2291
  if (!executable) throw new Error("swift-compile: no executable target to emit");
2110
2292
  const stanza = (target) => {
2111
2293
  const isolation = target.mainActorIsolation ? " .defaultIsolation(MainActor.self)," : "";
2294
+ const interoperability = target.cxxInterop ? " .interoperabilityMode(.Cxx)," : "";
2295
+ const defines = (target.defines ?? []).map((name2) => ` .define(${JSON.stringify(name2)}),`).join("");
2112
2296
  const imports = distribution ? `, "-I", ${JSON.stringify(import_node_path2.default.join(moduleRoot, "modules"))}` : "";
2113
- const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation} .unsafeFlags(["-Osize"${FOUNDATION_IMPLICIT_FLAGS}${oneModule ? ONE_IMPLICIT_FLAGS : ""}${imports}])]`;
2297
+ const native = args.native?.get(target.name);
2298
+ const nativeImports = (siblings.get(target.name) ?? []).filter((name2) => args.native?.has(name2)).map(
2299
+ (name2) => `, "-Xfrontend", "-import-module", "-Xfrontend", ${JSON.stringify(name2)}`
2300
+ ).join("");
2301
+ const header = args.headerDirectory && [...args.native?.values() ?? []].some(
2302
+ (value) => value.late.producers.includes(target.name)
2303
+ ) ? `, "-emit-objc-header-path", ${JSON.stringify(import_node_path2.default.join(args.headerDirectory, `${target.name}-Swift.h`))}` : "";
2304
+ const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation}${interoperability}${defines} .unsafeFlags(["-Osize"${FOUNDATION_IMPLICIT_FLAGS}${oneModule ? ONE_IMPLICIT_FLAGS : ""}${imports}${nativeImports}${header}])]`;
2114
2305
  const deps = [
2115
- ...distribution ? [] : [
2306
+ ...target.executable ? [...args.native?.values() ?? []].map(
2307
+ (value) => JSON.stringify(value.late.name)
2308
+ ) : [],
2309
+ ...distribution || native ? [] : [
2116
2310
  '.product(name: "SwiftUI", package: "sootsim-swift")',
2117
2311
  ...oneModule ? [ONE_PRODUCT] : [],
2118
2312
  ...spriteKit ? [SPRITEKIT_PRODUCT] : []
@@ -2133,13 +2327,15 @@ function emitSwiftPackageManifest(args) {
2133
2327
  "-Xlinker", "--export-if-defined=__main_argc_argv"${library},
2134
2328
  ]),
2135
2329
  .unsafeFlags(["-Xlinker", "--strip-all"], .when(configuration: .release)),
2136
- ]` : "";
2330
+ ]` : args.libraries?.has(target.name) ? `,
2331
+ linkerSettings: [.unsafeFlags([${JSON.stringify(args.libraries.get(target.name))}])]` : "";
2137
2332
  return [
2138
2333
  ` ${kind}(`,
2139
2334
  ` name: "${target.name}",`,
2140
2335
  ` dependencies: [${deps}],`,
2141
2336
  ` path: "${target.path}",`,
2142
- ` ${swiftSettings}${link}`,
2337
+ ...native ? [` exclude: ${JSON.stringify(native.lateSources)},`] : [],
2338
+ ` ${native ? "cxxSettings: []" : swiftSettings}${link}`,
2143
2339
  ` ),`
2144
2340
  ].join("\n");
2145
2341
  };
@@ -2154,7 +2350,16 @@ function emitSwiftPackageManifest(args) {
2154
2350
  ` dependencies: [${distribution ? "" : `.package(path: "${moduleRoot}")`}],`,
2155
2351
  " targets: [",
2156
2352
  ...targets.map(stanza),
2157
- " ]",
2353
+ ...[...args.native?.entries() ?? []].flatMap(([name2, native]) => [
2354
+ ` .target(name: ${JSON.stringify(native.late.name)},`,
2355
+ ` dependencies: ${JSON.stringify([name2, ...native.late.producers])},`,
2356
+ ` path: ${JSON.stringify(native.path)},`,
2357
+ ` sources: ${JSON.stringify(native.lateSources)},`,
2358
+ ` publicHeadersPath: "include",`,
2359
+ ` cxxSettings: [.unsafeFlags(["-fno-cxx-modules", "-I", ${JSON.stringify(native.includeDirectory)}, "-I", ${JSON.stringify(args.headerDirectory)}])]),`
2360
+ ]),
2361
+ args.cxxLanguageStandard ? ` ],
2362
+ cxxLanguageStandard: .${args.cxxLanguageStandard}` : " ]",
2158
2363
  ")",
2159
2364
  ""
2160
2365
  ].join("\n");
@@ -2171,9 +2376,10 @@ function syncSwiftTree(base, files2) {
2171
2376
  };
2172
2377
  walk2(base);
2173
2378
  for (const [full, contents] of files2) {
2174
- if ((0, import_node_fs2.existsSync)(full) && (0, import_node_fs2.readFileSync)(full, "utf8") === contents) continue;
2379
+ if ((0, import_node_fs2.existsSync)(full) && (typeof contents === "string" ? (0, import_node_fs2.readFileSync)(full, "utf8") === contents : (0, import_node_fs2.readFileSync)(full).equals(contents)))
2380
+ continue;
2175
2381
  (0, import_node_fs2.mkdirSync)(import_node_path2.default.dirname(full), { recursive: true });
2176
- (0, import_node_fs2.writeFileSync)(full, contents, "utf8");
2382
+ (0, import_node_fs2.writeFileSync)(full, contents);
2177
2383
  }
2178
2384
  }
2179
2385
  var DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/;
@@ -3239,6 +3445,8 @@ function swiftCodeScan(source) {
3239
3445
  }
3240
3446
  var compiledSource = (file, contents, extraObjCExtensions, tableConformances) => file.endsWith(".swift") ? swiftSourceAsIOS(contents, extraObjCExtensions, tableConformances) : contents;
3241
3447
  function writeSwiftProject(layout, input, moduleRoot) {
3448
+ if (input.resourceBundles !== void 0 && !isSwiftResourceBundles(input.resourceBundles))
3449
+ throw new Error("swift compile input has invalid target bundle assignments");
3242
3450
  const resourceTargets = swiftManifestTargets(
3243
3451
  input.files["Package.swift"] ?? "",
3244
3452
  input.resourcePaths
@@ -3255,6 +3463,80 @@ function writeSwiftProject(layout, input, moduleRoot) {
3255
3463
  }
3256
3464
  ] : compileTargets(input);
3257
3465
  const files2 = /* @__PURE__ */ new Map();
3466
+ const native = /* @__PURE__ */ new Map();
3467
+ const headerDirectory = import_node_path2.default.join(layout.root, ".build", "peach-cxx-headers");
3468
+ for (const target of targets) {
3469
+ const prefix = target.path === "." ? "" : `${target.path}/`;
3470
+ const entries = Object.entries(input.files).filter(
3471
+ ([file]) => file.startsWith(prefix) && !targets.some(
3472
+ (candidate) => candidate.name !== target.name && candidate.path !== "." && candidate.path.startsWith(prefix) && file.startsWith(`${candidate.path}/`)
3473
+ )
3474
+ );
3475
+ if (entries.some(([file]) => file.endsWith(".swift"))) continue;
3476
+ const units = entries.filter(([file]) => /\.(?:c|cc|cpp|cxx|m|mm)$/.test(file));
3477
+ if (units.length === 0) continue;
3478
+ const includes = `${prefix}include/`;
3479
+ const consumers = /* @__PURE__ */ new Map();
3480
+ const reverse = /* @__PURE__ */ new Map();
3481
+ for (const [file, contents] of entries) {
3482
+ const producers = /* @__PURE__ */ new Set();
3483
+ const source = contents.replace(/\/\*[\s\S]*?\*\//g, "");
3484
+ for (const match of source.matchAll(/^\s*#\s*include\s*[<"]([^>"]+)[>"]/gm)) {
3485
+ const include = match[1];
3486
+ const producer = /(?:^|\/)([^/]+)-Swift\.h$/.exec(include)?.[1];
3487
+ if (producer && targets.some((value) => value.name === producer))
3488
+ producers.add(producer);
3489
+ const local = [
3490
+ import_node_path2.default.posix.join(import_node_path2.default.posix.dirname(file), include),
3491
+ `${includes}${include}`
3492
+ ].find((candidate) => input.files[candidate] !== void 0);
3493
+ if (local) {
3494
+ reverse.set(local, [...reverse.get(local) ?? [], file]);
3495
+ }
3496
+ }
3497
+ consumers.set(file, producers);
3498
+ }
3499
+ const queue = [...consumers.keys()].filter((file) => consumers.get(file).size > 0);
3500
+ for (let index = 0; index < queue.length; index++) {
3501
+ const file = queue[index];
3502
+ for (const parent of reverse.get(file) ?? []) {
3503
+ const inherited = consumers.get(parent);
3504
+ const before = inherited.size;
3505
+ for (const producer of consumers.get(file)) inherited.add(producer);
3506
+ if (before !== inherited.size) queue.push(parent);
3507
+ }
3508
+ }
3509
+ const late = units.filter(([file]) => consumers.get(file).size > 0);
3510
+ if (late.length === 0) continue;
3511
+ native.set(target.name, {
3512
+ path: target.path,
3513
+ includeDirectory: import_node_path2.default.join(layout.root, includes),
3514
+ lateSources: late.map(([file]) => file.slice(prefix.length)),
3515
+ late: {
3516
+ name: `${target.name}SwiftImplementation`,
3517
+ producers: [
3518
+ ...new Set(late.flatMap(([file]) => [...consumers.get(file)]))
3519
+ ].sort()
3520
+ }
3521
+ });
3522
+ if (input.files[`${includes}module.modulemap`] !== void 0) continue;
3523
+ const roots = entries.filter(
3524
+ ([file]) => file.startsWith(includes) && /\.(?:h|hpp|hh|hxx)$/.test(file) && consumers.get(file).size === 0
3525
+ );
3526
+ files2.set(
3527
+ import_node_path2.default.join(layout.root, includes, "module.modulemap"),
3528
+ [
3529
+ `module ${target.name} {`,
3530
+ ...roots.map(
3531
+ ([file]) => ` header ${JSON.stringify(file.slice(includes.length))}`
3532
+ ),
3533
+ " export *",
3534
+ "}",
3535
+ ""
3536
+ ].join("\n")
3537
+ );
3538
+ }
3539
+ if (native.size > 0) (0, import_node_fs2.mkdirSync)(headerDirectory, { recursive: true });
3258
3540
  const modulePlan = (0, import_node_crypto2.createHash)("sha256").update(
3259
3541
  swiftModuleInputFiles(moduleRoot).join("\n")
3260
3542
  );
@@ -3263,7 +3545,11 @@ function writeSwiftProject(layout, input, moduleRoot) {
3263
3545
  }
3264
3546
  const resourcePlan = (0, import_node_crypto2.createHash)("sha256").update(
3265
3547
  JSON.stringify(
3266
- resourceTargets.filter((target) => target.resources).map((target) => [target.name, target.path])
3548
+ resourceTargets.filter((target) => target.resources).map((target) => [
3549
+ target.name,
3550
+ target.path,
3551
+ input.resourceBundles?.find((bundle) => bundle.target === target.name)?.path
3552
+ ])
3267
3553
  )
3268
3554
  ).digest("hex").slice(0, 16);
3269
3555
  const moduleFiles = `
@@ -3323,6 +3609,12 @@ function writeSwiftProject(layout, input, moduleRoot) {
3323
3609
  files2.set(import_node_path2.default.join(layout.root, "Package.swift"), manifest + moduleFiles);
3324
3610
  } else {
3325
3611
  const base = layout.multi ? layout.root : layout.sources;
3612
+ const libraries = /* @__PURE__ */ new Map();
3613
+ for (const [target, data] of Object.entries(input.libraries ?? {})) {
3614
+ const file = import_node_path2.default.join(layout.root, ".peach-libraries", `lib${target}.a`);
3615
+ files2.set(file, Buffer.from(data, "base64"));
3616
+ libraries.set(target, file);
3617
+ }
3326
3618
  for (const [file, contents] of Object.entries(input.files)) {
3327
3619
  if (file === "Package.swift") continue;
3328
3620
  files2.set(
@@ -3334,6 +3626,11 @@ function writeSwiftProject(layout, input, moduleRoot) {
3334
3626
  import_node_path2.default.join(layout.root, "Package.swift"),
3335
3627
  emitSwiftPackageManifest({
3336
3628
  targets,
3629
+ native,
3630
+ headerDirectory: native.size > 0 ? headerDirectory : void 0,
3631
+ cxxLanguageStandard: swiftManifestCxxLanguageStandard(
3632
+ input.files["Package.swift"] ?? ""
3633
+ ),
3337
3634
  siblings: swiftTargetDependencies(
3338
3635
  input.files,
3339
3636
  layout.multi ? targets : targets.map((target) => ({ ...target, path: "." }))
@@ -3341,12 +3638,20 @@ function writeSwiftProject(layout, input, moduleRoot) {
3341
3638
  moduleRoot,
3342
3639
  oneModule: input.oneModule,
3343
3640
  spriteKit: importsSpriteKit(input.files),
3344
- distribution: distribution ?? void 0
3641
+ distribution: distribution ?? void 0,
3642
+ libraries
3345
3643
  }) + moduleFiles
3346
3644
  );
3347
3645
  }
3348
3646
  for (const target of resourceTargets) {
3349
3647
  if (!target.resources) continue;
3648
+ const bundle = input.resourceBundles?.find(
3649
+ (candidate) => candidate.target === target.name
3650
+ );
3651
+ if (!bundle || bundle.sourcePath !== target.path)
3652
+ throw new Error(
3653
+ `swift resource target ${target.name} has no matching bundle assignment`
3654
+ );
3350
3655
  const directory = layout.multi ? import_node_path2.default.join(layout.root, target.path) : layout.sources;
3351
3656
  files2.set(
3352
3657
  import_node_path2.default.join(directory, "ResourceBundleAccessor.generated.swift"),
@@ -3354,7 +3659,11 @@ function writeSwiftProject(layout, input, moduleRoot) {
3354
3659
  "import Foundation",
3355
3660
  "",
3356
3661
  "extension Foundation.Bundle {",
3357
- " static let module: Bundle = Bundle.main",
3662
+ bundle.path === "." ? " static let module: Bundle = Bundle.main" : ` static let module: Bundle = {
3663
+ let url = Bundle.main.bundleURL.appendingPathComponent(${JSON.stringify(bundle.path)})
3664
+ guard let bundle = Bundle(url: url) else { fatalError("resource bundle is missing: ${bundle.target}") }
3665
+ return bundle
3666
+ }()`,
3358
3667
  "}",
3359
3668
  ""
3360
3669
  ].join("\n")
@@ -3422,7 +3731,7 @@ function compileSwiftProjectUnit(input, options) {
3422
3731
  };
3423
3732
  const hash = swiftArtifactHash(input, options.release, moduleRoot);
3424
3733
  return serialize(root, async () => {
3425
- if (process.platform === "darwin" && process.env.TM_SESSION && process.env.CI !== "true" && process.env.CONTRAST_HEAVY_ADMITTED !== "1" && moduleRoot === import_node_path2.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
3734
+ if (process.platform === "darwin" && process.env.TM_SESSION && process.env.CI !== "true" && moduleRoot === import_node_path2.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(moduleRoot)) {
3426
3735
  const requestRoot = (0, import_node_fs2.mkdtempSync)(import_node_path2.default.join(root, ".builder-request-"));
3427
3736
  const output = import_node_path2.default.join(requestRoot, "output");
3428
3737
  const request = import_node_path2.default.join(requestRoot, "request.json");
@@ -3447,7 +3756,11 @@ function compileSwiftProjectUnit(input, options) {
3447
3756
  "--output",
3448
3757
  output
3449
3758
  ],
3450
- { cwd: repo, timeout: options.timeoutMs, maxBuffer: 64 * 1024 * 1024 }
3759
+ {
3760
+ cwd: repo,
3761
+ timeout: options.timeoutMs,
3762
+ maxBuffer: 64 * 1024 * 1024
3763
+ }
3451
3764
  );
3452
3765
  pending.child.stdout?.on("data", (bytes2) => process.stdout.write(bytes2));
3453
3766
  pending.child.stderr?.on("data", (bytes2) => process.stderr.write(bytes2));
@@ -3479,7 +3792,11 @@ function compileSwiftProjectUnit(input, options) {
3479
3792
  `swift-compile: no swift.org toolchain at ${options.toolchainBin}; install ${options.release} and its matching wasm sdk`
3480
3793
  );
3481
3794
  }
3482
- const macroPlugins = await ensureMacroPlugins(moduleRoot, options.toolchainBin);
3795
+ const macroPlugins = await ensureMacroPlugins(
3796
+ moduleRoot,
3797
+ options.toolchainBin,
3798
+ options.release
3799
+ );
3483
3800
  const sdk = swiftModuleSdk(moduleRoot).wasmSdkId;
3484
3801
  const icu = swiftIcuAsset(options.toolchainBin, sdk);
3485
3802
  try {
@@ -3487,6 +3804,8 @@ function compileSwiftProjectUnit(input, options) {
3487
3804
  swift,
3488
3805
  [
3489
3806
  "build",
3807
+ "--build-system",
3808
+ "native",
3490
3809
  "-j",
3491
3810
  BUILD_JOBS,
3492
3811
  "--package-path",
@@ -3665,24 +3984,135 @@ var DAEMON_LOCKFILE_MAX_BYTES = 16 * 1024;
3665
3984
 
3666
3985
  // src/swift-distribution.lock.json
3667
3986
  var swift_distribution_lock_default = {
3668
- id: "dd4939815d74c469",
3669
- release: "swift-6.3-RELEASE",
3670
- wasmSdkId: "swift-6.3-RELEASE_wasm-peach-41921598-peach-edd95e37",
3671
- wasmSdkUrl: "https://r2.rnxsim.com/swift-wasm-sdk/swift-6.3-RELEASE_wasm-peach-41921598-peach-edd95e37.artifactbundle.tar.gz",
3672
- wasmSdkChecksum: "e8b76a6b78c21e9e16a6943a691ea001aeb0a18518d775a26130520303eb5c6d",
3673
- source: "65037f7f51d461fcf993549d206b3a5dfaa1f58f",
3987
+ id: "3246f7e5ccb24952",
3988
+ release: "swift-6.4.0-RELEASE",
3989
+ wasmSdkId: "swift-6.4.0-RELEASE_wasm-peach-e4629014",
3990
+ wasmSdkUrl: "https://r2.sootsim.com/swift-wasm-sdk/swift-6.4.0-RELEASE_wasm-peach-e4629014.artifactbundle.tar.gz",
3991
+ wasmSdkChecksum: "522f3ff98e951872d64751376d45e36394e572ec2aa4e0a52fb0027824bf41f6",
3992
+ source: "a1e87668019272a329f6d9fada213573e3c5107f",
3993
+ targets: [
3994
+ "ExpoModulesCore",
3995
+ "PeachJSON",
3996
+ "PeachFoundation",
3997
+ "FoundationNetworking",
3998
+ "DeveloperToolsSupport",
3999
+ "SwiftUI",
4000
+ "Dispatch",
4001
+ "Darwin",
4002
+ "MachO",
4003
+ "ObjectiveC",
4004
+ "PeachObjC",
4005
+ "UIKitCore",
4006
+ "PeachICU",
4007
+ "CoreImage",
4008
+ "QuartzCore",
4009
+ "CoreGraphics",
4010
+ "AppTrackingTransparency",
4011
+ "StoreKit",
4012
+ "WeatherKit",
4013
+ "DeviceCheck",
4014
+ "PassKit",
4015
+ "Translation",
4016
+ "CoreSpotlight",
4017
+ "CoreVideo",
4018
+ "CoreMedia",
4019
+ "VideoToolbox",
4020
+ "AdSupport",
4021
+ "BackgroundTasks",
4022
+ "LocalAuthentication",
4023
+ "CoreMotion",
4024
+ "MessageUI",
4025
+ "GameController",
4026
+ "MetricKit",
4027
+ "Metal",
4028
+ "AuthenticationServices",
4029
+ "os",
4030
+ "Charts",
4031
+ "Symbols",
4032
+ "UniformTypeIdentifiers",
4033
+ "WidgetKit",
4034
+ "ActivityKit",
4035
+ "SwiftData",
4036
+ "UIKit",
4037
+ "Combine",
4038
+ "PeachFoundationCombine",
4039
+ "AppIntents",
4040
+ "PhotosUI",
4041
+ "AVFoundation",
4042
+ "AVFAudio",
4043
+ "UserNotifications",
4044
+ "Network",
4045
+ "OSLog",
4046
+ "Security",
4047
+ "Accelerate",
4048
+ "CoreText",
4049
+ "CommonCrypto",
4050
+ "PeachCodec",
4051
+ "Compression",
4052
+ "zlib",
4053
+ "CryptoKit",
4054
+ "TikTokBusinessSDK",
4055
+ "nSure",
4056
+ "Statsig",
4057
+ "TOCropViewController",
4058
+ "RiveRuntime",
4059
+ "MetalKit",
4060
+ "DatadogCore",
4061
+ "DatadogLogs",
4062
+ "DatadogRUM",
4063
+ "DatadogTrace",
4064
+ "AppLovinSDK",
4065
+ "GoogleMobileAds",
4066
+ "AppsFlyerLib",
4067
+ "FBSDKCoreKit",
4068
+ "FBAEMKit",
4069
+ "FBSDKCoreKit_Basics",
4070
+ "FirebaseCore",
4071
+ "FirebaseSharedSwift",
4072
+ "FirebaseRemoteConfig",
4073
+ "FirebaseFirestoreInternal",
4074
+ "FirebaseAnalytics",
4075
+ "FirebaseAppCheck",
4076
+ "FirebaseAuth",
4077
+ "FirebaseCrashlytics",
4078
+ "FirebaseFirestore",
4079
+ "FirebaseStorage",
4080
+ "Intercom",
4081
+ "FBAudienceNetwork",
4082
+ "NaturalLanguage",
4083
+ "AVKit",
4084
+ "SafariServices",
4085
+ "QuickLook",
4086
+ "CoreHaptics",
4087
+ "WebKit",
4088
+ "Photos",
4089
+ "LinkPresentation",
4090
+ "FoundationModels",
4091
+ "CoreTransferable",
4092
+ "AudioToolbox",
4093
+ "Intents",
4094
+ "MobileCoreServices",
4095
+ "ImageIO",
4096
+ "CoreLocationEnums",
4097
+ "CoreLocation",
4098
+ "MapKit",
4099
+ "One",
4100
+ "GameplayKit",
4101
+ "SpriteKit",
4102
+ "PeachBox2D"
4103
+ ],
3674
4104
  hosts: {
3675
4105
  "darwin-arm64": {
3676
- sha256: "d15d78a731a2613ab34d199f45aec8d4a6046ce54155f321ea67f9f7476e5dfd",
3677
- size: 47319022
4106
+ sha256: "fb5a3e9db1eae670b5ba84432345e52de8b55b5fdf0e468ff95dfa25a62a6968",
4107
+ size: 55050821
3678
4108
  },
3679
4109
  "linux-x64": {
3680
- sha256: "0bcedbd713a5682041638fb99204b20b62437636302359f9a60fa2cb103acbf2",
3681
- size: 47324525
4110
+ sha256: "46a0eae68905751ee7c6536e79f626bc71d9d5a22cf9a76ce12b8d6c3aa34293",
4111
+ size: 55056198
3682
4112
  },
3683
4113
  "linux-arm64": {
3684
- sha256: "dfb7d0abf23a5c006ad81b06d4263b01f903220d5b15717d5c224f959c0e422f",
3685
- size: 47323454
4114
+ sha256: "ea6453b55ff428d4d152d829731504400d49969ab0750264a931eaf0d7659122",
4115
+ size: 55055213
3686
4116
  }
3687
4117
  }
3688
4118
  };
@@ -3692,6 +4122,9 @@ var import_node_child_process4 = require("node:child_process");
3692
4122
  var import_node_fs4 = __toESM(require("node:fs"), 1);
3693
4123
  var import_node_os4 = __toESM(require("node:os"), 1);
3694
4124
  var import_node_path5 = __toESM(require("node:path"), 1);
4125
+ function swiftCompilerRelease(release) {
4126
+ return release.replace(/^swift-(\d+\.\d+)\.0-RELEASE$/, "swift-$1-RELEASE");
4127
+ }
3695
4128
  function swiftToolchainBin(release) {
3696
4129
  if (process.platform === "darwin") {
3697
4130
  const dirs = [import_node_os4.default.homedir(), "/"].map(
@@ -3716,7 +4149,7 @@ function swiftToolchain(release, sdk) {
3716
4149
  encoding: "utf8",
3717
4150
  stdio: ["ignore", "pipe", "pipe"]
3718
4151
  }) : "";
3719
- if (!version.includes(`(${release})`)) {
4152
+ if (!version.includes(`(${swiftCompilerRelease(release)})`)) {
3720
4153
  const found = version ? `found ${version.split("\n")[0]?.trim()} at ${swift}` : process.platform === "darwin" ? `found no ${release}.xctoolchain in ~/Library/Developer/Toolchains or /Library/Developer/Toolchains` : "found no swift on PATH";
3721
4154
  throw new Error(
3722
4155
  `peach compiles Swift with the swift.org toolchain ${release} and its wasm SDK; ${found}.
@@ -3805,12 +4238,15 @@ function swiftDistributionRoot() {
3805
4238
  }
3806
4239
  return pending;
3807
4240
  }
3808
- async function resolveSwiftModule() {
4241
+ async function resolveSwiftModule({
4242
+ required = false
4243
+ } = {}) {
3809
4244
  const checkout2 = import_node_path6.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift");
3810
4245
  if (import_node_fs5.default.existsSync(import_node_path6.default.join(checkout2, "toolchain.json"))) {
3811
4246
  try {
3812
4247
  return { root: checkout2, ...swiftModuleToolchain(checkout2) };
3813
- } catch {
4248
+ } catch (error) {
4249
+ if (required) throw error;
3814
4250
  return null;
3815
4251
  }
3816
4252
  }
@@ -3851,17 +4287,17 @@ function baseOf(file) {
3851
4287
  const slash = file.lastIndexOf("/");
3852
4288
  return slash < 0 ? file : file.slice(slash + 1);
3853
4289
  }
3854
- function pickImagesetFile(images) {
3855
- const rasters = images.filter(
3856
- (image) => typeof image.filename === "string" && RASTER_EXTENSIONS.has(extOf(image.filename))
3857
- );
3858
- if (rasters.length === 0) return null;
3859
- const rank = (scale) => scale === "2x" ? 0 : scale === "3x" ? 1 : scale === "1x" ? 2 : 3;
3860
- const pick = [...rasters].sort((a, b) => rank(a.scale) - rank(b.scale))[0];
3861
- return {
3862
- filename: pick.filename,
3863
- scale: pick.scale === "2x" ? 2 : pick.scale === "3x" ? 3 : 1
3864
- };
4290
+ function imagesetFiles(images) {
4291
+ return images.flatMap((image) => {
4292
+ if (typeof image.filename !== "string" || !RASTER_EXTENSIONS.has(extOf(image.filename)) || image.filename.includes("/") || image.filename.includes("\\"))
4293
+ return [];
4294
+ return [
4295
+ {
4296
+ filename: image.filename,
4297
+ scale: image.scale === "2x" ? 2 : image.scale === "3x" ? 3 : 1
4298
+ }
4299
+ ];
4300
+ }).sort((a, b) => a.scale - b.scale);
3865
4301
  }
3866
4302
  function flatScale(path16) {
3867
4303
  const match = /@([23])x\.[^./]+$/.exec(path16);
@@ -3894,13 +4330,23 @@ function catalogEntryName(contentsPath, kind, readText) {
3894
4330
  function isFlatResourceImage(path16) {
3895
4331
  return path16.split("/").includes("Resources") && RASTER_EXTENSIONS.has(extOf(path16));
3896
4332
  }
3897
- function enumerateBundleImages(paths, readText) {
4333
+ function enumerateBundleImages(paths, readText, bundleForFile = () => ".") {
3898
4334
  const table = [];
3899
- const seen = /* @__PURE__ */ new Set();
4335
+ const seen = /* @__PURE__ */ new Map();
4336
+ const namesFor = (file) => {
4337
+ const bundlePath = bundleForFile(file);
4338
+ if (!isSwiftBundlePath(bundlePath))
4339
+ throw new Error(`invalid image bundle ${bundlePath}`);
4340
+ const names = seen.get(bundlePath) ?? /* @__PURE__ */ new Set();
4341
+ seen.set(bundlePath, names);
4342
+ return { bundlePath, names };
4343
+ };
3900
4344
  const catalogs = paths.filter((path16) => baseOf(path16) === "Contents.json");
3901
4345
  for (const contentsPath of catalogs) {
3902
4346
  const name2 = catalogEntryName(contentsPath, ".imageset", readText);
3903
- if (name2 === null || seen.has(name2)) continue;
4347
+ if (name2 === null) continue;
4348
+ const { bundlePath, names } = namesFor(contentsPath);
4349
+ if (names.has(name2)) continue;
3904
4350
  let parsed;
3905
4351
  try {
3906
4352
  const text3 = readText(contentsPath);
@@ -3912,18 +4358,24 @@ function enumerateBundleImages(paths, readText) {
3912
4358
  const images = parsed?.images;
3913
4359
  if (!Array.isArray(images)) continue;
3914
4360
  const dir = contentsPath.split("/").slice(0, -1).join("/");
3915
- const pick = pickImagesetFile(images);
3916
- if (pick === null || pick.filename.includes("/") || pick.filename.includes("\\"))
3917
- continue;
3918
- seen.add(name2);
3919
- table.push({ name: name2, file: `${dir}/${pick.filename}`, scale: pick.scale });
4361
+ const variants = imagesetFiles(images);
4362
+ if (variants.length === 0) continue;
4363
+ names.add(name2);
4364
+ for (const variant of variants)
4365
+ table.push({
4366
+ name: name2,
4367
+ file: `${dir}/${variant.filename}`,
4368
+ scale: variant.scale,
4369
+ bundlePath
4370
+ });
3920
4371
  }
3921
4372
  for (const path16 of paths) {
3922
4373
  if (!isFlatResourceImage(path16)) continue;
3923
4374
  const name2 = baseOf(path16).slice(0, -extOf(path16).length);
3924
- if (name2 === "" || seen.has(name2)) continue;
3925
- seen.add(name2);
3926
- table.push({ name: name2, file: path16, scale: flatScale(path16) });
4375
+ const { bundlePath, names } = namesFor(path16);
4376
+ if (name2 === "" || names.has(name2)) continue;
4377
+ names.add(name2);
4378
+ table.push({ name: name2, file: path16, scale: flatScale(path16), bundlePath });
3927
4379
  }
3928
4380
  return table;
3929
4381
  }
@@ -4043,11 +4495,14 @@ function guide(svg, id, axis) {
4043
4495
  const value = line === void 0 ? void 0 : new RegExp(`${axis}="([-0-9.]+)"`).exec(line)?.[1];
4044
4496
  return value === void 0 ? null : Number(value);
4045
4497
  }
4046
- function enumerateBundleSymbols(paths, readText) {
4498
+ function enumerateBundleSymbols(paths, readText, bundleForFile) {
4047
4499
  const table = {};
4048
4500
  for (const contentsPath of paths.filter((path16) => baseOf(path16) === "Contents.json")) {
4049
4501
  const name2 = catalogEntryName(contentsPath, ".symbolset", readText);
4050
- if (name2 === null || name2 in table) continue;
4502
+ if (name2 === null) continue;
4503
+ const bundle = bundleForFile(contentsPath);
4504
+ const key2 = bundle === "." ? name2 : `${bundle}/${name2}`;
4505
+ if (Object.hasOwn(table, key2)) continue;
4051
4506
  let symbols;
4052
4507
  try {
4053
4508
  symbols = Reflect.get(JSON.parse(readText(contentsPath) ?? "null") ?? {}, "symbols");
@@ -4074,7 +4529,7 @@ function enumerateBundleSymbols(paths, readText) {
4074
4529
  const translateY = 12 - (box.minY + box.maxY) * scale / 2;
4075
4530
  const advance = Math.round((right - left) * scale * 1e3) / 1e3;
4076
4531
  const tall = (box.maxY - box.minY) * scale + 0.175 * 24;
4077
- table[name2] = {
4532
+ table[key2] = {
4078
4533
  viewBox: "0 0 24 24",
4079
4534
  advance,
4080
4535
  box: [12 - advance / 2, 12 - tall / 2, advance, tall],
@@ -4085,11 +4540,18 @@ function enumerateBundleSymbols(paths, readText) {
4085
4540
  }
4086
4541
  return table;
4087
4542
  }
4088
- function enumerateBundleJson(paths) {
4543
+ var COMPILED_EXTENSIONS = /* @__PURE__ */ new Set([".swift", ".metal", ".storyboard", ".xib"]);
4544
+ var NESTED_BUNDLE_DIR = /\.(?:xcassets|lproj)$/;
4545
+ function isCopiedResource(path16) {
4546
+ const ext = extOf(path16);
4547
+ if (ext === ".json" || ext === ".xcstrings") return true;
4548
+ return !RASTER_EXTENSIONS.has(ext) && !COMPILED_EXTENSIONS.has(ext) && !path16.split("/").some((segment) => NESTED_BUNDLE_DIR.test(segment));
4549
+ }
4550
+ function enumerateBundleResources(paths) {
4089
4551
  const found = [];
4090
4552
  const seen = /* @__PURE__ */ new Set();
4091
4553
  const ordered = [...paths].filter(
4092
- (path16) => path16.split("/").includes("Resources") && path16.split("/").every((segment) => segment !== "" && segment !== "..") && (extOf(path16) === ".json" || extOf(path16) === ".xcstrings")
4554
+ (path16) => path16.split("/").includes("Resources") && path16.split("/").every((segment) => segment !== "" && segment !== "..") && isCopiedResource(path16)
4093
4555
  ).sort((a, b) => {
4094
4556
  const aDepth = a.split("/").length;
4095
4557
  const bDepth = b.split("/").length;
@@ -4566,7 +5028,7 @@ function frameworkModules(paths) {
4566
5028
  }
4567
5029
  async function range(url, spec) {
4568
5030
  const response = await fetch(url, {
4569
- headers: { range: `bytes=${spec}` },
5031
+ headers: { range: `bytes=${spec}`, "accept-encoding": "identity" },
4570
5032
  signal: AbortSignal.timeout(2e4)
4571
5033
  });
4572
5034
  const match = /^bytes (\d+)-\d+\/(\d+)$/.exec(
@@ -4632,11 +5094,6 @@ async function swiftBinaryModules(binary) {
4632
5094
  return modules;
4633
5095
  }
4634
5096
 
4635
- // src/swift-packages.ts
4636
- var import_node_child_process6 = require("node:child_process");
4637
- var import_node_fs9 = __toESM(require("node:fs"), 1);
4638
- var import_node_path10 = __toESM(require("node:path"), 1);
4639
-
4640
5097
  // src/swift-package-manifest.ts
4641
5098
  var import_node_child_process5 = require("node:child_process");
4642
5099
  var import_node_crypto5 = require("node:crypto");
@@ -4757,10 +5214,10 @@ function swiftPackageManifest(dir) {
4757
5214
  }
4758
5215
  const products = /* @__PURE__ */ new Map();
4759
5216
  for (const product of array(raw2.products)) {
4760
- const { name: name2, targets: targets2, type } = record(product);
4761
- if (!string(name2) || !("library" in record(type))) continue;
5217
+ const { name: name3, targets: targets2, type } = record(product);
5218
+ if (!string(name3) || !("library" in record(type))) continue;
4762
5219
  products.set(
4763
- string(name2),
5220
+ string(name3),
4764
5221
  array(targets2).flatMap((target) => string(target) ?? [])
4765
5222
  );
4766
5223
  }
@@ -4768,12 +5225,12 @@ function swiftPackageManifest(dir) {
4768
5225
  const names = new Set(array(raw2.targets).map((target) => string(record(target).name)));
4769
5226
  for (const entry of array(raw2.targets)) {
4770
5227
  const target = record(entry);
4771
- const name2 = string(target.name);
5228
+ const name3 = string(target.name);
4772
5229
  const kind = string(target.type);
4773
- if (!name2 || !isTargetType(kind)) continue;
5230
+ if (!name3 || !isTargetType(kind)) continue;
4774
5231
  const declared = string(target.path);
4775
5232
  const roots = kind === "test" ? ["Tests"] : ["Sources", "Source", "src", "srcs"];
4776
- const targetDir = declared ? import_node_path9.default.resolve(dir, declared) : roots.map((root) => import_node_path9.default.join(dir, root, name2)).find((candidate) => import_node_fs8.default.existsSync(candidate)) ?? import_node_path9.default.join(dir, roots[0], name2);
5233
+ const targetDir = declared ? import_node_path9.default.resolve(dir, declared) : roots.map((root) => import_node_path9.default.join(dir, root, name3)).find((candidate) => import_node_fs8.default.existsSync(candidate)) ?? import_node_path9.default.join(dir, roots[0], name3);
4777
5234
  const dependencies = [];
4778
5235
  for (const dependency of array(target.dependencies)) {
4779
5236
  const { target: local, product, byName } = record(dependency);
@@ -4798,16 +5255,26 @@ function swiftPackageManifest(dir) {
4798
5255
  }
4799
5256
  let languageMode = packageMode;
4800
5257
  let mainActorIsolation = false;
5258
+ const defines = [];
4801
5259
  for (const setting of array(target.settings)) {
4802
- const settingKind = record(record(setting).kind);
5260
+ const { kind: rawKind, tool, condition } = record(setting);
5261
+ const settingKind = record(rawKind);
4803
5262
  const mode = string(record(settingKind.swiftLanguageMode)._0);
4804
5263
  if (mode)
4805
5264
  languageMode = Math.max(5, Number(/^(\d+)/.exec(mode)?.[1] ?? languageMode));
4806
5265
  if (string(record(settingKind.defaultIsolation)._0) === "MainActor")
4807
5266
  mainActorIsolation = true;
5267
+ const define = string(record(settingKind.define)._0);
5268
+ if (define && string(tool) === "swift" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(define) && linksOnIOS(condition, traits)) {
5269
+ const config = string(record(condition).config);
5270
+ defines.push({
5271
+ name: define,
5272
+ configuration: config === "debug" || config === "release" ? config : null
5273
+ });
5274
+ }
4808
5275
  }
4809
- targets.set(name2, {
4810
- name: name2,
5276
+ targets.set(name3, {
5277
+ name: name3,
4811
5278
  type: kind,
4812
5279
  dir: targetDir,
4813
5280
  sources: target.sources == null ? null : array(target.sources).flatMap((file) => string(file) ?? []),
@@ -4815,12 +5282,15 @@ function swiftPackageManifest(dir) {
4815
5282
  dependencies,
4816
5283
  languageMode,
4817
5284
  mainActorIsolation,
5285
+ defines,
4818
5286
  declaresResources: array(target.resources).length > 0,
4819
5287
  url: string(target.url) ?? null,
4820
5288
  checksum: string(target.checksum) ?? null
4821
5289
  });
4822
5290
  }
4823
- const manifest = { dir, products, targets, packages };
5291
+ const name2 = string(raw2.name);
5292
+ if (!name2) throw new Error(`swiftpm returned no package name for ${dir}`);
5293
+ const manifest = { name: name2, dir, products, targets, packages };
4824
5294
  evaluated.set(key2, manifest);
4825
5295
  return manifest;
4826
5296
  }
@@ -4849,6 +5319,9 @@ function swiftTargetFiles(manifest, target) {
4849
5319
  }
4850
5320
 
4851
5321
  // src/swift-packages.ts
5322
+ var import_node_child_process6 = require("node:child_process");
5323
+ var import_node_fs9 = __toESM(require("node:fs"), 1);
5324
+ var import_node_path10 = __toESM(require("node:path"), 1);
4852
5325
  var REMOTE_CHECKOUTS = import_node_path10.default.join(".build", "peach", "checkouts");
4853
5326
  var C_FAMILY = /\.(c|cc|cpp|cxx|m|mm|s|S)$/;
4854
5327
  var BINARY = "is a binary framework";
@@ -4967,6 +5440,7 @@ function resolveSwiftPackages(options) {
4967
5440
  files: files2,
4968
5441
  packageDir: pkg.manifest.dir,
4969
5442
  remote: pkg.remote,
5443
+ packageDefines: target.defines,
4970
5444
  executable: false,
4971
5445
  languageMode: target.languageMode,
4972
5446
  mainActorIsolation: target.mainActorIsolation,
@@ -5161,6 +5635,7 @@ function getCliVersion() {
5161
5635
 
5162
5636
  // src/swift-standin-emit.ts
5163
5637
  var STANDIN_EMIT_VERSION = "5";
5638
+ var STANDIN_IMPORTS = ["Foundation", "UIKit"];
5164
5639
  var TYPE_KINDS = /* @__PURE__ */ new Set([
5165
5640
  "swift.class",
5166
5641
  "swift.struct",
@@ -5781,7 +6256,7 @@ function emitSwiftStandin(graphs, options) {
5781
6256
  else emitMember(member, " ", { openOwner: false, inClass: false });
5782
6257
  emit(`}`);
5783
6258
  }
5784
- const imports = ["Foundation", "UIKit", ...options.imports ?? []];
6259
+ const imports = [...STANDIN_IMPORTS, ...options.imports ?? []];
5785
6260
  const banner = [
5786
6261
  `// stand-in for the binary ${options.module} module, generated from ${options.source}.`,
5787
6262
  `// do not hand-edit: every body traps because the vendor binary cannot run`,
@@ -5982,6 +6457,8 @@ function xcframework(binary) {
5982
6457
  var files = (dir, test) => import_node_fs12.default.existsSync(dir) ? import_node_fs12.default.readdirSync(dir, { recursive: true, encoding: "utf8" }).filter((file) => test(import_node_path12.default.basename(file))).sort() : [];
5983
6458
  function surfaces(xcframeworkDir) {
5984
6459
  const slice = import_node_fs12.default.readdirSync(xcframeworkDir).filter((name2) => /^ios-.+-simulator$/.test(name2)).sort()[0];
6460
+ if (!slice && xcframeworkDir.endsWith(".framework"))
6461
+ throw new Error("a plain .framework has no .xcframework simulator slice");
5985
6462
  if (!slice) throw new Error("it has no iOS simulator slice");
5986
6463
  const root = import_node_path12.default.join(xcframeworkDir, slice);
5987
6464
  const found = [];
@@ -6024,6 +6501,9 @@ function peachModuleDirs(toolchain, imports) {
6024
6501
  const { moduleRoot, toolchainBin } = toolchain;
6025
6502
  if (swiftDistributionAt(moduleRoot)) return [import_node_path12.default.join(moduleRoot, "modules")];
6026
6503
  const peach = new Set(swiftPeachModules(moduleRoot));
6504
+ const targets = [.../* @__PURE__ */ new Set([...STANDIN_IMPORTS, ...imports])].filter(
6505
+ (name2) => peach.has(name2)
6506
+ );
6027
6507
  const plugins = swiftMacroPlugins(moduleRoot);
6028
6508
  if (plugins.stale)
6029
6509
  exec("sh", [
@@ -6031,11 +6511,15 @@ function peachModuleDirs(toolchain, imports) {
6031
6511
  toolchainBin,
6032
6512
  plugins.libraries[0]
6033
6513
  ]);
6034
- for (const target of imports.filter((name2) => peach.has(name2)))
6514
+ for (const target of targets)
6035
6515
  exec(
6036
6516
  import_node_path12.default.join(toolchainBin, "swift"),
6037
6517
  [
6038
6518
  "build",
6519
+ "--build-system",
6520
+ "native",
6521
+ "-j",
6522
+ "4",
6039
6523
  "--swift-sdk",
6040
6524
  swiftModuleSdk(moduleRoot).wasmSdkId,
6041
6525
  "-c",
@@ -6062,7 +6546,12 @@ function peachModuleDirs(toolchain, imports) {
6062
6546
  ];
6063
6547
  }
6064
6548
  function swiftInterfaceForWasm(text3) {
6065
- return text3.replace(
6549
+ const rooted = text3.replace(
6550
+ /\bObjectiveC(\.|::)(NSObject|NSObjectProtocol)\b/g,
6551
+ "Foundation$1$2"
6552
+ );
6553
+ const foundation = rooted !== text3 && !/^import[ \t]+Foundation\b/m.test(rooted) ? rooted.replace(/^(?=import[ \t])/m, "import Foundation\n") : rooted;
6554
+ return foundation.replace(
6066
6555
  /^(\/\/ swift-module-flags:.*)$/m,
6067
6556
  (flags) => flags.replace(/-target \S+/, `-target ${TRIPLE}`).replace(/\s-enable-objc-interop\b/, "").replace(/\s-target-variant \S+/, "")
6068
6557
  ).replace(
@@ -6381,6 +6870,167 @@ ${roots.map((file) => ` header "${file}"
6381
6870
  }
6382
6871
  };
6383
6872
  }
6873
+ var RUST_TARGET = "wasm32-wasip1";
6874
+ var UNSEARCHED = /* @__PURE__ */ new Set([
6875
+ "node_modules",
6876
+ "Pods",
6877
+ "target",
6878
+ ".build",
6879
+ ".git",
6880
+ "DerivedData"
6881
+ ]);
6882
+ function crateFor(root, name2) {
6883
+ const walk2 = (dir, depth) => {
6884
+ const manifest = import_node_path12.default.join(dir, "Cargo.toml");
6885
+ if (import_node_fs12.default.existsSync(manifest)) {
6886
+ const text3 = import_node_fs12.default.readFileSync(manifest, "utf8");
6887
+ const section = (title) => new RegExp(`^\\[${title}\\]\\s*$([\\s\\S]*?)(?=^\\[|(?![\\s\\S]))`, "m").exec(
6888
+ text3
6889
+ )?.[1] ?? "";
6890
+ const field = (body, key2) => new RegExp(`^${key2}\\s*=\\s*"([^"]+)"`, "m").exec(body)?.[1];
6891
+ const lib = section("lib");
6892
+ const crate = field(lib, "name") ?? field(section("package"), "name")?.replaceAll("-", "_");
6893
+ if (crate === name2) {
6894
+ if (!/crate-type\s*=\s*\[[^\]]*"staticlib"/.test(lib))
6895
+ throw new Error(
6896
+ `${import_node_path12.default.relative(root, manifest)} builds lib${name2} without crate-type "staticlib"`
6897
+ );
6898
+ return manifest;
6899
+ }
6900
+ }
6901
+ if (depth === 0) return null;
6902
+ for (const entry of import_node_fs12.default.readdirSync(dir, { withFileTypes: true })) {
6903
+ if (!entry.isDirectory() || UNSEARCHED.has(entry.name) || entry.name.endsWith(".xcframework"))
6904
+ continue;
6905
+ const found = walk2(import_node_path12.default.join(dir, entry.name), depth - 1);
6906
+ if (found) return found;
6907
+ }
6908
+ return null;
6909
+ };
6910
+ return walk2(root, 4);
6911
+ }
6912
+ function standinLibrary(binary, searchRoot) {
6913
+ const dir = xcframework(binary).dir;
6914
+ const slice = import_node_fs12.default.readdirSync(dir).filter((name2) => /^ios-.+-simulator$/.test(name2)).sort()[0];
6915
+ const library = slice ? import_node_fs12.default.readdirSync(import_node_path12.default.join(dir, slice)).find((name2) => /^lib.+\.a$/.test(name2)) : void 0;
6916
+ const supplied = import_node_path12.default.join(dir, RUST_TARGET);
6917
+ if (import_node_fs12.default.existsSync(supplied)) {
6918
+ const found = import_node_fs12.default.readdirSync(supplied).filter((name2) => name2.endsWith(".a"));
6919
+ const chosen = library && found.includes(library) ? library : found.length === 1 ? found[0] : null;
6920
+ if (!chosen)
6921
+ throw new Error(
6922
+ `${import_node_path12.default.relative(searchRoot, supplied)} holds no single static library${library ? ` named ${library}` : ""}`
6923
+ );
6924
+ return import_node_path12.default.join(supplied, chosen);
6925
+ }
6926
+ if (!library) return null;
6927
+ const manifest = crateFor(searchRoot, library.slice("lib".length, -".a".length));
6928
+ if (!manifest) return null;
6929
+ const result = (0, import_node_child_process7.spawnSync)(
6930
+ "cargo",
6931
+ [
6932
+ "build",
6933
+ "--release",
6934
+ "--target",
6935
+ RUST_TARGET,
6936
+ "--message-format=json-render-diagnostics",
6937
+ "--manifest-path",
6938
+ manifest
6939
+ ],
6940
+ {
6941
+ encoding: "utf8",
6942
+ maxBuffer: 256 * 1024 * 1024,
6943
+ stdio: ["ignore", "pipe", "pipe"]
6944
+ }
6945
+ );
6946
+ const crate = import_node_path12.default.relative(searchRoot, import_node_path12.default.dirname(manifest));
6947
+ if (result.error)
6948
+ throw new Error(
6949
+ `${crate} is a rust crate and cargo is not installed; install rust (https://rustup.rs), then run again`
6950
+ );
6951
+ if (result.status !== 0) {
6952
+ if (/target may not be installed|can't find crate for `(core|std)`/.test(result.stderr))
6953
+ throw new Error(
6954
+ `${crate} builds for ${RUST_TARGET}, which this rust lacks; run \`rustup target add ${RUST_TARGET}\`, then run again`
6955
+ );
6956
+ throw new Error(
6957
+ `cargo could not build ${crate} for ${RUST_TARGET}: ${failure(result)}`
6958
+ );
6959
+ }
6960
+ for (const line of result.stdout.split("\n")) {
6961
+ if (!line.startsWith("{")) continue;
6962
+ const message = JSON.parse(line);
6963
+ if (!message || typeof message !== "object" || !("filenames" in message) || !Array.isArray(message.filenames))
6964
+ continue;
6965
+ const archive = message.filenames.find(
6966
+ (file) => typeof file === "string" && import_node_path12.default.basename(file) === library
6967
+ );
6968
+ if (archive) return archive;
6969
+ }
6970
+ throw new Error(`cargo built ${crate} for ${RUST_TARGET} but reported no ${library}`);
6971
+ }
6972
+ function sourceBinaryStandins(binary, toolchain, provided) {
6973
+ const repo = import_node_path12.default.resolve(toolchain.moduleRoot, "../..");
6974
+ const work = import_node_fs12.default.mkdtempSync(import_node_path12.default.join(import_node_os7.default.tmpdir(), "peach-standin-request-"));
6975
+ try {
6976
+ const artifact = xcframework(binary);
6977
+ const local = { ...binary, dir: artifact.dir, url: null, checksum: null };
6978
+ const generation = standinGenerationInputs([local], toolchain);
6979
+ const request = import_node_path12.default.join(work, "request.json");
6980
+ const delivery = import_node_path12.default.join(work, "delivery");
6981
+ import_node_fs12.default.writeFileSync(
6982
+ request,
6983
+ JSON.stringify({
6984
+ binary: local,
6985
+ provided: [...provided],
6986
+ generation,
6987
+ release: toolchain.release,
6988
+ callerToolchainBin: toolchain.toolchainBin
6989
+ })
6990
+ );
6991
+ (0, import_node_child_process7.execFileSync)(
6992
+ "bash",
6993
+ [
6994
+ import_node_path12.default.join(repo, "scripts/build/remote.sh"),
6995
+ // a deadline makes a busy pool wait for a slot; without one it refuses
6996
+ // at once and the app reads as missing a module
6997
+ "--timeout",
6998
+ "1800",
6999
+ "--delivery-dir",
7000
+ delivery,
7001
+ "--toolchain",
7002
+ "packages/sootsim-swift/toolchain.json",
7003
+ "--input",
7004
+ request,
7005
+ "--input",
7006
+ artifact.dir,
7007
+ "bun",
7008
+ "scripts/build/swift-standins.ts",
7009
+ "--request",
7010
+ ".remote-inputs/request.json",
7011
+ "--artifact",
7012
+ `.remote-inputs/${import_node_path12.default.basename(artifact.dir)}`,
7013
+ "--output",
7014
+ ".remote-out/standins.json"
7015
+ ],
7016
+ { cwd: repo, stdio: "inherit" }
7017
+ );
7018
+ const receipt = JSON.parse(
7019
+ import_node_fs12.default.readFileSync(import_node_path12.default.join(delivery, "standins.json"), "utf8")
7020
+ );
7021
+ if (!receipt || typeof receipt !== "object" || !("generation" in receipt) || receipt.generation !== generation || !("result" in receipt))
7022
+ throw new Error("Swift stand-in builder source differs from the caller");
7023
+ const result = receipt.result;
7024
+ if (typeof result === "string") return result;
7025
+ if (!Array.isArray(result) || !result.every(
7026
+ (item) => item && typeof item === "object" && typeof item.module === "string" && typeof item.target === "string" && item.target === binary.target && item.files && typeof item.files === "object" && !Array.isArray(item.files) && Object.values(item.files).every((text3) => typeof text3 === "string")
7027
+ ))
7028
+ throw new Error("invalid Swift stand-in builder result");
7029
+ return result;
7030
+ } finally {
7031
+ import_node_fs12.default.rmSync(work, { recursive: true, force: true });
7032
+ }
7033
+ }
6384
7034
  var built = /* @__PURE__ */ new Map();
6385
7035
  function standinGenerationInputs(binaries, toolchain) {
6386
7036
  const { moduleRoot, toolchainBin, release } = toolchain;
@@ -6457,7 +7107,7 @@ function binaryStandins(binary, toolchain, provided) {
6457
7107
  const work = import_node_fs12.default.mkdtempSync(import_node_path12.default.join(import_node_os7.default.tmpdir(), "peach-standin-"));
6458
7108
  let result;
6459
7109
  try {
6460
- result = found.map((surface) => {
7110
+ result = process.platform === "darwin" && process.env.TM_SESSION && process.env.CI !== "true" && toolchain.moduleRoot === import_node_path12.default.resolve(__sootsim_import_meta_dirname, "../../sootsim-swift") && !swiftDistributionAt(toolchain.moduleRoot) ? sourceBinaryStandins(binary, toolchain, provided) : found.map((surface) => {
6461
7111
  const dir = import_node_path12.default.join(work, surface.module);
6462
7112
  try {
6463
7113
  return surface.kind === "swift" ? swiftStandin(surface, binary, toolchain, dir) : cStandin(surface, binary, toolchain, dir);
@@ -6467,6 +7117,7 @@ function binaryStandins(binary, toolchain, provided) {
6467
7117
  );
6468
7118
  }
6469
7119
  });
7120
+ if (typeof result === "string") return result;
6470
7121
  import_node_fs12.default.mkdirSync(import_node_path12.default.dirname(cached2), { recursive: true });
6471
7122
  import_node_fs12.default.writeFileSync(cached2, JSON.stringify(result));
6472
7123
  built.set(id, result);
@@ -6495,10 +7146,13 @@ var MAX_SWIFT_COMPILE_SOURCE_BYTES = 2 * 1024 * 1024;
6495
7146
  var MAX_SWIFT_COMPILE_RESOURCES = 128;
6496
7147
  var MAX_SWIFT_COMPILE_RESOURCE_BYTES = 2 * 1024 * 1024;
6497
7148
  var MAX_SWIFT_COMPILE_RESOURCE_TOTAL_BYTES = 8 * 1024 * 1024;
7149
+ var MAX_SWIFT_COMPILE_METAL_FILES = 128;
7150
+ var MAX_SWIFT_COMPILE_METAL_BYTES = 2 * 1024 * 1024;
7151
+ var MAX_SWIFT_COMPILE_METAL_TOTAL_BYTES = 8 * 1024 * 1024;
6498
7152
  var MAX_SWIFT_COMPILE_IMAGES = 128;
6499
7153
  var MAX_SWIFT_COMPILE_IMAGE_BYTES = 4 * 1024 * 1024;
6500
7154
  var MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES = 16 * 1024 * 1024;
6501
- var SWIFT_HOST_ABI = 24;
7155
+ var SWIFT_HOST_ABI = 41;
6502
7156
  var POLL_INTERVAL_MS = 1500;
6503
7157
  function httpSwiftCompileSubmit(context) {
6504
7158
  const { assetReadToken, authorization, endpoint } = context;
@@ -6543,7 +7197,11 @@ function isRecord2(value) {
6543
7197
  return typeof value === "object" && value !== null && !Array.isArray(value);
6544
7198
  }
6545
7199
  function isSwiftNativeModules(value) {
6546
- return isRecord2(value) && typeof value.packageId === "string" && typeof value.hash === "string" && isRecord2(value.files) && isRecord2(value.modules) && [...Object.values(value.files), ...Object.values(value.modules)].every(
7200
+ return isRecord2(value) && typeof value.packageId === "string" && typeof value.hash === "string" && isRecord2(value.files) && isRecord2(value.modules) && isRecord2(value.views) && [
7201
+ ...Object.values(value.files),
7202
+ ...Object.values(value.modules),
7203
+ ...Object.values(value.views)
7204
+ ].every(
6547
7205
  (names) => Array.isArray(names) && names.every((name2) => typeof name2 === "string")
6548
7206
  ) && Array.isArray(value.defaultViewFiles) && value.defaultViewFiles.every((file) => typeof file === "string");
6549
7207
  }
@@ -6551,7 +7209,7 @@ function isSwiftCompileOutcome(value) {
6551
7209
  if (!isRecord2(value)) return false;
6552
7210
  switch (value.status) {
6553
7211
  case "published":
6554
- return typeof value.artifactUrl === "string" && typeof value.icuUrl === "string" && typeof value.hash === "string" && /^[a-f0-9]{64}$/.test(value.hash) && (value.imageUrls === void 0 || isRecord2(value.imageUrls) && Object.values(value.imageUrls).every((url) => typeof url === "string")) && (value.native === void 0 || isSwiftNativeModules(value.native));
7212
+ return typeof value.artifactUrl === "string" && typeof value.icuUrl === "string" && typeof value.hash === "string" && /^[a-f0-9]{64}$/.test(value.hash) && (value.imageUrls === void 0 || isRecord2(value.imageUrls) && Object.values(value.imageUrls).every((url) => typeof url === "string")) && (value.metalSources === void 0 || isSwiftMetalLibrarySources(value.metalSources)) && (value.native === void 0 || isSwiftNativeModules(value.native));
6555
7213
  case "compiling":
6556
7214
  return typeof value.hash === "string" && /^[a-f0-9]{64}$/.test(value.hash);
6557
7215
  case "refused":
@@ -6586,6 +7244,14 @@ async function compileSwiftProject(submit, work, origin, signal) {
6586
7244
  hash: outcome.hash,
6587
7245
  icuUrl: compileAssetUrl(outcome.icuUrl, origin),
6588
7246
  ...outcome.imageUrls === void 0 ? {} : { imageUrls: resolveImageUrls(outcome.imageUrls, origin) },
7247
+ ...outcome.metalSources === void 0 ? {} : {
7248
+ metalSources: Object.fromEntries(
7249
+ Object.entries(outcome.metalSources).map(([file, source]) => [
7250
+ file,
7251
+ { ...source, url: compileAssetUrl(source.url, origin) }
7252
+ ])
7253
+ )
7254
+ },
6589
7255
  ...outcome.native === void 0 ? {} : { native: outcome.native }
6590
7256
  };
6591
7257
  case "compiling":
@@ -6952,7 +7618,10 @@ function isJsonObject(value) {
6952
7618
  return typeof value === "object" && value !== null && !Array.isArray(value);
6953
7619
  }
6954
7620
 
6955
- // src/xcode-project.ts
7621
+ // src/openstep-plist.ts
7622
+ var isDict = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
7623
+ var str = (value) => typeof value === "string" ? value : void 0;
7624
+ var list = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
6956
7625
  function parseOpenStepPlist(text3) {
6957
7626
  let i = 0;
6958
7627
  const fail = (message) => {
@@ -7010,6 +7679,7 @@ function parseOpenStepPlist(text3) {
7010
7679
  if (typeof key2 !== "string") fail("dictionary key is not a string");
7011
7680
  skip();
7012
7681
  if (text3[i++] !== "=") fail("expected =");
7682
+ if (Object.hasOwn(dict, key2)) fail(`duplicate key ${key2}`);
7013
7683
  dict[key2] = value();
7014
7684
  skip();
7015
7685
  if (text3[i++] !== ";") fail("expected ;");
@@ -7042,9 +7712,8 @@ function parseOpenStepPlist(text3) {
7042
7712
  if (i !== text3.length) fail("trailing content");
7043
7713
  return root;
7044
7714
  }
7045
- var isDict = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
7046
- var str = (value) => typeof value === "string" ? value : void 0;
7047
- var list = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
7715
+
7716
+ // src/xcode-project.ts
7048
7717
  var APPLICATION = "com.apple.product-type.application";
7049
7718
  var MODULE_PRODUCTS = /* @__PURE__ */ new Set([
7050
7719
  "com.apple.product-type.framework",
@@ -7071,9 +7740,9 @@ function walkFiles(dir) {
7071
7740
  return out;
7072
7741
  }
7073
7742
  var isDirectory = (dir) => import_node_fs13.default.existsSync(dir) && import_node_fs13.default.statSync(dir).isDirectory();
7074
- function readXcconfig(file, seen = /* @__PURE__ */ new Set()) {
7075
- if (seen.has(file) || !import_node_fs13.default.existsSync(file)) return {};
7076
- seen.add(file);
7743
+ function readXcconfig(file, read) {
7744
+ if (read.includes(file) || !import_node_fs13.default.existsSync(file)) return {};
7745
+ read.push(file);
7077
7746
  const settings = {};
7078
7747
  for (const raw2 of import_node_fs13.default.readFileSync(file, "utf8").split("\n")) {
7079
7748
  const line = raw2.replace(/\/\/.*$/, "").trim();
@@ -7081,7 +7750,7 @@ function readXcconfig(file, seen = /* @__PURE__ */ new Set()) {
7081
7750
  if (include) {
7082
7751
  Object.assign(
7083
7752
  settings,
7084
- readXcconfig(import_node_path14.default.resolve(import_node_path14.default.dirname(file), include[1]), seen)
7753
+ readXcconfig(import_node_path14.default.resolve(import_node_path14.default.dirname(file), include[1]), read)
7085
7754
  );
7086
7755
  continue;
7087
7756
  }
@@ -7162,7 +7831,7 @@ function workspaceReferences(workspace) {
7162
7831
  function enclosingXcodeWorkspace(xcodeproj) {
7163
7832
  const project = import_node_fs13.default.realpathSync(xcodeproj);
7164
7833
  for (let dir = import_node_path14.default.dirname(project); ; dir = import_node_path14.default.dirname(dir)) {
7165
- for (const name2 of import_node_fs13.default.readdirSync(dir)) {
7834
+ for (const name2 of import_node_fs13.default.readdirSync(dir).sort()) {
7166
7835
  if (!name2.endsWith(".xcworkspace")) continue;
7167
7836
  const workspace = import_node_path14.default.join(dir, name2);
7168
7837
  if (!import_node_fs13.default.existsSync(import_node_path14.default.join(workspace, "contents.xcworkspacedata"))) continue;
@@ -7244,17 +7913,30 @@ function loadProject(xcodeproj) {
7244
7913
  loaded.set(projectFile, { mtimeMs, project: result });
7245
7914
  return result;
7246
7915
  }
7247
- function targetSettings(ref, builtins) {
7916
+ function defaultConfiguration(project) {
7917
+ const configList = project.object(str(project.project.buildConfigurationList));
7918
+ const names = list(configList?.buildConfigurations).flatMap(
7919
+ (id) => str(project.object(id)?.name) ?? []
7920
+ );
7921
+ return names.includes("Debug") ? "Debug" : str(configList?.defaultConfigurationName) ?? names[0] ?? "Debug";
7922
+ }
7923
+ function targetSettings(ref, configuration, builtins) {
7248
7924
  const { project, target } = ref;
7925
+ const xcconfigs = [];
7249
7926
  const level = (listId) => {
7250
- const configs = list(project.object(listId)?.buildConfigurations).map(project.object);
7251
- const config = configs.find((entry) => entry?.name === "Debug") ?? configs.find(Boolean);
7927
+ const configList = project.object(listId);
7928
+ const configs = list(configList?.buildConfigurations).map(project.object);
7929
+ const config = configs.find((entry) => entry?.name === configuration) ?? configs.find((entry) => entry?.name === str(configList?.defaultConfigurationName));
7252
7930
  if (!config) return [];
7253
- const name2 = str(config.name) ?? "Debug";
7931
+ const name2 = str(config.name) ?? configuration;
7254
7932
  const base = str(config.baseConfigurationReference);
7255
7933
  const own = isDict(config.buildSettings) ? config.buildSettings : {};
7934
+ const baseFile = base ? project.resolvePath(base) : null;
7935
+ const read = [];
7936
+ const fromFile = baseFile ? readXcconfig(baseFile, read) : {};
7937
+ xcconfigs.push(...read);
7256
7938
  return [
7257
- applyConditions(base ? readXcconfig(project.resolvePath(base) ?? "") : {}, name2),
7939
+ applyConditions(fromFile, name2),
7258
7940
  applyConditions(
7259
7941
  Object.fromEntries(
7260
7942
  Object.entries(own).flatMap(
@@ -7266,7 +7948,7 @@ function targetSettings(ref, builtins) {
7266
7948
  ];
7267
7949
  };
7268
7950
  const levels = [
7269
- builtins,
7951
+ { ...builtins, CONFIGURATION: configuration },
7270
7952
  ...level(str(project.project.buildConfigurationList)),
7271
7953
  ...level(str(target.buildConfigurationList))
7272
7954
  ];
@@ -7305,9 +7987,30 @@ function targetSettings(ref, builtins) {
7305
7987
  };
7306
7988
  return {
7307
7989
  get: (key2) => valueAt(key2, levels.length - 1),
7308
- keys: new Set(levels.flatMap((values) => Object.keys(values)))
7990
+ keys: new Set(levels.flatMap((values) => Object.keys(values))),
7991
+ xcconfigs
7309
7992
  };
7310
7993
  }
7994
+ function settingList(value) {
7995
+ const items2 = [];
7996
+ for (const [, quoted, plain] of value.matchAll(
7997
+ /"((?:\\.|[^"\\])*)"|((?:\\.|[^\s"])+)/g
7998
+ ))
7999
+ items2.push((quoted ?? plain).replace(/\\(.)/g, "$1"));
8000
+ return items2;
8001
+ }
8002
+ function compilationConditions(settings) {
8003
+ const flags = settingList(settings("OTHER_SWIFT_FLAGS"));
8004
+ const defined = flags.flatMap(
8005
+ (flag, index) => flag === "-D" ? flags[index + 1] ?? [] : flag.startsWith("-D") ? flag.slice(2) : []
8006
+ );
8007
+ return [
8008
+ .../* @__PURE__ */ new Set([
8009
+ ...settingList(settings("SWIFT_ACTIVE_COMPILATION_CONDITIONS")),
8010
+ ...defined
8011
+ ])
8012
+ ];
8013
+ }
7311
8014
  function expand(value, lookup) {
7312
8015
  return value.replace(
7313
8016
  /\$(?:\(([A-Za-z_][A-Za-z0-9_]*)((?::[^)]*)?)\)|\{([A-Za-z_][A-Za-z0-9_]*)((?::[^}]*)?)\}|([A-Za-z_][A-Za-z0-9_]*))/g,
@@ -7318,8 +8021,9 @@ function expand(value, lookup) {
7318
8021
  }
7319
8022
  );
7320
8023
  }
7321
- function targetMembers(ref) {
8024
+ function targetMembers(ref, settings, options = {}) {
7322
8025
  const { project, target, id: targetId } = ref;
8026
+ const targetName = str(target.name) ?? targetId;
7323
8027
  const sources = /* @__PURE__ */ new Set();
7324
8028
  const allSources = /* @__PURE__ */ new Set();
7325
8029
  const resources = /* @__PURE__ */ new Set();
@@ -7340,6 +8044,29 @@ function targetMembers(ref) {
7340
8044
  const resolved = project.resolvePath(refId);
7341
8045
  return resolved ? [resolved] : [];
7342
8046
  };
8047
+ const scriptForOutput = /* @__PURE__ */ new Map();
8048
+ const noteScriptOutput = (raw2, script) => {
8049
+ const expanded = expand(raw2, settings);
8050
+ if (!expanded.endsWith(".swift")) return;
8051
+ const absolute = import_node_path14.default.isAbsolute(expanded) ? import_node_path14.default.normalize(expanded) : import_node_path14.default.resolve(project.projectDir, expanded);
8052
+ if (!scriptForOutput.has(absolute)) scriptForOutput.set(absolute, script);
8053
+ };
8054
+ for (const phaseId of list(target.buildPhases)) {
8055
+ const phase = project.object(phaseId);
8056
+ if (phase?.isa !== "PBXShellScriptBuildPhase") continue;
8057
+ const script = str(phase.name) ?? phaseId;
8058
+ for (const raw2 of list(phase.outputPaths)) noteScriptOutput(raw2, script);
8059
+ for (const listPath of list(phase.outputFileListPaths)) {
8060
+ const expandedList = expand(listPath, settings);
8061
+ const absoluteList = import_node_path14.default.isAbsolute(expandedList) ? expandedList : import_node_path14.default.resolve(project.projectDir, expandedList);
8062
+ if (!import_node_fs13.default.existsSync(absoluteList)) continue;
8063
+ for (const line of import_node_fs13.default.readFileSync(absoluteList, "utf8").split("\n")) {
8064
+ const trimmed = line.trim();
8065
+ if (trimmed === "" || trimmed.startsWith("#")) continue;
8066
+ noteScriptOutput(trimmed, script);
8067
+ }
8068
+ }
8069
+ }
7343
8070
  for (const phaseId of list(target.buildPhases)) {
7344
8071
  const phase = project.object(phaseId);
7345
8072
  if (phase?.isa !== "PBXSourcesBuildPhase" && phase?.isa !== "PBXResourcesBuildPhase")
@@ -7347,13 +8074,30 @@ function targetMembers(ref) {
7347
8074
  for (const buildFileId of list(phase.files)) {
7348
8075
  for (const file of fileRefPaths(str(project.object(buildFileId)?.fileRef) ?? "")) {
7349
8076
  if (phase.isa === "PBXSourcesBuildPhase") {
7350
- if (!import_node_fs13.default.existsSync(file)) continue;
8077
+ if (!import_node_fs13.default.existsSync(file)) {
8078
+ if (options.requireSources === false) continue;
8079
+ const script = scriptForOutput.get(import_node_path14.default.normalize(file));
8080
+ throw new Error(
8081
+ script ? `${targetName}: missing generated source ${file} (Run Script "${script}" declares it in outputPaths; run the script or check in its output)` : `${targetName}: missing source ${file}`
8082
+ );
8083
+ }
7351
8084
  allSources.add(file);
7352
8085
  if (file.endsWith(".swift")) sources.add(file);
7353
8086
  } else if (phase.isa === "PBXResourcesBuildPhase") addResource(file);
7354
8087
  }
7355
8088
  }
7356
8089
  }
8090
+ for (const [file, script] of scriptForOutput) {
8091
+ if (sources.has(file) || allSources.has(file)) continue;
8092
+ if (!import_node_fs13.default.existsSync(file)) {
8093
+ if (options.requireSources === false) continue;
8094
+ throw new Error(
8095
+ `${targetName}: missing generated source ${file} (Run Script "${script}" declares it in outputPaths; run the script or check in its output)`
8096
+ );
8097
+ }
8098
+ allSources.add(file);
8099
+ sources.add(file);
8100
+ }
7357
8101
  const addSynchronized = (folder, relative) => {
7358
8102
  const file = import_node_path14.default.join(folder, relative);
7359
8103
  if (NEVER_MEMBER.test(relative)) return;
@@ -7453,7 +8197,7 @@ function nativeTargets(project) {
7453
8197
  }
7454
8198
  return refs;
7455
8199
  }
7456
- function readXcodeAppTarget(input, targetName) {
8200
+ function readXcodeAppTarget(input, targetName, configurationName, options = {}) {
7457
8201
  const xcodeprojOrWorkspace = import_node_fs13.default.realpathSync(input);
7458
8202
  const workspace = xcodeprojOrWorkspace.endsWith(".xcworkspace") ? xcodeprojOrWorkspace : null;
7459
8203
  const { listed, projects: projects2, projectAt } = workspaceProjects(xcodeprojOrWorkspace);
@@ -7468,6 +8212,7 @@ function readXcodeAppTarget(input, targetName) {
7468
8212
  );
7469
8213
  }
7470
8214
  const app = named[0];
8215
+ const configuration = configurationName ?? defaultConfiguration(app.project);
7471
8216
  const byProduct = /* @__PURE__ */ new Map();
7472
8217
  for (const ref of allTargets) {
7473
8218
  const product = ref.project.object(str(ref.target.productReference));
@@ -7518,9 +8263,14 @@ function readXcodeAppTarget(input, targetName) {
7518
8263
  order.push(ref);
7519
8264
  };
7520
8265
  visit(app);
8266
+ const xcconfigs = /* @__PURE__ */ new Set();
7521
8267
  const moduleTarget = (ref) => {
7522
8268
  const name2 = str(ref.target.name) ?? ref.id;
7523
- const { get: settings2, keys } = targetSettings(ref, {
8269
+ const {
8270
+ get: settings2,
8271
+ keys,
8272
+ xcconfigs: read
8273
+ } = targetSettings(ref, configuration, {
7524
8274
  TARGET_NAME: name2,
7525
8275
  PROJECT_NAME: import_node_path14.default.basename(ref.project.xcodeproj, ".xcodeproj"),
7526
8276
  SRCROOT: ref.project.projectDir,
@@ -7528,6 +8278,7 @@ function readXcodeAppTarget(input, targetName) {
7528
8278
  PROJECT_DIR: ref.project.projectDir,
7529
8279
  DEVELOPMENT_LANGUAGE: str(ref.project.project.developmentRegion) ?? "en"
7530
8280
  });
8281
+ for (const file of read) xcconfigs.add(file);
7531
8282
  const swiftVersion = Number.parseFloat(settings2("SWIFT_VERSION") || "5");
7532
8283
  return {
7533
8284
  settings: settings2,
@@ -7535,9 +8286,10 @@ function readXcodeAppTarget(input, targetName) {
7535
8286
  module: {
7536
8287
  name: name2,
7537
8288
  moduleName: applyOperator(settings2("PRODUCT_MODULE_NAME"), "c99extidentifier"),
7538
- ...targetMembers(ref),
8289
+ ...targetMembers(ref, settings2, options),
7539
8290
  languageMode: swiftVersion >= 6 ? 6 : 5,
7540
- mainActorIsolation: settings2("SWIFT_DEFAULT_ACTOR_ISOLATION") === "MainActor"
8291
+ mainActorIsolation: settings2("SWIFT_DEFAULT_ACTOR_ISOLATION") === "MainActor",
8292
+ defines: compilationConditions(settings2)
7541
8293
  }
7542
8294
  };
7543
8295
  };
@@ -7643,7 +8395,9 @@ function readXcodeAppTarget(input, targetName) {
7643
8395
  )
7644
8396
  ].map((dir) => import_node_fs13.default.realpathSync(dir))
7645
8397
  ),
7646
- projectFiles: [...new Set(used.map((project) => project.projectFile))].sort(),
8398
+ projectFiles: [
8399
+ .../* @__PURE__ */ new Set([...used.map((project) => project.projectFile), ...xcconfigs])
8400
+ ].sort(),
7647
8401
  appIconName: settings("ASSETCATALOG_COMPILER_APPICON_NAME"),
7648
8402
  infoPlist: import_plist.default.build(info),
7649
8403
  infoPlistFile,
@@ -7654,7 +8408,9 @@ function readXcodeAppTarget(input, targetName) {
7654
8408
  ].sort(),
7655
8409
  binaryFrameworks: [...binaryFrameworks].map(([name2, file]) => ({ name: name2, path: file })).sort((left, right) => left.name.localeCompare(right.name)),
7656
8410
  packageResolved: import_node_fs13.default.existsSync(resolvedFile) ? resolvedFile : null,
7657
- appTargets: appTargetNames
8411
+ appTargets: appTargetNames,
8412
+ configuration,
8413
+ settings
7658
8414
  };
7659
8415
  }
7660
8416
 
@@ -7790,7 +8546,7 @@ function swiftPackages(entry, app) {
7790
8546
  cached2.standinKey = generation;
7791
8547
  }
7792
8548
  }
7793
- return cached2;
8549
+ return { ...cached2, binaries: reached };
7794
8550
  }
7795
8551
  var XCODE_APP_DIR = "__app__";
7796
8552
  var XCODE_FRAMEWORKS_DIR = "__frameworks__";
@@ -7805,14 +8561,37 @@ function xcodeInputKey(layout, file, relative) {
7805
8561
  function xcodeLayout(root) {
7806
8562
  const registered = xcodeProjects.get(root);
7807
8563
  if (!registered) return null;
7808
- const app = readXcodeAppTarget(registered.xcodeproj, registered.target);
7809
- const files2 = /* @__PURE__ */ new Set([...app.projectFiles, ...app.sources, ...app.resources]);
8564
+ const app = readXcodeAppTarget(
8565
+ registered.xcodeproj,
8566
+ registered.target,
8567
+ registered.configuration
8568
+ );
8569
+ const appSources = app.allSources.filter(
8570
+ (file) => file.endsWith(".swift") || file.endsWith(".metal")
8571
+ );
8572
+ const files2 = /* @__PURE__ */ new Set([...app.projectFiles, ...appSources, ...app.resources]);
7810
8573
  if (app.infoPlistFile) files2.add(app.infoPlistFile);
7811
- const targetDirs = new Map(app.sources.map((file) => [file, XCODE_APP_DIR]));
8574
+ const targetDirs = new Map(
8575
+ [...appSources, ...app.resources].map((file) => [file, XCODE_APP_DIR])
8576
+ );
8577
+ const resourceBundles = [
8578
+ { target: app.moduleName, sourcePath: XCODE_APP_DIR, path: "." }
8579
+ ];
7812
8580
  const targets = [];
7813
8581
  for (const framework of app.frameworks) {
7814
8582
  const dir = import_node_path15.default.posix.join(XCODE_FRAMEWORKS_DIR, framework.moduleName);
7815
- for (const file of framework.sources) {
8583
+ resourceBundles.push({
8584
+ target: framework.moduleName,
8585
+ sourcePath: dir,
8586
+ path: `Frameworks/${framework.moduleName}.framework`
8587
+ });
8588
+ for (const file of framework.allSources) {
8589
+ if (!file.endsWith(".swift") && !file.endsWith(".metal")) continue;
8590
+ if (targetDirs.has(file)) continue;
8591
+ targetDirs.set(file, dir);
8592
+ files2.add(file);
8593
+ }
8594
+ for (const file of framework.resources) {
7816
8595
  if (targetDirs.has(file)) continue;
7817
8596
  targetDirs.set(file, dir);
7818
8597
  files2.add(file);
@@ -7824,10 +8603,11 @@ function xcodeLayout(root) {
7824
8603
  resources: false,
7825
8604
  exclude: [],
7826
8605
  languageMode: framework.languageMode,
7827
- mainActorIsolation: framework.mainActorIsolation
8606
+ mainActorIsolation: framework.mainActorIsolation,
8607
+ defines: framework.defines
7828
8608
  });
7829
8609
  }
7830
- const { packages, standins, projectGaps } = swiftPackages(registered, app);
8610
+ const { packages, standins, projectGaps, binaries } = swiftPackages(registered, app);
7831
8611
  for (const standin of standins)
7832
8612
  targets.push({
7833
8613
  name: standin.module,
@@ -7838,6 +8618,7 @@ function xcodeLayout(root) {
7838
8618
  languageMode: 5,
7839
8619
  mainActorIsolation: false
7840
8620
  });
8621
+ const packageConfiguration = app.configuration === "Debug" ? "debug" : "release";
7841
8622
  for (const target of packages.targets) {
7842
8623
  const relative = import_node_path15.default.relative(
7843
8624
  target.remote ? import_node_path15.default.join(root, REMOTE_CHECKOUTS) : root,
@@ -7849,8 +8630,21 @@ function xcodeLayout(root) {
7849
8630
  targets.push({
7850
8631
  ...target,
7851
8632
  path: target.remote ? import_node_path15.default.posix.join(XCODE_PACKAGES_DIR, posix) : posix,
7852
- exclude: []
8633
+ exclude: [],
8634
+ defines: [
8635
+ ...packageConfiguration === "debug" ? ["DEBUG"] : [],
8636
+ ...target.packageDefines.filter(
8637
+ (define) => define.configuration === null || define.configuration === packageConfiguration
8638
+ ).map((define) => define.name)
8639
+ ]
7853
8640
  });
8641
+ if (target.resources) {
8642
+ resourceBundles.push({
8643
+ target: target.name,
8644
+ sourcePath: target.remote ? import_node_path15.default.posix.join(XCODE_PACKAGES_DIR, posix) : posix,
8645
+ path: `${swiftPackageManifest(target.packageDir).name}_${target.name}.bundle`
8646
+ });
8647
+ }
7854
8648
  if (!target.remote) files2.add(import_node_path15.default.join(target.packageDir, "Package.swift"));
7855
8649
  for (const file of target.files) files2.add(file);
7856
8650
  }
@@ -7862,20 +8656,26 @@ function xcodeLayout(root) {
7862
8656
  targets,
7863
8657
  packages,
7864
8658
  standins,
8659
+ binaries,
7865
8660
  projectGaps,
7866
8661
  targetDirs,
8662
+ resourceBundles,
7867
8663
  files: [...files2].sort()
7868
8664
  };
7869
8665
  }
7870
8666
  function xcodeManifest(layout) {
7871
- const settings = (mode, mainActor) => `swiftSettings: [.swiftLanguageMode(.v${mode})${mainActor ? ", .defaultIsolation(MainActor.self)" : ""}]`;
8667
+ const settings = (target) => `swiftSettings: [${[
8668
+ `.swiftLanguageMode(.v${target.languageMode})`,
8669
+ ...target.mainActorIsolation ? [".defaultIsolation(MainActor.self)"] : [],
8670
+ ...(target.defines ?? []).map((name2) => `.define(${JSON.stringify(name2)})`)
8671
+ ].join(", ")}]`;
7872
8672
  return [
7873
8673
  "// swift-tools-version: 6.2",
7874
8674
  "import PackageDescription",
7875
8675
  'let package = Package(name: "app", targets: [',
7876
- ` .executableTarget(name: "${layout.app.moduleName}", path: "${XCODE_APP_DIR}", ${settings(layout.app.languageMode, layout.app.mainActorIsolation)}),`,
8676
+ ` .executableTarget(name: "${layout.app.moduleName}", path: "${XCODE_APP_DIR}", ${settings(layout.app)}),`,
7877
8677
  ...layout.targets.map(
7878
- (target) => ` .target(name: "${target.name}", path: "${target.path}", ${target.exclude.length > 0 ? `exclude: ${JSON.stringify(target.exclude)}, ` : ""}${target.resources ? "resources: [], " : ""}${settings(target.languageMode, target.mainActorIsolation)}),`
8678
+ (target) => ` .target(name: "${target.name}", path: "${target.path}", ${target.exclude.length > 0 ? `exclude: ${JSON.stringify(target.exclude)}, ` : ""}${target.resources ? "resources: [], " : ""}${settings(target)}),`
7879
8679
  ),
7880
8680
  "])",
7881
8681
  ""
@@ -7916,7 +8716,7 @@ function sourceFiles(root) {
7916
8716
  }
7917
8717
  function resourceCandidateFiles(root) {
7918
8718
  return packageFiles(root).filter(
7919
- (file) => !file.endsWith(".swift") && !["project.pbxproj", "project.xcproj"].includes(import_node_path15.default.basename(file))
8719
+ (file) => !file.endsWith(".swift") && !file.endsWith(".xcconfig") && !["project.pbxproj", "project.xcproj"].includes(import_node_path15.default.basename(file))
7920
8720
  );
7921
8721
  }
7922
8722
  var HOSTED_LIMITS = {
@@ -7946,7 +8746,7 @@ var RESOURCE_CONTENT_TYPES = {
7946
8746
  ".png": "image/png",
7947
8747
  ".webp": "image/webp"
7948
8748
  };
7949
- function buildSwiftResourceTable(project, baseUrl) {
8749
+ function buildSwiftResourceTable(project, baseUrl, inputs) {
7950
8750
  const limits = inputLimits(Boolean(project.hosted));
7951
8751
  const absolute = resourceCandidateFiles(project.packagePath);
7952
8752
  const relative = absolute.map(
@@ -7961,15 +8761,77 @@ function buildSwiftResourceTable(project, baseUrl) {
7961
8761
  "utf8"
7962
8762
  );
7963
8763
  };
7964
- const found = enumerateBundleImages(relative, readContents);
7965
- const colors = enumerateBundleColors(relative, readContents);
7966
- const symbols = enumerateBundleSymbols(relative, readContents);
7967
- const table = {};
8764
+ const layout = xcodeLayout(project.packagePath);
8765
+ const bundles = layout?.resourceBundles ?? swiftResourceBundles(inputs, relative);
8766
+ const catalogFiles = relative.filter((file) => {
8767
+ const disk = byRelative.get(file);
8768
+ return !disk || !layout?.targetDirs.get(disk)?.startsWith(`${XCODE_FRAMEWORKS_DIR}/`);
8769
+ });
8770
+ const found = enumerateBundleImages(relative, readContents, (file) => {
8771
+ const disk = byRelative.get(file);
8772
+ if (!disk) throw new Error(`image source ${file} has no input file`);
8773
+ const key2 = layout ? xcodeInputKey(layout, disk, file) : file;
8774
+ return swiftResourceBundleForFile(bundles, key2)?.path ?? ".";
8775
+ });
8776
+ const colors = enumerateBundleColors(catalogFiles, readContents);
8777
+ const symbols = enumerateBundleSymbols(catalogFiles, readContents, (file) => {
8778
+ const disk = byRelative.get(file);
8779
+ if (!disk) throw new Error(`symbol source ${file} has no input file`);
8780
+ const key2 = layout ? xcodeInputKey(layout, disk, file) : file;
8781
+ return swiftResourceBundleForFile(bundles, key2)?.path ?? ".";
8782
+ });
8783
+ const table = /* @__PURE__ */ Object.create(null);
7968
8784
  const images = {};
8785
+ const metalSources = {};
8786
+ const metalUploads = {};
7969
8787
  const watched = [];
7970
8788
  const registered = /* @__PURE__ */ new Map();
8789
+ const shaderFiles = relative.filter((file) => file.endsWith(".metal"));
8790
+ const metalCandidates = {};
8791
+ if (inputs["Package.swift"] !== void 0)
8792
+ metalCandidates["Package.swift"] = inputs["Package.swift"];
8793
+ const metalInputs = /* @__PURE__ */ new Map();
8794
+ for (const file of shaderFiles) {
8795
+ const disk = byRelative.get(file);
8796
+ if (!disk) throw new Error(`metal source ${file} has no input file`);
8797
+ const key2 = layout ? xcodeInputKey(layout, disk, file) : file;
8798
+ metalCandidates[key2] = "";
8799
+ metalInputs.set(key2, { file, disk });
8800
+ }
8801
+ const metalFiles = Object.keys(swiftMetalSourceFiles(metalCandidates));
8802
+ if (metalFiles.length > MAX_SWIFT_COMPILE_METAL_FILES)
8803
+ throw new Error("metal source pack exceeds the compile service file cap");
8804
+ let metalBytes = 0;
8805
+ for (const key2 of metalFiles) {
8806
+ const input = metalInputs.get(key2);
8807
+ if (!input) throw new Error(`metal source ${key2} has no input file`);
8808
+ const { file, disk } = input;
8809
+ const bytes = readPackageFile(
8810
+ project.packagePath,
8811
+ disk,
8812
+ MAX_SWIFT_COMPILE_METAL_BYTES
8813
+ );
8814
+ metalBytes += bytes.length;
8815
+ if (metalBytes > MAX_SWIFT_COMPILE_METAL_TOTAL_BYTES)
8816
+ throw new Error("metal source pack exceeds the compile service caps");
8817
+ const source = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
8818
+ bytes
8819
+ );
8820
+ const sha256 = (0, import_node_crypto7.createHash)("sha256").update(bytes).digest("hex");
8821
+ const bundle = swiftResourceBundleForFile(bundles, key2);
8822
+ if (!bundle && inputs["Package.swift"])
8823
+ throw new Error(`metal source ${key2} has no resource target bundle`);
8824
+ metalSources[key2] = {
8825
+ sha256,
8826
+ url: `${baseUrl}${RESOURCE_PATH}${sha256}.metal`,
8827
+ bundlePath: bundle?.path ?? "."
8828
+ };
8829
+ metalUploads[key2] = source;
8830
+ watched.push(file);
8831
+ registered.set(`${sha256}.metal`, { bytes, contentType: "text/plain; charset=utf-8" });
8832
+ }
7971
8833
  let imageBytes = 0;
7972
- for (const { name: name2, file, scale } of found) {
8834
+ for (const { name: name2, file, scale, bundlePath } of found) {
7973
8835
  const disk = byRelative.get(file);
7974
8836
  if (!disk) continue;
7975
8837
  if (Object.keys(images).length >= limits.images || imageBytes + import_node_fs14.default.statSync(disk).size > limits.imageTotalBytes) {
@@ -7979,8 +8841,12 @@ function buildSwiftResourceTable(project, baseUrl) {
7979
8841
  imageBytes += bytes.length;
7980
8842
  const hash = (0, import_node_crypto7.createHash)("sha256").update(bytes).digest("hex").slice(0, 16);
7981
8843
  const ext = import_node_path15.default.posix.extname(file).toLowerCase();
7982
- table[name2] = { uri: `${baseUrl}${RESOURCE_PATH}${hash}${ext}`, scale };
7983
- images[name2] = {
8844
+ const bundle = table[bundlePath] ?? /* @__PURE__ */ Object.create(null);
8845
+ const variants = bundle[name2] ??= [];
8846
+ variants.push({ uri: `${baseUrl}${RESOURCE_PATH}${hash}${ext}`, scale });
8847
+ table[bundlePath] = bundle;
8848
+ const key2 = layout ? xcodeInputKey(layout, disk, file) : file;
8849
+ images[key2] = {
7984
8850
  file: import_node_path15.default.posix.basename(file),
7985
8851
  data: bytes.toString("base64")
7986
8852
  };
@@ -8002,9 +8868,9 @@ function buildSwiftResourceTable(project, baseUrl) {
8002
8868
  project.resourcesPrevious = project.resourceFiles;
8003
8869
  project.resourceFiles = registered;
8004
8870
  }
8005
- return { table, images, colors, symbols, watched };
8871
+ return { table, images, metalSources, metalUploads, colors, symbols, watched };
8006
8872
  }
8007
- function buildSwiftBundleFiles(packagePath, hosted) {
8873
+ function buildSwiftBundleFiles(packagePath, hosted, inputs) {
8008
8874
  packagePath = import_node_fs14.default.realpathSync(packagePath);
8009
8875
  const limits = inputLimits(hosted);
8010
8876
  const relative = resourceCandidateFiles(packagePath).map(
@@ -8014,30 +8880,51 @@ function buildSwiftBundleFiles(packagePath, hosted) {
8014
8880
  const watched = [];
8015
8881
  let total = 0;
8016
8882
  const xcode = xcodeLayout(packagePath);
8883
+ const bundles = xcode?.resourceBundles ?? swiftResourceBundles(inputs ?? packageSources(packagePath), relative);
8884
+ const addFile = (key2, bytes) => {
8885
+ if (Object.keys(files2).length >= limits.resources || bytes.length > limits.resourceBytes || total + bytes.length > limits.resourceTotalBytes)
8886
+ throw new Error(
8887
+ `swift bundle pack exceeds ${limits.resources} files / ${limits.resourceTotalBytes} bytes`
8888
+ );
8889
+ files2[key2] = bytes.toString("base64");
8890
+ total += bytes.length;
8891
+ };
8017
8892
  if (xcode) {
8018
8893
  const bytes = Buffer.from(xcode.app.infoPlist);
8019
8894
  if (bytes.length > limits.resourceBytes || bytes.length > limits.resourceTotalBytes)
8020
8895
  throw new Error("swift launch Info.plist exceeds bundle resource limits");
8021
- files2["Info.plist"] = bytes.toString("base64");
8022
- total += bytes.length;
8896
+ addFile("Info.plist", bytes);
8023
8897
  if (xcode.app.infoPlistFile)
8024
8898
  watched.push(
8025
8899
  import_node_path15.default.relative(packagePath, xcode.app.infoPlistFile).split(import_node_path15.default.sep).join("/")
8026
8900
  );
8027
8901
  }
8028
- for (const { base, file } of enumerateBundleJson(relative)) {
8029
- watched.push(file);
8902
+ const groups = /* @__PURE__ */ new Map();
8903
+ for (const file of relative) {
8030
8904
  const disk = import_node_path15.default.join(packagePath, ...file.split("/"));
8031
- if (Object.keys(files2).length >= limits.resources || total + import_node_fs14.default.statSync(disk).size > limits.resourceTotalBytes) {
8032
- throw new Error(
8033
- `swift bundle pack exceeds ${limits.resources} files / ${limits.resourceTotalBytes} bytes`
8034
- );
8905
+ const key2 = xcode ? xcodeInputKey(xcode, disk, file) : file;
8906
+ const bundle = swiftResourceBundleForFile(bundles, key2);
8907
+ const bundlePath = bundle?.path ?? ".";
8908
+ const group = groups.get(bundlePath) ?? [];
8909
+ group.push(file);
8910
+ groups.set(bundlePath, group);
8911
+ }
8912
+ for (const bundle of bundles) {
8913
+ if (bundle.path === ".") continue;
8914
+ addFile(
8915
+ `${bundle.path}/Info.plist`,
8916
+ Buffer.from(swiftResourceBundleInfoPlist(bundle))
8917
+ );
8918
+ }
8919
+ for (const [bundlePath, paths] of groups) {
8920
+ for (const { base, file } of enumerateBundleResources(paths)) {
8921
+ watched.push(file);
8922
+ const disk = import_node_path15.default.join(packagePath, ...file.split("/"));
8923
+ const bytes = readPackageFile(packagePath, disk, limits.resourceBytes);
8924
+ addFile(bundlePath === "." ? base : `${bundlePath}/${base}`, bytes);
8035
8925
  }
8036
- const bytes = readPackageFile(packagePath, disk, limits.resourceBytes);
8037
- files2[base] = bytes.toString("base64");
8038
- total += bytes.length;
8039
8926
  }
8040
- return { files: files2, watched };
8927
+ return { files: files2, bundles, watched };
8041
8928
  }
8042
8929
  function linkedModuleRoots(packagePath) {
8043
8930
  packagePath = import_node_fs14.default.realpathSync(packagePath);
@@ -8083,7 +8970,20 @@ function sourceStamp(packagePath, moduleRootOverride, hosted = false) {
8083
8970
  function icuUrl(origin, artifact) {
8084
8971
  return "url" in artifact.icu ? artifact.icu.url : `${origin}${ICU_PATH}${artifact.icu.sha256}`;
8085
8972
  }
8086
- function packageSources(packagePath) {
8973
+ function standinLibraries(layout) {
8974
+ const linked = /* @__PURE__ */ new Map();
8975
+ for (const binary of layout.binaries) {
8976
+ const modules = layout.standins.filter(
8977
+ (standin) => standin.target === binary.target && `${standin.module}.c` in standin.files
8978
+ );
8979
+ if (modules.length === 0) continue;
8980
+ const library = standinLibrary(binary, layout.app.rootDir);
8981
+ if (!library) continue;
8982
+ linked.set(library, modules);
8983
+ }
8984
+ return linked;
8985
+ }
8986
+ function packageSources(packagePath, linked = /* @__PURE__ */ new Set()) {
8087
8987
  const xcode = xcodeLayout(packagePath);
8088
8988
  const files2 = {};
8089
8989
  for (const file of sourceFiles(packagePath)) {
@@ -8099,25 +8999,40 @@ function packageSources(packagePath) {
8099
8999
  files2["Package.swift"] = xcodeManifest(xcode);
8100
9000
  for (const standin of xcode.standins)
8101
9001
  for (const [file, text3] of Object.entries(standin.files))
8102
- files2[import_node_path15.default.posix.join(XCODE_STANDINS_DIR, standin.module, file)] = text3;
9002
+ files2[import_node_path15.default.posix.join(XCODE_STANDINS_DIR, standin.module, file)] = linked.has(standin) && file === `${standin.module}.c` ? `// ${standin.target}'s WebAssembly library defines ${standin.module}'s functions.
9003
+ ` : text3;
8103
9004
  }
8104
9005
  return files2;
8105
9006
  }
8106
9007
  function packageSnapshot(project, entry) {
8107
- const files2 = packageSources(project.packagePath);
8108
9008
  const layout = xcodeLayout(project.packagePath);
9009
+ const linked = layout ? standinLibraries(layout) : /* @__PURE__ */ new Map();
9010
+ const files2 = packageSources(project.packagePath, new Set([...linked.values()].flat()));
8109
9011
  const native = nativeSourceDescriptor(project.packagePath);
8110
9012
  return {
8111
9013
  files: files2,
8112
9014
  entry: layout ? xcodeInputKey(layout, import_node_path15.default.resolve(project.packagePath, entry), entry) : entry,
8113
9015
  resourcePaths: swiftImplicitResourcePaths(
8114
- resourceCandidateFiles(project.packagePath).map(
8115
- (file) => import_node_path15.default.relative(project.packagePath, file).split(import_node_path15.default.sep).join(import_node_path15.default.posix.sep)
8116
- )
9016
+ resourceCandidateFiles(project.packagePath).map((file) => {
9017
+ const relative = import_node_path15.default.relative(project.packagePath, file).split(import_node_path15.default.sep).join(import_node_path15.default.posix.sep);
9018
+ return layout && file.endsWith(".metal") ? xcodeInputKey(layout, file, relative) : relative;
9019
+ })
9020
+ ),
9021
+ resources: buildSwiftResourceTable(project, "", files2),
9022
+ bundleFiles: buildSwiftBundleFiles(
9023
+ project.packagePath,
9024
+ Boolean(project.hosted),
9025
+ files2
8117
9026
  ),
8118
- resources: buildSwiftResourceTable(project, ""),
8119
- bundleFiles: buildSwiftBundleFiles(project.packagePath, Boolean(project.hosted)),
8120
9027
  native,
9028
+ ...linked.size > 0 ? {
9029
+ libraries: Object.fromEntries(
9030
+ [...linked].map(([library, [first]]) => [
9031
+ first.module,
9032
+ import_node_fs14.default.readFileSync(library).toString("base64")
9033
+ ])
9034
+ )
9035
+ } : {},
8121
9036
  ...native ? {
8122
9037
  glue: readPackageFile(
8123
9038
  project.packagePath,
@@ -8130,11 +9045,14 @@ function packageSnapshot(project, entry) {
8130
9045
  function snapshotCompileInput(snapshot) {
8131
9046
  const input = {
8132
9047
  files: snapshot.files,
9048
+ metalSources: snapshot.resources.metalUploads,
8133
9049
  resourcePaths: snapshot.resourcePaths,
9050
+ resourceBundles: snapshot.bundleFiles.bundles,
8134
9051
  resources: snapshot.bundleFiles.files,
8135
9052
  images: snapshot.resources.images,
8136
9053
  entry: snapshot.entry,
8137
- oneModule: true
9054
+ oneModule: true,
9055
+ ...snapshot.libraries ? { libraries: snapshot.libraries } : {}
8138
9056
  };
8139
9057
  return snapshot.glue ? withNativeSourceGlue(input, snapshot.glue) : input;
8140
9058
  }
@@ -8143,6 +9061,7 @@ async function compile(packagePath, stamp, moduleRootOverride, hosted, snapshot)
8143
9061
  table: snapshot.resources.table,
8144
9062
  colors: snapshot.resources.colors,
8145
9063
  symbols: snapshot.resources.symbols,
9064
+ metalSources: snapshot.resources.metalSources,
8146
9065
  watched: snapshot.resources.watched
8147
9066
  };
8148
9067
  const content = {
@@ -8250,10 +9169,6 @@ function swiftApiGapReport(output) {
8250
9169
  ...other.size > 0 ? ["other errors, often caused by the ones above:", ...rows(other)] : []
8251
9170
  ].join("\n");
8252
9171
  }
8253
- var UNPROVIDED_PLATFORM_MODULES = {
8254
- Darwin: "Peach compiles for WebAssembly, which has no Darwin; C library names come through Foundation",
8255
- MachO: "Peach compiles for WebAssembly, which has no Mach-O images"
8256
- };
8257
9172
  var IOS_SDK_FRAMEWORKS = new Set(ios_sdk_frameworks_default.frameworks);
8258
9173
  async function missingModulesMessage(packagePath, missing) {
8259
9174
  const layout = xcodeLayout(packagePath);
@@ -8269,12 +9184,7 @@ async function missingModulesMessage(packagePath, missing) {
8269
9184
  ];
8270
9185
  }),
8271
9186
  ...[...missing.keys()].flatMap(
8272
- (name2) => UNPROVIDED_PLATFORM_MODULES[name2] ? [
8273
- [
8274
- name2,
8275
- { source: "the iOS SDK", reason: UNPROVIDED_PLATFORM_MODULES[name2] }
8276
- ]
8277
- ] : IOS_SDK_FRAMEWORKS.has(name2) ? [
9187
+ (name2) => IOS_SDK_FRAMEWORKS.has(name2) ? [
8278
9188
  [
8279
9189
  name2,
8280
9190
  { source: "the iOS SDK", reason: "a framework Peach does not provide" }
@@ -8285,9 +9195,7 @@ async function missingModulesMessage(packagePath, missing) {
8285
9195
  ...layout?.packages.unavailable ?? []
8286
9196
  ]);
8287
9197
  const packaged = new Set(
8288
- [...missing.keys()].filter(
8289
- (name2) => !UNPROVIDED_PLATFORM_MODULES[name2] && !IOS_SDK_FRAMEWORKS.has(name2)
8290
- )
9198
+ [...missing.keys()].filter((name2) => !IOS_SDK_FRAMEWORKS.has(name2))
8291
9199
  );
8292
9200
  if (packaged.size > 0)
8293
9201
  await Promise.all(
@@ -8346,7 +9254,9 @@ async function compileRemote(packagePath, snapshot, hosted) {
8346
9254
  submit,
8347
9255
  {
8348
9256
  files: snapshot.files,
9257
+ metalSources: snapshot.resources.metalUploads,
8349
9258
  resourcePaths: snapshot.resourcePaths,
9259
+ resourceBundles: snapshot.bundleFiles.bundles,
8350
9260
  resources: snapshot.bundleFiles.files,
8351
9261
  images: snapshot.resources.images,
8352
9262
  entry: snapshot.entry,
@@ -8591,7 +9501,7 @@ function expoEntry(units) {
8591
9501
  import ExpoModulesCore
8592
9502
  ${[...new Set(units.map((unit) => unit.namespace))].map((namespace) => `import ${namespace}`).join("\n")}
8593
9503
 
8594
- @main struct PeachExpoApp: RNXPackage {
9504
+ @main struct PeachExpoApp: PeachPackage {
8595
9505
  init() { MainActor.assumeIsolated { PeachExpoRuntime.register([${units.flatMap((unit) => unit.classes).join(", ")}]) } }
8596
9506
  func view(props: JSON) -> PeachExpoNativeView { PeachExpoNativeView(props: props) }
8597
9507
  }
@@ -8615,72 +9525,45 @@ async function compileExpoSwiftModules(root, base, publishArtifact) {
8615
9525
  modules: [],
8616
9526
  failures: []
8617
9527
  };
8618
- const key2 = (0, import_node_crypto8.createHash)("sha256").update(import_node_fs15.default.realpathSync(root)).digest("hex");
8619
- const linked = [];
8620
- for (const unit of units) {
8621
- if (!module2) {
9528
+ if (!module2) {
9529
+ for (const unit of units)
8622
9530
  result.failures.push({
8623
9531
  namespace: unit.moduleId,
8624
9532
  diagnostic: "No local Swift toolchain or distribution is available"
8625
9533
  });
8626
- continue;
8627
- }
9534
+ return result;
9535
+ }
9536
+ const key2 = (0, import_node_crypto8.createHash)("sha256").update(import_node_fs15.default.realpathSync(root)).digest("hex");
9537
+ const failures = /* @__PURE__ */ new Map();
9538
+ const candidates = [];
9539
+ const stamps = /* @__PURE__ */ new Map();
9540
+ for (const unit of units) {
8628
9541
  const packagePath = import_node_path16.default.join(import_node_os9.default.tmpdir(), "peach-expo-swift", key2, unit.moduleId);
8629
- let stamp;
8630
- try {
8631
- syncSwiftTree(
8632
- packagePath,
8633
- new Map(
8634
- Object.entries(unit.files).map(([name2, source]) => [
8635
- import_node_path16.default.join(packagePath, name2),
8636
- source
8637
- ])
8638
- )
8639
- );
8640
- stamp = sourceStamp(packagePath, module2.root);
8641
- const failed = failedCompilations.get(packagePath);
8642
- if (failed?.stamp === stamp) {
8643
- result.failures.push({
8644
- namespace: unit.moduleId,
8645
- diagnostic: failed.diagnostic
8646
- });
8647
- continue;
8648
- }
8649
- failedCompilations.delete(packagePath);
8650
- await artifactFor(projectFor(packagePath), EXPO_SWIFT_ENTRY, module2.root);
8651
- linked.push(unit);
8652
- } catch (error) {
8653
- const diagnostic = error instanceof Error ? error.message : String(error);
8654
- const appPaths = Object.values(unit.files).flatMap((source) => {
8655
- const match = /^#sourceLocation\(file: (".*"), line: 1\)$/m.exec(source);
8656
- if (!match) return [];
8657
- const file = JSON.parse(match[1]);
8658
- return typeof file === "string" ? [file] : [];
8659
- });
8660
- const errors = diagnostic.match(/^.+:\d+(?::\d+)?: error:.*$/gm) ?? [];
8661
- const sourceErrors = errors.filter(
8662
- (line) => appPaths.some((file) => line.startsWith(`${file}:`)) && !/external macro implementation type|failed to load library plugin/.test(line)
8663
- );
8664
- if (publishArtifact && (sourceErrors.length === 0 || sourceErrors.length !== errors.length) && !(error instanceof SwiftMissingModulesError))
8665
- throw error;
8666
- if (sourceErrors.length && sourceErrors.length === errors.length && module2 && stamp && sourceStamp(packagePath, module2.root) === stamp) {
8667
- failedCompilations.set(packagePath, {
8668
- stamp,
8669
- diagnostic: sourceErrors.join("\n")
8670
- });
8671
- }
8672
- result.failures.push({
8673
- namespace: unit.moduleId,
8674
- diagnostic: sourceErrors.length ? sourceErrors.join("\n") : diagnostic
8675
- });
9542
+ syncSwiftTree(
9543
+ packagePath,
9544
+ new Map(
9545
+ Object.entries(unit.files).map(([name2, source]) => [
9546
+ import_node_path16.default.join(packagePath, name2),
9547
+ source
9548
+ ])
9549
+ )
9550
+ );
9551
+ const stamp = sourceStamp(packagePath, module2.root);
9552
+ const failed = failedCompilations.get(packagePath);
9553
+ if (failed?.stamp === stamp) {
9554
+ failures.set(unit.moduleId, failed.diagnostic);
9555
+ continue;
8676
9556
  }
9557
+ failedCompilations.delete(packagePath);
9558
+ stamps.set(unit, stamp);
9559
+ candidates.push(unit);
8677
9560
  }
8678
- if (module2 && linked.length) {
9561
+ const link = async (linked2) => {
8679
9562
  const files2 = Object.assign(
8680
9563
  {},
8681
- ...linked.map((unit) => unit.files)
9564
+ ...linked2.map((unit) => unit.files)
8682
9565
  );
8683
- files2[EXPO_SWIFT_ENTRY] = expoEntry(linked);
9566
+ files2[EXPO_SWIFT_ENTRY] = expoEntry(linked2);
8684
9567
  const targets = [
8685
9568
  ...new Set(
8686
9569
  Object.keys(files2).flatMap((name2) => {
@@ -8703,11 +9586,58 @@ let package = Package(name: "PeachExpo", targets: [${targets.map((name2) => `.ta
8703
9586
  ])
8704
9587
  )
8705
9588
  );
8706
- const artifact = await artifactFor(
8707
- projectFor(packagePath),
8708
- EXPO_SWIFT_ENTRY,
8709
- module2.root
8710
- );
9589
+ return artifactFor(projectFor(packagePath), EXPO_SWIFT_ENTRY, module2.root);
9590
+ };
9591
+ let linked = candidates;
9592
+ let artifact;
9593
+ if (linked.length) {
9594
+ try {
9595
+ artifact = await link(linked);
9596
+ } catch (linkError) {
9597
+ linked = [];
9598
+ for (const unit of candidates) {
9599
+ const packagePath = import_node_path16.default.join(import_node_os9.default.tmpdir(), "peach-expo-swift", key2, unit.moduleId);
9600
+ try {
9601
+ await artifactFor(projectFor(packagePath), EXPO_SWIFT_ENTRY, module2.root);
9602
+ linked.push(unit);
9603
+ } catch (error) {
9604
+ const diagnostic = error instanceof Error ? error.message : String(error);
9605
+ const appPaths = Object.values(unit.files).flatMap((source) => {
9606
+ const match = /^#sourceLocation\(file: (".*"), line: 1\)$/m.exec(source);
9607
+ if (!match) return [];
9608
+ const file = JSON.parse(match[1]);
9609
+ return typeof file === "string" ? [file] : [];
9610
+ });
9611
+ const errors = diagnostic.match(/^.+:\d+(?::\d+)?: error:.*$/gm) ?? [];
9612
+ const sourceErrors = errors.filter(
9613
+ (line) => appPaths.some((file) => line.startsWith(`${file}:`)) && !/external macro implementation type|failed to load library plugin/.test(
9614
+ line
9615
+ )
9616
+ );
9617
+ if (publishArtifact && (sourceErrors.length === 0 || sourceErrors.length !== errors.length) && !(error instanceof SwiftMissingModulesError))
9618
+ throw error;
9619
+ if (sourceErrors.length && sourceErrors.length === errors.length && sourceStamp(packagePath, module2.root) === stamps.get(unit)) {
9620
+ failedCompilations.set(packagePath, {
9621
+ stamp: stamps.get(unit),
9622
+ diagnostic: sourceErrors.join("\n")
9623
+ });
9624
+ }
9625
+ failures.set(
9626
+ unit.moduleId,
9627
+ sourceErrors.length ? sourceErrors.join("\n") : diagnostic
9628
+ );
9629
+ }
9630
+ }
9631
+ if (linked.length === candidates.length) throw linkError;
9632
+ if (linked.length) artifact = await link(linked);
9633
+ }
9634
+ }
9635
+ for (const unit of units) {
9636
+ const diagnostic = failures.get(unit.moduleId);
9637
+ if (diagnostic !== void 0)
9638
+ result.failures.push({ namespace: unit.moduleId, diagnostic });
9639
+ }
9640
+ if (artifact) {
8711
9641
  await publishArtifact?.(artifact);
8712
9642
  result.modules.push({
8713
9643
  namespaces: linked.map((unit) => unit.moduleId),