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.
- package/README.md +28 -22
- package/cli/app-catalog.ts +29 -14
- package/cli/app-fonts.ts +5 -3
- package/cli/bridge-flow-runner.ts +40 -29
- package/cli/cloud-client.ts +57 -21
- package/cli/cloud-test-tunnel.ts +12 -18
- package/cli/commands/agent.ts +1 -1
- package/cli/commands/app-fonts.ts +3 -3
- package/cli/commands/assert.ts +8 -8
- package/cli/commands/auth.ts +8 -3
- package/cli/commands/box/bundle-plane.ts +13 -1
- package/cli/commands/box.ts +16 -5
- package/cli/commands/compat.ts +1 -1
- package/cli/commands/config.ts +2 -2
- package/cli/commands/control.ts +125 -71
- package/cli/commands/cpu-profile.ts +45 -1
- package/cli/commands/daemon.ts +131 -33
- package/cli/commands/debug.ts +24 -17
- package/cli/commands/desktop.ts +7 -1
- package/cli/commands/detect.ts +101 -0
- package/cli/commands/detox.ts +6 -6
- package/cli/commands/device.ts +12 -12
- package/cli/commands/electron.ts +32 -14
- package/cli/commands/flow.ts +49 -41
- package/cli/commands/guest-host.ts +39 -1
- package/cli/commands/inspect/core.ts +14 -8
- package/cli/commands/inspect/list.ts +1 -1
- package/cli/commands/inspect/settle.ts +5 -3
- package/cli/commands/inspect/settling.ts +229 -44
- package/cli/commands/inspect/wait-idle.ts +3 -2
- package/cli/commands/inspect.ts +105 -93
- package/cli/commands/install-cli.ts +36 -15
- package/cli/commands/install-desktop.ts +68 -195
- package/cli/commands/kotlin.ts +6 -5
- package/cli/commands/login.ts +5 -5
- package/cli/commands/maestro-compare.ts +554 -0
- package/cli/commands/maestro-generate.ts +6 -3
- package/cli/commands/maestro.ts +22 -0
- package/cli/commands/mode.ts +2 -2
- package/cli/commands/no-bridge-hint.ts +6 -2
- package/cli/commands/platform.ts +35 -6
- package/cli/commands/preview.ts +6 -0
- package/cli/commands/project-report.ts +10 -12
- package/cli/commands/record.ts +37 -37
- package/cli/commands/runtime.ts +9 -9
- package/cli/commands/screenshot-layers.ts +4 -4
- package/cli/commands/screenshot-mode.ts +2 -2
- package/cli/commands/screenshot.ts +8 -8
- package/cli/commands/screenshots-capture.ts +2 -2
- package/cli/commands/serve.ts +9 -12
- package/cli/commands/setup.ts +29 -14
- package/cli/commands/shell-boolean-mode.ts +2 -2
- package/cli/commands/show-touches-mode.ts +2 -2
- package/cli/commands/skills.ts +11 -11
- package/cli/commands/swift.ts +29 -11
- package/cli/commands/telemetry.ts +2 -2
- package/cli/commands/test.ts +5 -0
- package/cli/commands/three-mode.ts +3 -3
- package/cli/commands/timeline.ts +4 -4
- package/cli/commands/upgrade.ts +2 -2
- package/cli/commands/upload.ts +15 -15
- package/cli/commands/what-happened.ts +2 -2
- package/cli/current-sim.ts +6 -3
- package/cli/desktop-companion.ts +55 -149
- package/cli/dev-build-freshness.ts +2 -2
- package/cli/drivers/desktop.ts +17 -9
- package/cli/drivers/electron.ts +1 -2
- package/cli/drivers/playwright-sim-host.ts +11 -2
- package/cli/drivers/playwright.ts +35 -2
- package/cli/drivers/types.ts +8 -0
- package/cli/maestro-compare.ts +670 -0
- package/cli/outbound-endpoints.ts +46 -8
- package/cli/recording-access.ts +6 -6
- package/cli/run-registry.ts +1 -1
- package/cli/runtime-compat.ts +5 -1
- package/cli/send-to-box.ts +3 -3
- package/cli/shell-init.ts +2 -1
- package/cli/ws-bridge.ts +9 -5
- package/detox/element-types.ts +1 -0
- package/detox/gestures.ts +3 -3
- package/detox/index.ts +67 -38
- package/detox/navigation-lifecycle.ts +9 -6
- package/detox/proof-frame.cjs +6 -4
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract-input.cjs +42 -17
- package/dist-lib/bridge-contract-input.mjs +41 -16
- package/dist-lib/bridge-contract.cjs +1 -4
- package/dist-lib/bridge-contract.mjs +1 -3
- package/dist-lib/bundle-channel.cjs +2918 -550
- package/dist-lib/capture-contract.cjs +65 -24
- package/dist-lib/capture-contract.mjs +63 -24
- package/dist-lib/cloud-contract.cjs +2 -2
- package/dist-lib/cloud-contract.mjs +2 -2
- package/dist-lib/cloud-test-args.cjs +1 -1
- package/dist-lib/cloud-test-args.mjs +1 -1
- package/dist-lib/cloud.cjs +3 -3
- package/dist-lib/cloud.mjs +3 -3
- package/dist-lib/config.cjs +15 -5
- package/dist-lib/config.mjs +154 -0
- package/dist-lib/detox/index.cjs +495 -139
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/expo-swift-bundle.cjs +1168 -238
- package/dist-lib/expo-swift-metadata.cjs +34 -23
- package/dist-lib/expo-swift-metadata.mjs +32 -23
- package/dist-lib/home-paths.cjs +2 -2
- package/dist-lib/host/bridge-host.cjs +2938 -654
- package/dist-lib/host/fetch-proxy-handler.cjs +14 -1
- package/dist-lib/host/fetch-proxy-overrides.cjs +7 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +5 -1
- package/dist-lib/host/replacement-module-handler.cjs +2 -2
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +999 -353
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/jump-to-source-native.cjs +1 -1
- package/dist-lib/kotlin-host.cjs +332 -19
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-fingerprint-registry.cjs +1 -1
- package/dist-lib/metro-fingerprint-registry.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +7 -7
- package/dist-lib/metro-production-bundle.mjs +5 -5
- package/dist-lib/metro.cjs +688 -250
- package/dist-lib/native-app-identity-project.cjs +2647 -0
- package/dist-lib/native-app-identity-project.mjs +1257 -0
- package/dist-lib/native-app-identity.cjs +325 -25
- package/dist-lib/native-app-identity.mjs +323 -25
- package/dist-lib/native-firebase-metadata.cjs +1 -1
- package/dist-lib/native-firebase-metadata.mjs +1 -1
- package/dist-lib/plist.cjs +1 -1
- package/dist-lib/plist.mjs +1 -1
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +5 -1
- package/dist-lib/react-native-host-modules.mjs +5 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +57 -32
- package/dist-lib/sdk.cjs +231 -51
- package/dist-lib/sdk.mjs +231 -51
- package/dist-lib/skills.cjs +4107 -1374
- package/dist-lib/swift-compile.cjs +290 -30
- package/dist-lib/swift-compile.mjs +290 -30
- package/dist-lib/swift-package.cjs +143 -12
- package/dist-lib/swift-package.mjs +137 -11
- package/dist-lib/swift-submit.cjs +47 -5
- package/dist-lib/swift-submit.mjs +42 -5
- package/dist-lib/swift-toolchain.cjs +7 -2
- package/dist-lib/swift.cjs +1 -1
- package/dist-lib/vite-swift.cjs +1392 -458
- package/dist-lib/vite.cjs +13 -17
- package/dist-lib/worklet-executable.cjs +248 -33
- package/dist-lib/worklet-executable.mjs +248 -33
- package/install.sh +10 -1
- package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Resources.kt +9 -9
- package/kotlin/AndroidViewSources/android/graphics/Canvas.kt +20 -0
- package/kotlin/AndroidViewSources/android/view/View.kt +211 -0
- package/kotlin/AndroidViewSources/android/widget/FrameLayout.kt +61 -0
- package/kotlin/AndroidViewSources/android/widget/LinearLayout.kt +49 -0
- package/kotlin/AppSources/android/view/Window.kt +36 -0
- package/kotlin/AppSources/android/view/WindowInsets.kt +9 -0
- package/kotlin/AppSources/android/view/WindowInsetsController.kt +5 -0
- package/kotlin/AppSources/android/window/OnBackInvokedDispatcher.kt +48 -0
- package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcher.kt +20 -5
- package/kotlin/AppSources/androidx/compose/foundation/layout/WindowInsets.kt +15 -0
- package/kotlin/AppSources/androidx/compose/ui/platform/ComposeView.kt +2 -1
- package/kotlin/AppSources/dev/peach/app/PeachApp.kt +42 -50
- package/kotlin/ComposeSources/PeachComposeHost.kt +200 -84
- package/kotlin/ExpoComposeSources/PeachAndroidView.kt +87 -0
- package/kotlin/ExpoComposeSources/PeachExpoViewMount.kt +24 -0
- package/kotlin/ExpoComposeSources/dev/peach/expo/PeachExpoCompose.kt +28 -0
- package/kotlin/ExpoComposeSources/expo/modules/kotlin/views/ExpoComposeView.kt +70 -0
- package/kotlin/ExpoSources/dev/peach/expo/PeachExpoRuntime.kt +513 -0
- package/kotlin/ExpoSources/dev/peach/expo/PeachExpoTypes.kt +173 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/AppContext.kt +20 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/Promise.kt +19 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +198 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/exception/CodedException.kt +126 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/functions/Functions.kt +132 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/jni/JavaScriptTypedArray.kt +81 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/modules/Module.kt +98 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +236 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/records/Record.kt +12 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/runtime/Runtime.kt +9 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObject.kt +50 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +57 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/sharedobjects/SharedRef.kt +19 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/ConcreteTypedArrays.kt +158 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/GenericTypedArray.kt +8 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArray.kt +29 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/typedarray/TypedArrayIterator.kt +9 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/types/AnyType.kt +155 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/types/Either.kt +91 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/types/Enumerable.kt +6 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/viewevent/ViewEvent.kt +54 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ExpoView.kt +23 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +71 -0
- package/kotlin/ExpoSources/expo/modules/kotlin/views/ViewProps.kt +35 -0
- package/kotlin/README.md +13 -3
- package/kotlin/Sources/android/os/Build.kt +17 -0
- package/kotlin/Sources/android/os/Handler.kt +35 -0
- package/kotlin/Sources/android/os/Looper.kt +17 -0
- package/kotlin/Sources/android/os/MessageQueue.kt +56 -0
- package/kotlin/Sources/android/os/SystemClock.kt +14 -0
- package/kotlin/Sources/android/util/Log.kt +64 -0
- package/kotlin/Sources/java/security/MessageDigest.kt +114 -0
- package/kotlin/Sources/kotlin/text/StringFormat.kt +9 -0
- package/kotlin/Sources/org/json/JSON.kt +44 -0
- package/kotlin/fixtures/counter/Counter.d.kt.ts +1 -0
- package/kotlin/fixtures/counter/Counter.kt +10 -3
- package/kotlin/fixtures/counter/CounterApp.native.tsx +1 -1
- package/kotlin/fixtures/counter/vite.config.ts +2 -2
- package/kotlin/fixtures/headless-counter/Headless.kt +7 -6
- package/kotlin/fixtures/import-animation/Animation.d.kt.ts +7 -0
- package/kotlin/fixtures/import-animation/Animation.kt +80 -0
- package/kotlin/fixtures/import-animation/ImportAnimation.native.tsx +13 -0
- package/kotlin/fixtures/import-animation/README.md +24 -0
- package/kotlin/fixtures/import-animation/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-animation/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-animation/app/routes.d.ts +18 -0
- package/kotlin/fixtures/import-animation/package.json +23 -0
- package/kotlin/fixtures/import-animation/tsconfig.json +20 -0
- package/kotlin/fixtures/import-animation/vite.config.ts +20 -0
- package/kotlin/fixtures/import-editor/Editor.d.kt.ts +7 -0
- package/kotlin/fixtures/import-editor/Editor.kt +59 -0
- package/kotlin/fixtures/import-editor/ImportEditor.native.tsx +23 -0
- package/kotlin/fixtures/import-editor/README.md +27 -0
- package/kotlin/fixtures/import-editor/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-editor/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-editor/package.json +23 -0
- package/kotlin/fixtures/import-editor/tsconfig.json +20 -0
- package/kotlin/fixtures/import-editor/vite.config.ts +20 -0
- package/kotlin/fixtures/import-effects/Effects.d.kt.ts +7 -0
- package/kotlin/fixtures/import-effects/Effects.kt +87 -0
- package/kotlin/fixtures/import-effects/ImportEffects.native.tsx +13 -0
- package/kotlin/fixtures/import-effects/README.md +19 -0
- package/kotlin/fixtures/import-effects/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-effects/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-effects/package.json +23 -0
- package/kotlin/fixtures/import-effects/tsconfig.json +20 -0
- package/kotlin/fixtures/import-effects/vite.config.ts +20 -0
- package/kotlin/fixtures/import-layout/ImportLayout.native.tsx +13 -0
- package/kotlin/fixtures/import-layout/Layout.d.kt.ts +7 -0
- package/kotlin/fixtures/import-layout/Layout.kt +72 -0
- package/kotlin/fixtures/import-layout/README.md +24 -0
- package/kotlin/fixtures/import-layout/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-layout/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-layout/package.json +23 -0
- package/kotlin/fixtures/import-layout/tsconfig.json +20 -0
- package/kotlin/fixtures/import-layout/vite.config.ts +20 -0
- package/kotlin/fixtures/import-navigation/ImportNavigation.native.tsx +18 -0
- package/kotlin/fixtures/import-navigation/Navigation.d.kt.ts +7 -0
- package/kotlin/fixtures/import-navigation/Navigation.kt +104 -0
- package/kotlin/fixtures/import-navigation/README.md +31 -0
- package/kotlin/fixtures/import-navigation/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-navigation/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-navigation/package.json +23 -0
- package/kotlin/fixtures/import-navigation/tsconfig.json +20 -0
- package/kotlin/fixtures/import-navigation/vite.config.ts +20 -0
- package/kotlin/fixtures/import-overlays/ImportOverlays.native.tsx +29 -0
- package/kotlin/fixtures/import-overlays/Overlays.d.kt.ts +7 -0
- package/kotlin/fixtures/import-overlays/Overlays.kt +93 -0
- package/kotlin/fixtures/import-overlays/README.md +34 -0
- package/kotlin/fixtures/import-overlays/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-overlays/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-overlays/package.json +23 -0
- package/kotlin/fixtures/import-overlays/tsconfig.json +20 -0
- package/kotlin/fixtures/import-overlays/vite.config.ts +20 -0
- package/kotlin/fixtures/import-scroll/ImportScroll.native.tsx +13 -0
- package/kotlin/fixtures/import-scroll/README.md +23 -0
- package/kotlin/fixtures/import-scroll/Scroll.d.kt.ts +7 -0
- package/kotlin/fixtures/import-scroll/Scroll.kt +91 -0
- package/kotlin/fixtures/import-scroll/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-scroll/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-scroll/package.json +23 -0
- package/kotlin/fixtures/import-scroll/tsconfig.json +20 -0
- package/kotlin/fixtures/import-scroll/vite.config.ts +20 -0
- package/kotlin/fixtures/import-selection/ImportSelection.native.tsx +44 -0
- package/kotlin/fixtures/import-selection/README.md +32 -0
- package/kotlin/fixtures/import-selection/Selection.d.kt.ts +8 -0
- package/kotlin/fixtures/import-selection/Selection.kt +78 -0
- package/kotlin/fixtures/import-selection/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-selection/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-selection/package.json +23 -0
- package/kotlin/fixtures/import-selection/tsconfig.json +20 -0
- package/kotlin/fixtures/import-selection/vite.config.ts +20 -0
- package/kotlin/fixtures/import-surfaces/ImportSurfaces.native.tsx +13 -0
- package/kotlin/fixtures/import-surfaces/README.md +22 -0
- package/kotlin/fixtures/import-surfaces/Surfaces.d.kt.ts +7 -0
- package/kotlin/fixtures/import-surfaces/Surfaces.kt +64 -0
- package/kotlin/fixtures/import-surfaces/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-surfaces/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-surfaces/package.json +23 -0
- package/kotlin/fixtures/import-surfaces/tsconfig.json +20 -0
- package/kotlin/fixtures/import-surfaces/vite.config.ts +20 -0
- package/kotlin/fixtures/import-values/ImportValues.native.tsx +35 -0
- package/kotlin/fixtures/import-values/README.md +23 -0
- package/kotlin/fixtures/import-values/Values.d.kt.ts +11 -0
- package/kotlin/fixtures/import-values/Values.kt +66 -0
- package/kotlin/fixtures/import-values/app/_layout.tsx +4 -0
- package/kotlin/fixtures/import-values/app/index+spa.tsx +1 -0
- package/kotlin/fixtures/import-values/package.json +23 -0
- package/kotlin/fixtures/import-values/tsconfig.json +20 -0
- package/kotlin/fixtures/import-values/vite.config.ts +20 -0
- package/kotlin/fixtures/kotlin-app-variants/BarBehavior.kt +38 -0
- package/kotlin/fixtures/kotlin-app-variants/BarVisibility.kt +36 -0
- package/kotlin/fixtures/kotlin-app-variants/Ime.kt +3 -1
- package/kotlin/fixtures/kotlin-app-variants/TransientInsets.kt +50 -0
- package/kotlin/fork/NOTICE +6 -1
- package/kotlin/fork/README.md +15 -7
- package/kotlin/fork/build.sh +2 -0
- package/kotlin/fork/compose-worker-globals.patch +186 -4
- package/kotlin/fork/fork.json +2 -2
- package/kotlin/fork/skiko-worker-clock.patch +12 -0
- package/kotlin/toolchain.json +12 -12
- package/kotlin/tools/expo-types.main.kts +115 -0
- package/package.json +17 -23
- package/scripts/dev-server-scanner.ts +92 -66
- package/skills/contrast/SKILL.md +2 -2
- package/skills/peach-debug/SKILL.md +1 -1
- package/skills/peach-perf/SKILL.md +1 -1
- package/skills/peach-setup/SKILL.md +2 -1
- package/skills/peach-test/SKILL.md +8 -0
- package/src/assetCatalogContract.ts +43 -1
- package/src/bridge-contract-input.ts +46 -19
- package/src/bridge-contract.ts +0 -1
- package/src/bundle-channel.mjs +197 -84
- package/src/bundleGlobalFooter.ts +38 -0
- package/src/capture-contract.ts +107 -33
- package/src/cloud-contract.ts +5 -1
- package/src/cloud.ts +5 -2
- package/src/config.ts +22 -3
- package/src/configured-bundle-producer.ts +1 -1
- package/src/desktop-host-delivery.ts +95 -1
- package/src/expo-kotlin-bundle.ts +29 -0
- package/src/expo-kotlin-host.ts +201 -0
- package/src/expo-swift-host.ts +96 -76
- package/src/expoKotlinContract.ts +70 -0
- package/src/expoSwiftContract.ts +4 -25
- package/src/home-paths.ts +7 -4
- package/src/host/bridge-host.ts +23 -3
- package/src/host/fetch-proxy-handler.ts +13 -0
- package/src/host/fetch-proxy-overrides.ts +11 -0
- package/src/host/replacement-module-handler.ts +5 -2
- package/src/index.ts +3 -1
- package/src/kotlin-host.ts +463 -19
- package/src/metro-plugin.ts +56 -28
- package/src/metro-production-bundle.ts +2 -2
- package/src/native-app-identity-project.ts +190 -0
- package/src/native-app-identity.ts +398 -34
- package/src/native-firebase-config.ts +69 -15
- package/src/native-seam-manifest.ts +6 -0
- package/src/one-widget-discovery.ts +2 -1
- package/src/openstep-plist.ts +107 -0
- package/src/react-native-host-modules.ts +4 -0
- package/src/runtime-assets.ts +2 -2
- package/src/sim-client.ts +2 -2
- package/src/swift-binary-modules.ts +3 -1
- package/src/swift-compile.ts +286 -38
- package/src/swift-distribution-contract.ts +4 -0
- package/src/swift-distribution.lock.json +123 -12
- package/src/swift-distribution.ts +7 -3
- package/src/swift-host.ts +298 -83
- package/src/swift-package-manifest.ts +29 -2
- package/src/swift-package.ts +180 -10
- package/src/swift-packages.ts +4 -0
- package/src/swift-standin-emit.ts +4 -1
- package/src/swift-standins.ts +274 -15
- package/src/swift-submit.ts +62 -7
- package/src/swift-toolchain.ts +6 -1
- package/src/swiftContract.ts +126 -3
- package/src/vite-plugin-one.ts +13 -16
- package/src/vite-plugin-swift.ts +4 -5
- package/src/vite-plugin.ts +360 -144
- package/src/vite.d.ts +1 -1
- package/src/worker-system-chunks.ts +221 -0
- package/src/worklet-executable.ts +348 -38
- package/src/worklets-babel.ts +1 -1
- package/src/xcode-project.ts +243 -127
- package/dist-lib/agent-identity.cjs +0 -39
- package/dist-lib/agent-sessions.cjs +0 -760
- package/dist-lib/cli-constants.cjs +0 -32
- package/dist-lib/render-mode.cjs +0 -44
- package/kotlin/AppSources/android/view/View.kt +0 -74
- package/kotlin/AppSources/android/widget/FrameLayout.kt +0 -6
- package/src/render-mode.ts +0 -15
- /package/kotlin/{AppSources → AndroidViewSources}/android/content/Context.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/android/content/res/Configuration.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/android/graphics/Color.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/android/util/DisplayMetrics.kt +0 -0
- /package/kotlin/{AppSources → AndroidViewSources}/dev/peach/app/JavaFormat.kt +0 -0
- /package/kotlin/{AppSources → Sources}/java/lang/Runnable.kt +0 -0
package/src/swift-compile.ts
CHANGED
|
@@ -22,12 +22,15 @@ import {
|
|
|
22
22
|
} from './swift-distribution-contract'
|
|
23
23
|
import { swiftIcuAsset, type SwiftIcuAsset } from './swift-icu'
|
|
24
24
|
import {
|
|
25
|
+
swiftManifestCxxLanguageStandard,
|
|
25
26
|
swiftManifestTargets,
|
|
26
27
|
swiftPackagePartition,
|
|
27
28
|
type SwiftPackageTarget,
|
|
28
29
|
} from './swift-package'
|
|
30
|
+
import { isSwiftResourceBundles } from './swiftContract'
|
|
29
31
|
import type { SwiftImageUpload } from './swift-submit'
|
|
30
32
|
import type { SwiftWasmSdk } from './swift-toolchain'
|
|
33
|
+
import type { SwiftResourceBundle } from './swiftContract'
|
|
31
34
|
|
|
32
35
|
export { swiftIcuAsset, type SwiftIcuAsset }
|
|
33
36
|
|
|
@@ -47,17 +50,25 @@ const BUILD_JOBS = String(Math.min(4, Math.max(1, Math.floor(cores / 2))))
|
|
|
47
50
|
|
|
48
51
|
export interface SwiftCompileInput {
|
|
49
52
|
files: Record<string, string>
|
|
53
|
+
metalSources?: Record<string, string>
|
|
50
54
|
resources?: Record<string, string>
|
|
51
55
|
/** project-relative resource paths retained before the bundle namespace flattens. */
|
|
52
56
|
resourcePaths?: string[]
|
|
57
|
+
resourceBundles?: SwiftResourceBundle[]
|
|
53
58
|
images?: Record<string, SwiftImageUpload>
|
|
54
59
|
entry: string
|
|
55
60
|
/**
|
|
56
61
|
* the sources are a One swift package. One's pod compiles every file with
|
|
57
|
-
* `-import-module One`, so `
|
|
62
|
+
* `-import-module One`, so `PeachModule`, `PeachPackage` and `JSON` resolve
|
|
58
63
|
* without an import; the compile links Peach's `One` module the same way.
|
|
59
64
|
*/
|
|
60
65
|
oneModule?: boolean
|
|
66
|
+
/**
|
|
67
|
+
* WebAssembly static libraries a local compile links, base64 by the target
|
|
68
|
+
* they link into: a vendored c framework's own wasm build, whose functions
|
|
69
|
+
* replace the stand-in's traps.
|
|
70
|
+
*/
|
|
71
|
+
libraries?: Record<string, string>
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
export interface SwiftCompileOptions {
|
|
@@ -124,6 +135,7 @@ export function swiftModuleInputFiles(root: string): string[] {
|
|
|
124
135
|
'Package.swift',
|
|
125
136
|
'scripts/contrast-app-Package.swift',
|
|
126
137
|
'scripts/build-distribution.ts',
|
|
138
|
+
'scripts/distribution-clang.ts',
|
|
127
139
|
'scripts/build-distribution-plugins.sh',
|
|
128
140
|
'scripts/build-preview-plugin.sh',
|
|
129
141
|
'toolchain.json',
|
|
@@ -160,6 +172,10 @@ export function swiftMacroPlugins(moduleRoot: string): {
|
|
|
160
172
|
stale: false,
|
|
161
173
|
}
|
|
162
174
|
const dir = path.join(moduleRoot, '.build/host/RnxPreviewMacros')
|
|
175
|
+
const release = JSON.parse(
|
|
176
|
+
readFileSync(path.join(moduleRoot, 'toolchain.json'), 'utf8'),
|
|
177
|
+
).release
|
|
178
|
+
const compilerStamp = path.join(dir, 'compiler-release')
|
|
163
179
|
// linux names a plugin's module from lib<Module>.so
|
|
164
180
|
const ext = process.platform === 'darwin' ? 'dylib' : 'so'
|
|
165
181
|
const plugins = [
|
|
@@ -174,16 +190,20 @@ export function swiftMacroPlugins(moduleRoot: string): {
|
|
|
174
190
|
]
|
|
175
191
|
return {
|
|
176
192
|
libraries: plugins.map(({ library }) => library),
|
|
177
|
-
stale:
|
|
178
|
-
(
|
|
179
|
-
|
|
180
|
-
|
|
193
|
+
stale:
|
|
194
|
+
!existsSync(compilerStamp) ||
|
|
195
|
+
readFileSync(compilerStamp, 'utf8').trim() !== release ||
|
|
196
|
+
plugins.some(
|
|
197
|
+
({ library, source }) =>
|
|
198
|
+
!existsSync(library) || statSync(source).mtimeMs > statSync(library).mtimeMs,
|
|
199
|
+
),
|
|
181
200
|
}
|
|
182
201
|
}
|
|
183
202
|
|
|
184
203
|
async function ensureMacroPlugins(
|
|
185
204
|
moduleRoot: string,
|
|
186
205
|
toolchainBin: string,
|
|
206
|
+
release: string,
|
|
187
207
|
): Promise<string[]> {
|
|
188
208
|
const { libraries, stale } = swiftMacroPlugins(moduleRoot)
|
|
189
209
|
if (stale) {
|
|
@@ -192,6 +212,10 @@ async function ensureMacroPlugins(
|
|
|
192
212
|
toolchainBin,
|
|
193
213
|
libraries[0],
|
|
194
214
|
])
|
|
215
|
+
writeFileSync(
|
|
216
|
+
path.join(path.dirname(libraries[0]!), 'compiler-release'),
|
|
217
|
+
`${release}\n`,
|
|
218
|
+
)
|
|
195
219
|
}
|
|
196
220
|
return libraries
|
|
197
221
|
}
|
|
@@ -279,6 +303,7 @@ const OPTIONAL_FRAMEWORK_DEPENDENCIES: Record<string, string[]> = {
|
|
|
279
303
|
TikTokBusinessSDK: [],
|
|
280
304
|
nSure: [],
|
|
281
305
|
Statsig: [],
|
|
306
|
+
TOCropViewController: [],
|
|
282
307
|
RiveRuntime: ['MetalKit'],
|
|
283
308
|
MetalKit: [],
|
|
284
309
|
DatadogCore: [],
|
|
@@ -293,6 +318,7 @@ const OPTIONAL_FRAMEWORK_DEPENDENCIES: Record<string, string[]> = {
|
|
|
293
318
|
Intercom: [],
|
|
294
319
|
FirebaseCore: [],
|
|
295
320
|
FirebaseSharedSwift: ['FirebaseCore'],
|
|
321
|
+
FirebaseRemoteConfig: ['FirebaseCore', 'FirebaseSharedSwift'],
|
|
296
322
|
FirebaseFirestoreInternal: ['FirebaseCore'],
|
|
297
323
|
FirebaseAnalytics: ['FirebaseCore'],
|
|
298
324
|
FirebaseAppCheck: ['FirebaseCore'],
|
|
@@ -300,6 +326,7 @@ const OPTIONAL_FRAMEWORK_DEPENDENCIES: Record<string, string[]> = {
|
|
|
300
326
|
FirebaseCrashlytics: ['FirebaseCore'],
|
|
301
327
|
FirebaseFirestore: ['FirebaseCore', 'FirebaseSharedSwift', 'FirebaseFirestoreInternal'],
|
|
302
328
|
FirebaseStorage: ['FirebaseCore'],
|
|
329
|
+
GoogleMobileAds: [],
|
|
303
330
|
FBAudienceNetwork: [],
|
|
304
331
|
}
|
|
305
332
|
const OPTIONAL_FRAMEWORKS = new Set(Object.keys(OPTIONAL_FRAMEWORK_DEPENDENCIES))
|
|
@@ -514,13 +541,21 @@ export function missingSwiftModules(
|
|
|
514
541
|
|
|
515
542
|
export function swiftTargetDependencies(
|
|
516
543
|
files: Record<string, string>,
|
|
517
|
-
targets: Pick<SwiftPackageTarget, 'name' | 'path'>[],
|
|
544
|
+
targets: Pick<SwiftPackageTarget, 'name' | 'path' | 'dependencies'>[],
|
|
518
545
|
): Map<string, string[]> {
|
|
519
546
|
const names = new Set([...OPTIONAL_FRAMEWORKS, ...targets.map((target) => target.name)])
|
|
520
547
|
const siblings = new Map<string, string[]>()
|
|
521
548
|
for (const target of targets) {
|
|
522
549
|
const prefix = target.path === '.' ? '' : `${target.path}/`
|
|
523
|
-
const deps = new Set
|
|
550
|
+
const deps = new Set(
|
|
551
|
+
(target.dependencies ?? []).flatMap((dependency) =>
|
|
552
|
+
dependency.kind === 'target' &&
|
|
553
|
+
dependency.name !== target.name &&
|
|
554
|
+
names.has(dependency.name)
|
|
555
|
+
? [dependency.name]
|
|
556
|
+
: [],
|
|
557
|
+
),
|
|
558
|
+
)
|
|
524
559
|
for (const [file, contents] of Object.entries(files)) {
|
|
525
560
|
if (file === 'Package.swift' || !file.startsWith(prefix)) continue
|
|
526
561
|
if (
|
|
@@ -554,23 +589,22 @@ const importsSpriteKit = (files: Record<string, string>): boolean =>
|
|
|
554
589
|
// every iOS source sees through Foundation what darwin's Foundation exports:
|
|
555
590
|
// PeachObjC supplies the ObjectiveC module's selectors, Dispatch Foundation's
|
|
556
591
|
// Darwin queue exports, and FoundationNetworking (re-exporting PeachFoundation)
|
|
557
|
-
// URLSession, NotificationCenter, OperationQueue and the CoreFoundation types
|
|
558
|
-
//
|
|
559
|
-
//
|
|
560
|
-
//
|
|
561
|
-
//
|
|
562
|
-
//
|
|
563
|
-
//
|
|
564
|
-
//
|
|
565
|
-
//
|
|
566
|
-
// of them re-exports. scripts/contrast-app-Package.swift and
|
|
592
|
+
// URLSession, NotificationCenter, OperationQueue and the CoreFoundation types,
|
|
593
|
+
// and PeachFoundationCombine the ObservableObject and Published aliases.
|
|
594
|
+
// Darwin is the platform libc and Mach, as Foundation re-exports it on iOS:
|
|
595
|
+
// it re-exports WASILibc, whose math.h answers the free round Kingfisher's
|
|
596
|
+
// SizeExtensions reaches, and the sdk's separate pthread module wasi_pthread,
|
|
597
|
+
// whose mutexes a Foundation-only source reaches (SwiftSoup's Mutex). these
|
|
598
|
+
// modules export only names iOS has, WASILibc's wasi-only names aside;
|
|
599
|
+
// Peach's host plumbing is `package` or lives in PeachJSON, which none of
|
|
600
|
+
// them re-exports. scripts/contrast-app-Package.swift and
|
|
567
601
|
// example/Package.swift carry the same flags.
|
|
568
602
|
export const FOUNDATION_IMPLICIT_MODULES = [
|
|
569
603
|
'PeachObjC',
|
|
570
604
|
'Dispatch',
|
|
571
605
|
'FoundationNetworking',
|
|
572
|
-
'
|
|
573
|
-
'
|
|
606
|
+
'PeachFoundationCombine',
|
|
607
|
+
'Darwin',
|
|
574
608
|
]
|
|
575
609
|
const FOUNDATION_IMPLICIT_FLAGS = FOUNDATION_IMPLICIT_MODULES.map(
|
|
576
610
|
(module) => `, "-Xfrontend", "-import-module", "-Xfrontend", "${module}"`,
|
|
@@ -578,7 +612,7 @@ const FOUNDATION_IMPLICIT_FLAGS = FOUNDATION_IMPLICIT_MODULES.map(
|
|
|
578
612
|
const ONE_IMPLICIT_FLAGS = ', "-Xfrontend", "-import-module", "-Xfrontend", "One"'
|
|
579
613
|
|
|
580
614
|
/** bump with any change to the emitted multi-target manifest text. */
|
|
581
|
-
export const MULTI_MANIFEST_VERSION =
|
|
615
|
+
export const MULTI_MANIFEST_VERSION = 18
|
|
582
616
|
|
|
583
617
|
export function swiftArtifactHash(
|
|
584
618
|
input: SwiftCompileInput,
|
|
@@ -586,6 +620,8 @@ export function swiftArtifactHash(
|
|
|
586
620
|
moduleRoot: string,
|
|
587
621
|
): string {
|
|
588
622
|
const hash = createHash('sha256')
|
|
623
|
+
// v22: Foundation sources see Darwin, which carries the libc and Mach
|
|
624
|
+
// v21: Foundation sources see the ObservableObject and Published aliases
|
|
589
625
|
// v20: supplied table editing and swipe methods preserve objective-c selectors
|
|
590
626
|
// v18: NSValue(time:) constructs NSStructBox through NSValue.boxedTime
|
|
591
627
|
// v17: AVAsset(url:) constructs AVURLAsset for the class cluster
|
|
@@ -602,13 +638,22 @@ export function swiftArtifactHash(
|
|
|
602
638
|
// v6: app and scene delegate classes compile final
|
|
603
639
|
// (v5: a target declaring resources gets SwiftPM's Bundle.module accessor;
|
|
604
640
|
// v4: sources compile through swiftSourceAsIOS)
|
|
605
|
-
hash.update(`swift-compile/
|
|
641
|
+
hash.update(`swift-compile/v23\n${release}\n`)
|
|
606
642
|
if (input.oneModule) hash.update('one-module\n')
|
|
607
643
|
hash.update(swiftModuleDigest(moduleRoot))
|
|
608
644
|
for (const file of Object.keys(input.files).sort()) {
|
|
609
645
|
hash.update(createHash('sha256').update(file).digest())
|
|
610
646
|
hash.update(createHash('sha256').update(input.files[file]).digest())
|
|
611
647
|
}
|
|
648
|
+
for (const file of Object.keys(input.metalSources ?? {}).sort()) {
|
|
649
|
+
hash.update('metal-source\n')
|
|
650
|
+
hash.update(createHash('sha256').update(file).digest())
|
|
651
|
+
hash.update(
|
|
652
|
+
createHash('sha256')
|
|
653
|
+
.update(input.metalSources?.[file] ?? '')
|
|
654
|
+
.digest(),
|
|
655
|
+
)
|
|
656
|
+
}
|
|
612
657
|
for (const base of Object.keys(input.resources ?? {}).sort()) {
|
|
613
658
|
hash.update(createHash('sha256').update(base).digest())
|
|
614
659
|
hash.update(
|
|
@@ -628,6 +673,19 @@ export function swiftArtifactHash(
|
|
|
628
673
|
hash.update('resource-path\n')
|
|
629
674
|
hash.update(createHash('sha256').update(file).digest())
|
|
630
675
|
}
|
|
676
|
+
hash.update(
|
|
677
|
+
JSON.stringify(
|
|
678
|
+
[...(input.resourceBundles ?? [])].sort((a, b) => a.target.localeCompare(b.target)),
|
|
679
|
+
),
|
|
680
|
+
)
|
|
681
|
+
for (const target of Object.keys(input.libraries ?? {}).sort()) {
|
|
682
|
+
hash.update(`library\n${target}\n`)
|
|
683
|
+
hash.update(
|
|
684
|
+
createHash('sha256')
|
|
685
|
+
.update(input.libraries?.[target] ?? '')
|
|
686
|
+
.digest(),
|
|
687
|
+
)
|
|
688
|
+
}
|
|
631
689
|
const targets = compileTargets(input)
|
|
632
690
|
if (targets.length > 0) {
|
|
633
691
|
hash.update(`swift-multi/v${MULTI_MANIFEST_VERSION}\n`)
|
|
@@ -643,14 +701,28 @@ export function swiftArtifactHash(
|
|
|
643
701
|
return hash.digest('hex')
|
|
644
702
|
}
|
|
645
703
|
|
|
704
|
+
interface SwiftNativeTargetPlan {
|
|
705
|
+
path: string
|
|
706
|
+
includeDirectory: string
|
|
707
|
+
// units that consume a swift-generated header: excluded from the original
|
|
708
|
+
// target and compiled by the downstream implementation target.
|
|
709
|
+
lateSources: string[]
|
|
710
|
+
late: { name: string; producers: string[] }
|
|
711
|
+
}
|
|
712
|
+
|
|
646
713
|
export function emitSwiftPackageManifest(args: {
|
|
647
714
|
targets: SwiftPackageTarget[]
|
|
715
|
+
cxxLanguageStandard?: string
|
|
716
|
+
native?: Map<string, SwiftNativeTargetPlan>
|
|
717
|
+
headerDirectory?: string
|
|
648
718
|
siblings: Map<string, string[]>
|
|
649
719
|
moduleRoot: string
|
|
650
720
|
oneModule?: boolean
|
|
651
721
|
spriteKit?: boolean
|
|
652
722
|
/** link the prebuilt distribution at moduleRoot instead of its sources. */
|
|
653
723
|
distribution?: SwiftDistributionManifest
|
|
724
|
+
/** the static library each target links, by target name. */
|
|
725
|
+
libraries?: Map<string, string>
|
|
654
726
|
}): string {
|
|
655
727
|
const { targets, siblings, moduleRoot, oneModule, spriteKit, distribution } = args
|
|
656
728
|
const reachedFrameworks = new Set(
|
|
@@ -682,6 +754,10 @@ export function emitSwiftPackageManifest(args: {
|
|
|
682
754
|
const isolation = target.mainActorIsolation
|
|
683
755
|
? ' .defaultIsolation(MainActor.self),'
|
|
684
756
|
: ''
|
|
757
|
+
const interoperability = target.cxxInterop ? ' .interoperabilityMode(.Cxx),' : ''
|
|
758
|
+
const defines = (target.defines ?? [])
|
|
759
|
+
.map((name) => ` .define(${JSON.stringify(name)}),`)
|
|
760
|
+
.join('')
|
|
685
761
|
// a distribution's modules import from its modules/ directory, and its
|
|
686
762
|
// objects link as inputs, exactly as a source build links every object it
|
|
687
763
|
// compiled: whole, and ahead of the sdk libraries, so PeachICU's
|
|
@@ -693,9 +769,29 @@ export function emitSwiftPackageManifest(args: {
|
|
|
693
769
|
const imports = distribution
|
|
694
770
|
? `, "-I", ${JSON.stringify(path.join(moduleRoot, 'modules'))}`
|
|
695
771
|
: ''
|
|
696
|
-
const
|
|
772
|
+
const native = args.native?.get(target.name)
|
|
773
|
+
const nativeImports = (siblings.get(target.name) ?? [])
|
|
774
|
+
.filter((name) => args.native?.has(name))
|
|
775
|
+
.map(
|
|
776
|
+
(name) =>
|
|
777
|
+
`, "-Xfrontend", "-import-module", "-Xfrontend", ${JSON.stringify(name)}`,
|
|
778
|
+
)
|
|
779
|
+
.join('')
|
|
780
|
+
const header =
|
|
781
|
+
args.headerDirectory &&
|
|
782
|
+
[...(args.native?.values() ?? [])].some((value) =>
|
|
783
|
+
value.late.producers.includes(target.name),
|
|
784
|
+
)
|
|
785
|
+
? `, "-emit-objc-header-path", ${JSON.stringify(path.join(args.headerDirectory, `${target.name}-Swift.h`))}`
|
|
786
|
+
: ''
|
|
787
|
+
const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation}${interoperability}${defines} .unsafeFlags(["-Osize"${FOUNDATION_IMPLICIT_FLAGS}${oneModule ? ONE_IMPLICIT_FLAGS : ''}${imports}${nativeImports}${header}])]`
|
|
697
788
|
const deps = [
|
|
698
|
-
...(
|
|
789
|
+
...(target.executable
|
|
790
|
+
? [...(args.native?.values() ?? [])].map((value) =>
|
|
791
|
+
JSON.stringify(value.late.name),
|
|
792
|
+
)
|
|
793
|
+
: []),
|
|
794
|
+
...(distribution || native
|
|
699
795
|
? []
|
|
700
796
|
: [
|
|
701
797
|
'.product(name: "SwiftUI", package: "sootsim-swift")',
|
|
@@ -729,13 +825,17 @@ export function emitSwiftPackageManifest(args: {
|
|
|
729
825
|
]),
|
|
730
826
|
.unsafeFlags(["-Xlinker", "--strip-all"], .when(configuration: .release)),
|
|
731
827
|
]`
|
|
732
|
-
:
|
|
828
|
+
: args.libraries?.has(target.name)
|
|
829
|
+
? `,
|
|
830
|
+
linkerSettings: [.unsafeFlags([${JSON.stringify(args.libraries.get(target.name))}])]`
|
|
831
|
+
: ''
|
|
733
832
|
return [
|
|
734
833
|
` ${kind}(`,
|
|
735
834
|
` name: "${target.name}",`,
|
|
736
835
|
` dependencies: [${deps}],`,
|
|
737
836
|
` path: "${target.path}",`,
|
|
738
|
-
` ${
|
|
837
|
+
...(native ? [` exclude: ${JSON.stringify(native.lateSources)},`] : []),
|
|
838
|
+
` ${native ? 'cxxSettings: []' : swiftSettings}${link}`,
|
|
739
839
|
` ),`,
|
|
740
840
|
].join('\n')
|
|
741
841
|
}
|
|
@@ -752,7 +852,17 @@ export function emitSwiftPackageManifest(args: {
|
|
|
752
852
|
` dependencies: [${distribution ? '' : `.package(path: "${moduleRoot}")`}],`,
|
|
753
853
|
' targets: [',
|
|
754
854
|
...targets.map(stanza),
|
|
755
|
-
|
|
855
|
+
...[...(args.native?.entries() ?? [])].flatMap(([name, native]) => [
|
|
856
|
+
` .target(name: ${JSON.stringify(native.late.name)},`,
|
|
857
|
+
` dependencies: ${JSON.stringify([name, ...native.late.producers])},`,
|
|
858
|
+
` path: ${JSON.stringify(native.path)},`,
|
|
859
|
+
` sources: ${JSON.stringify(native.lateSources)},`,
|
|
860
|
+
` publicHeadersPath: "include",`,
|
|
861
|
+
` cxxSettings: [.unsafeFlags(["-fno-cxx-modules", "-I", ${JSON.stringify(native.includeDirectory)}, "-I", ${JSON.stringify(args.headerDirectory)}])]),`,
|
|
862
|
+
]),
|
|
863
|
+
args.cxxLanguageStandard
|
|
864
|
+
? ` ],\n cxxLanguageStandard: .${args.cxxLanguageStandard}`
|
|
865
|
+
: ' ]',
|
|
756
866
|
')',
|
|
757
867
|
'',
|
|
758
868
|
].join('\n')
|
|
@@ -761,7 +871,7 @@ export function emitSwiftPackageManifest(args: {
|
|
|
761
871
|
// the build tree mirrors the input: a file is written only when its text
|
|
762
872
|
// changed and a file the input dropped is removed, so an unchanged source
|
|
763
873
|
// keeps its mtime and swiftpm rebuilds only what moved. `.build` stays.
|
|
764
|
-
export function syncSwiftTree(base: string, files: Map<string, string>): void {
|
|
874
|
+
export function syncSwiftTree(base: string, files: Map<string, string | Buffer>): void {
|
|
765
875
|
mkdirSync(base, { recursive: true })
|
|
766
876
|
const walk = (dir: string): void => {
|
|
767
877
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
@@ -773,9 +883,15 @@ export function syncSwiftTree(base: string, files: Map<string, string>): void {
|
|
|
773
883
|
}
|
|
774
884
|
walk(base)
|
|
775
885
|
for (const [full, contents] of files) {
|
|
776
|
-
if (
|
|
886
|
+
if (
|
|
887
|
+
existsSync(full) &&
|
|
888
|
+
(typeof contents === 'string'
|
|
889
|
+
? readFileSync(full, 'utf8') === contents
|
|
890
|
+
: readFileSync(full).equals(contents))
|
|
891
|
+
)
|
|
892
|
+
continue
|
|
777
893
|
mkdirSync(path.dirname(full), { recursive: true })
|
|
778
|
-
writeFileSync(full, contents
|
|
894
|
+
writeFileSync(full, contents)
|
|
779
895
|
}
|
|
780
896
|
}
|
|
781
897
|
|
|
@@ -1009,7 +1125,12 @@ function liftExtensionOverrides(
|
|
|
1009
1125
|
nameAt: number
|
|
1010
1126
|
edits: [number, number, string][]
|
|
1011
1127
|
}[] = []
|
|
1012
|
-
const overrides: {
|
|
1128
|
+
const overrides: {
|
|
1129
|
+
type: string
|
|
1130
|
+
member: string
|
|
1131
|
+
at: number
|
|
1132
|
+
nameAt: number
|
|
1133
|
+
}[] = []
|
|
1013
1134
|
// the offset just past the brace that closes the one at `open`
|
|
1014
1135
|
const closing = (open: number): number => closingBrace(source, tokens, open)
|
|
1015
1136
|
for (const at of tokens) {
|
|
@@ -2203,6 +2324,11 @@ export function writeSwiftProject(
|
|
|
2203
2324
|
input: SwiftCompileInput,
|
|
2204
2325
|
moduleRoot: string,
|
|
2205
2326
|
): void {
|
|
2327
|
+
if (
|
|
2328
|
+
input.resourceBundles !== undefined &&
|
|
2329
|
+
!isSwiftResourceBundles(input.resourceBundles)
|
|
2330
|
+
)
|
|
2331
|
+
throw new Error('swift compile input has invalid target bundle assignments')
|
|
2206
2332
|
const resourceTargets = swiftManifestTargets(
|
|
2207
2333
|
input.files['Package.swift'] ?? '',
|
|
2208
2334
|
input.resourcePaths,
|
|
@@ -2223,7 +2349,96 @@ export function writeSwiftProject(
|
|
|
2223
2349
|
},
|
|
2224
2350
|
]
|
|
2225
2351
|
: compileTargets(input)
|
|
2226
|
-
const files = new Map<string, string>()
|
|
2352
|
+
const files = new Map<string, string | Buffer>()
|
|
2353
|
+
const native = new Map<string, SwiftNativeTargetPlan>()
|
|
2354
|
+
const headerDirectory = path.join(layout.root, '.build', 'peach-cxx-headers')
|
|
2355
|
+
// declarations are imported before swift can emit the header that native
|
|
2356
|
+
// implementations consume. give those implementations a downstream target.
|
|
2357
|
+
for (const target of targets) {
|
|
2358
|
+
const prefix = target.path === '.' ? '' : `${target.path}/`
|
|
2359
|
+
const entries = Object.entries(input.files).filter(
|
|
2360
|
+
([file]) =>
|
|
2361
|
+
file.startsWith(prefix) &&
|
|
2362
|
+
!targets.some(
|
|
2363
|
+
(candidate) =>
|
|
2364
|
+
candidate.name !== target.name &&
|
|
2365
|
+
candidate.path !== '.' &&
|
|
2366
|
+
candidate.path.startsWith(prefix) &&
|
|
2367
|
+
file.startsWith(`${candidate.path}/`),
|
|
2368
|
+
),
|
|
2369
|
+
)
|
|
2370
|
+
if (entries.some(([file]) => file.endsWith('.swift'))) continue
|
|
2371
|
+
const units = entries.filter(([file]) => /\.(?:c|cc|cpp|cxx|m|mm)$/.test(file))
|
|
2372
|
+
if (units.length === 0) continue
|
|
2373
|
+
const includes = `${prefix}include/`
|
|
2374
|
+
const consumers = new Map<string, Set<string>>()
|
|
2375
|
+
const reverse = new Map<string, string[]>()
|
|
2376
|
+
for (const [file, contents] of entries) {
|
|
2377
|
+
const producers = new Set<string>()
|
|
2378
|
+
// a block-commented include is not an edge.
|
|
2379
|
+
const source = contents.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
2380
|
+
for (const match of source.matchAll(/^\s*#\s*include\s*[<"]([^>"]+)[>"]/gm)) {
|
|
2381
|
+
const include = match[1]!
|
|
2382
|
+
const producer = /(?:^|\/)([^/]+)-Swift\.h$/.exec(include)?.[1]
|
|
2383
|
+
if (producer && targets.some((value) => value.name === producer))
|
|
2384
|
+
producers.add(producer)
|
|
2385
|
+
const local = [
|
|
2386
|
+
path.posix.join(path.posix.dirname(file), include),
|
|
2387
|
+
`${includes}${include}`,
|
|
2388
|
+
].find((candidate) => input.files[candidate] !== undefined)
|
|
2389
|
+
if (local) {
|
|
2390
|
+
reverse.set(local, [...(reverse.get(local) ?? []), file])
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
consumers.set(file, producers)
|
|
2394
|
+
}
|
|
2395
|
+
const queue = [...consumers.keys()].filter((file) => consumers.get(file)!.size > 0)
|
|
2396
|
+
for (let index = 0; index < queue.length; index++) {
|
|
2397
|
+
const file = queue[index]!
|
|
2398
|
+
for (const parent of reverse.get(file) ?? []) {
|
|
2399
|
+
const inherited = consumers.get(parent)!
|
|
2400
|
+
const before = inherited.size
|
|
2401
|
+
for (const producer of consumers.get(file)!) inherited.add(producer)
|
|
2402
|
+
if (before !== inherited.size) queue.push(parent)
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
const late = units.filter(([file]) => consumers.get(file)!.size > 0)
|
|
2406
|
+
if (late.length === 0) continue
|
|
2407
|
+
native.set(target.name, {
|
|
2408
|
+
path: target.path,
|
|
2409
|
+
includeDirectory: path.join(layout.root, includes),
|
|
2410
|
+
lateSources: late.map(([file]) => file.slice(prefix.length)),
|
|
2411
|
+
late: {
|
|
2412
|
+
name: `${target.name}SwiftImplementation`,
|
|
2413
|
+
producers: [
|
|
2414
|
+
...new Set(late.flatMap(([file]) => [...consumers.get(file)!])),
|
|
2415
|
+
].sort(),
|
|
2416
|
+
},
|
|
2417
|
+
})
|
|
2418
|
+
// only declaration roots belong to the imported clang module. headers
|
|
2419
|
+
// consuming swift's generated output belong to its implementation target.
|
|
2420
|
+
// a package that ships its own module map keeps it.
|
|
2421
|
+
if (input.files[`${includes}module.modulemap`] !== undefined) continue
|
|
2422
|
+
const roots = entries.filter(
|
|
2423
|
+
([file]) =>
|
|
2424
|
+
file.startsWith(includes) &&
|
|
2425
|
+
/\.(?:h|hpp|hh|hxx)$/.test(file) &&
|
|
2426
|
+
consumers.get(file)!.size === 0,
|
|
2427
|
+
)
|
|
2428
|
+
files.set(
|
|
2429
|
+
path.join(layout.root, includes, 'module.modulemap'),
|
|
2430
|
+
[
|
|
2431
|
+
`module ${target.name} {`,
|
|
2432
|
+
...roots.map(
|
|
2433
|
+
([file]) => ` header ${JSON.stringify(file.slice(includes.length))}`,
|
|
2434
|
+
),
|
|
2435
|
+
' export *',
|
|
2436
|
+
'}',
|
|
2437
|
+
'',
|
|
2438
|
+
].join('\n'),
|
|
2439
|
+
)
|
|
2440
|
+
}
|
|
2441
|
+
if (native.size > 0) mkdirSync(headerDirectory, { recursive: true })
|
|
2227
2442
|
// swiftpm plans a build root's build once and reuses the plan until a
|
|
2228
2443
|
// manifest changes, so a file added to the module would never compile
|
|
2229
2444
|
// there (RAN: a broken new UIKitCore file built "complete" in 0.1s). the
|
|
@@ -2239,7 +2454,11 @@ export function writeSwiftProject(
|
|
|
2239
2454
|
JSON.stringify(
|
|
2240
2455
|
resourceTargets
|
|
2241
2456
|
.filter((target) => target.resources)
|
|
2242
|
-
.map((target) => [
|
|
2457
|
+
.map((target) => [
|
|
2458
|
+
target.name,
|
|
2459
|
+
target.path,
|
|
2460
|
+
input.resourceBundles?.find((bundle) => bundle.target === target.name)?.path,
|
|
2461
|
+
]),
|
|
2243
2462
|
),
|
|
2244
2463
|
)
|
|
2245
2464
|
.digest('hex')
|
|
@@ -2305,6 +2524,12 @@ export function writeSwiftProject(
|
|
|
2305
2524
|
files.set(path.join(layout.root, 'Package.swift'), manifest + moduleFiles)
|
|
2306
2525
|
} else {
|
|
2307
2526
|
const base = layout.multi ? layout.root : layout.sources
|
|
2527
|
+
const libraries = new Map<string, string>()
|
|
2528
|
+
for (const [target, data] of Object.entries(input.libraries ?? {})) {
|
|
2529
|
+
const file = path.join(layout.root, '.peach-libraries', `lib${target}.a`)
|
|
2530
|
+
files.set(file, Buffer.from(data, 'base64'))
|
|
2531
|
+
libraries.set(target, file)
|
|
2532
|
+
}
|
|
2308
2533
|
for (const [file, contents] of Object.entries(input.files)) {
|
|
2309
2534
|
if (file === 'Package.swift') continue
|
|
2310
2535
|
files.set(
|
|
@@ -2316,6 +2541,11 @@ export function writeSwiftProject(
|
|
|
2316
2541
|
path.join(layout.root, 'Package.swift'),
|
|
2317
2542
|
emitSwiftPackageManifest({
|
|
2318
2543
|
targets,
|
|
2544
|
+
native,
|
|
2545
|
+
headerDirectory: native.size > 0 ? headerDirectory : undefined,
|
|
2546
|
+
cxxLanguageStandard: swiftManifestCxxLanguageStandard(
|
|
2547
|
+
input.files['Package.swift'] ?? '',
|
|
2548
|
+
),
|
|
2319
2549
|
siblings: swiftTargetDependencies(
|
|
2320
2550
|
input.files,
|
|
2321
2551
|
layout.multi ? targets : targets.map((target) => ({ ...target, path: '.' })),
|
|
@@ -2324,13 +2554,20 @@ export function writeSwiftProject(
|
|
|
2324
2554
|
oneModule: input.oneModule,
|
|
2325
2555
|
spriteKit: importsSpriteKit(input.files),
|
|
2326
2556
|
distribution: distribution ?? undefined,
|
|
2557
|
+
libraries,
|
|
2327
2558
|
}) + moduleFiles,
|
|
2328
2559
|
)
|
|
2329
2560
|
}
|
|
2330
|
-
//
|
|
2331
|
-
// retain target ownership of the accessor even though its bytes share that bundle.
|
|
2561
|
+
// resource accessors and the /res pack share the original target assignment.
|
|
2332
2562
|
for (const target of resourceTargets) {
|
|
2333
2563
|
if (!target.resources) continue
|
|
2564
|
+
const bundle = input.resourceBundles?.find(
|
|
2565
|
+
(candidate) => candidate.target === target.name,
|
|
2566
|
+
)
|
|
2567
|
+
if (!bundle || bundle.sourcePath !== target.path)
|
|
2568
|
+
throw new Error(
|
|
2569
|
+
`swift resource target ${target.name} has no matching bundle assignment`,
|
|
2570
|
+
)
|
|
2334
2571
|
const directory = layout.multi ? path.join(layout.root, target.path) : layout.sources
|
|
2335
2572
|
files.set(
|
|
2336
2573
|
path.join(directory, 'ResourceBundleAccessor.generated.swift'),
|
|
@@ -2338,7 +2575,9 @@ export function writeSwiftProject(
|
|
|
2338
2575
|
'import Foundation',
|
|
2339
2576
|
'',
|
|
2340
2577
|
'extension Foundation.Bundle {',
|
|
2341
|
-
|
|
2578
|
+
bundle.path === '.'
|
|
2579
|
+
? ' static let module: Bundle = Bundle.main'
|
|
2580
|
+
: ` static let module: Bundle = {\n let url = Bundle.main.bundleURL.appendingPathComponent(${JSON.stringify(bundle.path)})\n guard let bundle = Bundle(url: url) else { fatalError("resource bundle is missing: ${bundle.target}") }\n return bundle\n }()`,
|
|
2342
2581
|
'}',
|
|
2343
2582
|
'',
|
|
2344
2583
|
].join('\n'),
|
|
@@ -2434,7 +2673,6 @@ export function compileSwiftProjectUnit(
|
|
|
2434
2673
|
process.platform === 'darwin' &&
|
|
2435
2674
|
process.env.TM_SESSION &&
|
|
2436
2675
|
process.env.CI !== 'true' &&
|
|
2437
|
-
process.env.CONTRAST_HEAVY_ADMITTED !== '1' &&
|
|
2438
2676
|
moduleRoot === path.resolve(import.meta.dirname, '../../sootsim-swift') &&
|
|
2439
2677
|
!swiftDistributionAt(moduleRoot)
|
|
2440
2678
|
) {
|
|
@@ -2462,7 +2700,11 @@ export function compileSwiftProjectUnit(
|
|
|
2462
2700
|
'--output',
|
|
2463
2701
|
output,
|
|
2464
2702
|
],
|
|
2465
|
-
{
|
|
2703
|
+
{
|
|
2704
|
+
cwd: repo,
|
|
2705
|
+
timeout: options.timeoutMs,
|
|
2706
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
2707
|
+
},
|
|
2466
2708
|
)
|
|
2467
2709
|
pending.child.stdout?.on('data', (bytes: Buffer) => process.stdout.write(bytes))
|
|
2468
2710
|
pending.child.stderr?.on('data', (bytes: Buffer) => process.stderr.write(bytes))
|
|
@@ -2508,7 +2750,11 @@ export function compileSwiftProjectUnit(
|
|
|
2508
2750
|
`swift-compile: no swift.org toolchain at ${options.toolchainBin}; install ${options.release} and its matching wasm sdk`,
|
|
2509
2751
|
)
|
|
2510
2752
|
}
|
|
2511
|
-
const macroPlugins = await ensureMacroPlugins(
|
|
2753
|
+
const macroPlugins = await ensureMacroPlugins(
|
|
2754
|
+
moduleRoot,
|
|
2755
|
+
options.toolchainBin,
|
|
2756
|
+
options.release,
|
|
2757
|
+
)
|
|
2512
2758
|
// memoized per toolchain, so only a process's first build waits on it,
|
|
2513
2759
|
// and that one reads and gzips it while swift builds
|
|
2514
2760
|
const sdk = swiftModuleSdk(moduleRoot).wasmSdkId
|
|
@@ -2518,6 +2764,8 @@ export function compileSwiftProjectUnit(
|
|
|
2518
2764
|
swift,
|
|
2519
2765
|
[
|
|
2520
2766
|
'build',
|
|
2767
|
+
'--build-system',
|
|
2768
|
+
'native',
|
|
2521
2769
|
'-j',
|
|
2522
2770
|
BUILD_JOBS,
|
|
2523
2771
|
'--package-path',
|
|
@@ -52,6 +52,8 @@ export interface SwiftDistributionLock extends SwiftWasmSdk {
|
|
|
52
52
|
release: string
|
|
53
53
|
/** the commit the module sources were built from. */
|
|
54
54
|
source: string
|
|
55
|
+
/** the Package.swift targets it was built from (swiftPeachModules). */
|
|
56
|
+
targets: string[]
|
|
55
57
|
hosts: Record<SwiftDistributionHost, { sha256: string; size: number }>
|
|
56
58
|
}
|
|
57
59
|
|
|
@@ -107,6 +109,7 @@ export function parseSwiftDistributionLock(value: unknown): SwiftDistributionLoc
|
|
|
107
109
|
typeof value.wasmSdkUrl !== 'string' ||
|
|
108
110
|
typeof value.wasmSdkChecksum !== 'string' ||
|
|
109
111
|
typeof value.source !== 'string' ||
|
|
112
|
+
!isStrings(value.targets) ||
|
|
110
113
|
!isRecord(value.hosts)
|
|
111
114
|
) {
|
|
112
115
|
throw new Error('invalid Swift distribution lock')
|
|
@@ -131,6 +134,7 @@ export function parseSwiftDistributionLock(value: unknown): SwiftDistributionLoc
|
|
|
131
134
|
wasmSdkUrl: value.wasmSdkUrl,
|
|
132
135
|
wasmSdkChecksum: value.wasmSdkChecksum,
|
|
133
136
|
source: value.source,
|
|
137
|
+
targets: value.targets,
|
|
134
138
|
hosts: {
|
|
135
139
|
'darwin-arm64': entry('darwin-arm64'),
|
|
136
140
|
'linux-x64': entry('linux-x64'),
|