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-host.ts
CHANGED
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
enumerateBundleColors,
|
|
9
9
|
enumerateBundleSymbols,
|
|
10
10
|
enumerateBundleImages,
|
|
11
|
-
|
|
11
|
+
enumerateBundleResources,
|
|
12
|
+
resolveSwiftImageResourceUrls,
|
|
12
13
|
} from '../../sootsim-swift/src/bundleAssets'
|
|
13
14
|
import { authHeaderValue, resolveCliAuth } from '../cli/auth'
|
|
14
15
|
import { resolveContrastBackendOrigin } from './backend-origin'
|
|
@@ -25,7 +26,15 @@ import {
|
|
|
25
26
|
swiftApplicationEntry,
|
|
26
27
|
} from './swift-compile'
|
|
27
28
|
import { swiftDistributionRoot, swiftModuleToolchain } from './swift-distribution'
|
|
28
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
swiftImplicitResourcePaths,
|
|
31
|
+
swiftMetalSourceFiles,
|
|
32
|
+
swiftResourceBundles,
|
|
33
|
+
swiftResourceBundleForFile,
|
|
34
|
+
swiftResourceBundleInfoPlist,
|
|
35
|
+
type SwiftPackageTarget,
|
|
36
|
+
} from './swift-package'
|
|
37
|
+
import { swiftPackageManifest } from './swift-package-manifest'
|
|
29
38
|
import {
|
|
30
39
|
REMOTE_CHECKOUTS,
|
|
31
40
|
resolveSwiftPackages,
|
|
@@ -36,6 +45,7 @@ import {
|
|
|
36
45
|
import { readPackageFile } from './swift-source-file'
|
|
37
46
|
import {
|
|
38
47
|
standinGenerationInputs,
|
|
48
|
+
standinLibrary,
|
|
39
49
|
swiftStandins,
|
|
40
50
|
type SwiftStandin,
|
|
41
51
|
} from './swift-standins'
|
|
@@ -45,6 +55,9 @@ import {
|
|
|
45
55
|
MAX_SWIFT_COMPILE_RESOURCES,
|
|
46
56
|
MAX_SWIFT_COMPILE_RESOURCE_BYTES,
|
|
47
57
|
MAX_SWIFT_COMPILE_RESOURCE_TOTAL_BYTES,
|
|
58
|
+
MAX_SWIFT_COMPILE_METAL_FILES,
|
|
59
|
+
MAX_SWIFT_COMPILE_METAL_BYTES,
|
|
60
|
+
MAX_SWIFT_COMPILE_METAL_TOTAL_BYTES,
|
|
48
61
|
MAX_SWIFT_COMPILE_IMAGES,
|
|
49
62
|
MAX_SWIFT_COMPILE_IMAGE_BYTES,
|
|
50
63
|
MAX_SWIFT_COMPILE_IMAGE_TOTAL_BYTES,
|
|
@@ -64,9 +77,10 @@ import type { SwiftEntryModuleArgs } from '../../sootsim-swift/src/entryModule'
|
|
|
64
77
|
import type {
|
|
65
78
|
AppCatalogColor,
|
|
66
79
|
SfSymbolVector,
|
|
67
|
-
|
|
80
|
+
SwiftImageResources,
|
|
68
81
|
} from './assetCatalogContract'
|
|
69
82
|
import type { SwiftCompileInput, SwiftIcuAsset } from './swift-compile'
|
|
83
|
+
import type { SwiftMetalLibrarySource, SwiftResourceBundle } from './swiftContract'
|
|
70
84
|
import type { ServerResponse } from 'node:http'
|
|
71
85
|
|
|
72
86
|
const ARTIFACT_PATH = '/__peach/swift/'
|
|
@@ -135,7 +149,7 @@ export interface SwiftArtifact {
|
|
|
135
149
|
// rather than from whichever of them ran first.
|
|
136
150
|
stamp: string
|
|
137
151
|
package: {
|
|
138
|
-
resources: Omit<SwiftResourceTable, 'images'>
|
|
152
|
+
resources: Omit<SwiftResourceTable, 'images' | 'metalUploads'>
|
|
139
153
|
bundleFiles: SwiftBundlePack
|
|
140
154
|
native: SwiftNativeModules | null
|
|
141
155
|
}
|
|
@@ -194,6 +208,8 @@ export function projectFor(
|
|
|
194
208
|
interface XcodeProjectEntry {
|
|
195
209
|
xcodeproj: string
|
|
196
210
|
target?: string
|
|
211
|
+
/** the build configuration a selected scheme runs; xcode's default otherwise. */
|
|
212
|
+
configuration?: string
|
|
197
213
|
/** peach's own modules: a remote product named one links it, never its source. */
|
|
198
214
|
provided: ReadonlySet<string> | null
|
|
199
215
|
/** the module root a local compile links, which builds binary stand-ins. */
|
|
@@ -220,12 +236,14 @@ export function openXcodeProject(
|
|
|
220
236
|
xcodeproj: string,
|
|
221
237
|
target: string | undefined,
|
|
222
238
|
moduleRoot: string | undefined,
|
|
239
|
+
configuration?: string,
|
|
223
240
|
): string {
|
|
224
|
-
const app = readXcodeAppTarget(xcodeproj, target)
|
|
241
|
+
const app = readXcodeAppTarget(xcodeproj, target, configuration)
|
|
225
242
|
const root = app.rootDir
|
|
226
243
|
xcodeProjects.set(root, {
|
|
227
244
|
xcodeproj,
|
|
228
245
|
target: app.name,
|
|
246
|
+
configuration: app.configuration,
|
|
229
247
|
provided: moduleRoot ? new Set(swiftPeachModules(moduleRoot)) : null,
|
|
230
248
|
moduleRoot: moduleRoot ?? null,
|
|
231
249
|
})
|
|
@@ -240,6 +258,7 @@ function swiftPackages(
|
|
|
240
258
|
packages: SwiftPackages
|
|
241
259
|
standins: SwiftStandin[]
|
|
242
260
|
projectGaps: Map<string, string>
|
|
261
|
+
binaries: SwiftPackageBinary[]
|
|
243
262
|
} {
|
|
244
263
|
const stamp = (file: string | null) =>
|
|
245
264
|
file && fs.existsSync(file) ? fs.statSync(file).mtimeMs : 0
|
|
@@ -328,7 +347,7 @@ function swiftPackages(
|
|
|
328
347
|
cached.standinKey = generation
|
|
329
348
|
}
|
|
330
349
|
}
|
|
331
|
-
return cached
|
|
350
|
+
return { ...cached, binaries: reached }
|
|
332
351
|
}
|
|
333
352
|
|
|
334
353
|
// the app target's sources compile as one executable target under this
|
|
@@ -361,24 +380,50 @@ interface XcodeLayout {
|
|
|
361
380
|
targets: (SwiftPackageTarget & { exclude: string[] })[]
|
|
362
381
|
packages: SwiftPackages
|
|
363
382
|
standins: SwiftStandin[]
|
|
383
|
+
/** the binary targets the stand-ins come from. */
|
|
384
|
+
binaries: SwiftPackageBinary[]
|
|
364
385
|
/** why a framework the project vendors got no stand-in, by name. */
|
|
365
386
|
projectGaps: Map<string, string>
|
|
366
387
|
/** the input directory each app and framework source compiles under. */
|
|
367
388
|
targetDirs: Map<string, string>
|
|
389
|
+
resourceBundles: SwiftResourceBundle[]
|
|
368
390
|
files: string[]
|
|
369
391
|
}
|
|
370
392
|
|
|
371
393
|
function xcodeLayout(root: string): XcodeLayout | null {
|
|
372
394
|
const registered = xcodeProjects.get(root)
|
|
373
395
|
if (!registered) return null
|
|
374
|
-
const app = readXcodeAppTarget(
|
|
375
|
-
|
|
396
|
+
const app = readXcodeAppTarget(
|
|
397
|
+
registered.xcodeproj,
|
|
398
|
+
registered.target,
|
|
399
|
+
registered.configuration,
|
|
400
|
+
)
|
|
401
|
+
const appSources = app.allSources.filter(
|
|
402
|
+
(file) => file.endsWith('.swift') || file.endsWith('.metal'),
|
|
403
|
+
)
|
|
404
|
+
const files = new Set([...app.projectFiles, ...appSources, ...app.resources])
|
|
376
405
|
if (app.infoPlistFile) files.add(app.infoPlistFile)
|
|
377
|
-
const targetDirs = new Map(
|
|
406
|
+
const targetDirs = new Map(
|
|
407
|
+
[...appSources, ...app.resources].map((file) => [file, XCODE_APP_DIR]),
|
|
408
|
+
)
|
|
409
|
+
const resourceBundles: SwiftResourceBundle[] = [
|
|
410
|
+
{ target: app.moduleName, sourcePath: XCODE_APP_DIR, path: '.' },
|
|
411
|
+
]
|
|
378
412
|
const targets: XcodeLayout['targets'] = []
|
|
379
413
|
for (const framework of app.frameworks) {
|
|
380
414
|
const dir = path.posix.join(XCODE_FRAMEWORKS_DIR, framework.moduleName)
|
|
381
|
-
|
|
415
|
+
resourceBundles.push({
|
|
416
|
+
target: framework.moduleName,
|
|
417
|
+
sourcePath: dir,
|
|
418
|
+
path: `Frameworks/${framework.moduleName}.framework`,
|
|
419
|
+
})
|
|
420
|
+
for (const file of framework.allSources) {
|
|
421
|
+
if (!file.endsWith('.swift') && !file.endsWith('.metal')) continue
|
|
422
|
+
if (targetDirs.has(file)) continue
|
|
423
|
+
targetDirs.set(file, dir)
|
|
424
|
+
files.add(file)
|
|
425
|
+
}
|
|
426
|
+
for (const file of framework.resources) {
|
|
382
427
|
if (targetDirs.has(file)) continue
|
|
383
428
|
targetDirs.set(file, dir)
|
|
384
429
|
files.add(file)
|
|
@@ -391,9 +436,10 @@ function xcodeLayout(root: string): XcodeLayout | null {
|
|
|
391
436
|
exclude: [],
|
|
392
437
|
languageMode: framework.languageMode,
|
|
393
438
|
mainActorIsolation: framework.mainActorIsolation,
|
|
439
|
+
defines: framework.defines,
|
|
394
440
|
})
|
|
395
441
|
}
|
|
396
|
-
const { packages, standins, projectGaps } = swiftPackages(registered, app)
|
|
442
|
+
const { packages, standins, projectGaps, binaries } = swiftPackages(registered, app)
|
|
397
443
|
for (const standin of standins)
|
|
398
444
|
targets.push({
|
|
399
445
|
name: standin.module,
|
|
@@ -404,6 +450,9 @@ function xcodeLayout(root: string): XcodeLayout | null {
|
|
|
404
450
|
languageMode: 5,
|
|
405
451
|
mainActorIsolation: false,
|
|
406
452
|
})
|
|
453
|
+
// xcode builds packages in swiftpm's debug configuration for Debug, which
|
|
454
|
+
// defines DEBUG, and in release for any other, as its package compiles show
|
|
455
|
+
const packageConfiguration = app.configuration === 'Debug' ? 'debug' : 'release'
|
|
407
456
|
for (const target of packages.targets) {
|
|
408
457
|
const relative = path.relative(
|
|
409
458
|
target.remote ? path.join(root, REMOTE_CHECKOUTS) : root,
|
|
@@ -420,7 +469,24 @@ function xcodeLayout(root: string): XcodeLayout | null {
|
|
|
420
469
|
...target,
|
|
421
470
|
path: target.remote ? path.posix.join(XCODE_PACKAGES_DIR, posix) : posix,
|
|
422
471
|
exclude: [],
|
|
472
|
+
defines: [
|
|
473
|
+
...(packageConfiguration === 'debug' ? ['DEBUG'] : []),
|
|
474
|
+
...target.packageDefines
|
|
475
|
+
.filter(
|
|
476
|
+
(define) =>
|
|
477
|
+
define.configuration === null ||
|
|
478
|
+
define.configuration === packageConfiguration,
|
|
479
|
+
)
|
|
480
|
+
.map((define) => define.name),
|
|
481
|
+
],
|
|
423
482
|
})
|
|
483
|
+
if (target.resources) {
|
|
484
|
+
resourceBundles.push({
|
|
485
|
+
target: target.name,
|
|
486
|
+
sourcePath: target.remote ? path.posix.join(XCODE_PACKAGES_DIR, posix) : posix,
|
|
487
|
+
path: `${swiftPackageManifest(target.packageDir).name}_${target.name}.bundle`,
|
|
488
|
+
})
|
|
489
|
+
}
|
|
424
490
|
if (!target.remote) files.add(path.join(target.packageDir, 'Package.swift'))
|
|
425
491
|
for (const file of target.files) files.add(file)
|
|
426
492
|
}
|
|
@@ -436,8 +502,10 @@ function xcodeLayout(root: string): XcodeLayout | null {
|
|
|
436
502
|
targets,
|
|
437
503
|
packages,
|
|
438
504
|
standins,
|
|
505
|
+
binaries,
|
|
439
506
|
projectGaps,
|
|
440
507
|
targetDirs,
|
|
508
|
+
resourceBundles,
|
|
441
509
|
files: [...files].sort(),
|
|
442
510
|
}
|
|
443
511
|
}
|
|
@@ -445,16 +513,24 @@ function xcodeLayout(root: string): XcodeLayout | null {
|
|
|
445
513
|
// the manifest the compile reads for an xcode app: the app target and each
|
|
446
514
|
// framework and package target, in the forms swiftManifestTargets scans.
|
|
447
515
|
function xcodeManifest(layout: XcodeLayout): string {
|
|
448
|
-
const settings = (
|
|
449
|
-
|
|
516
|
+
const settings = (target: {
|
|
517
|
+
languageMode: number
|
|
518
|
+
mainActorIsolation: boolean
|
|
519
|
+
defines?: string[]
|
|
520
|
+
}) =>
|
|
521
|
+
`swiftSettings: [${[
|
|
522
|
+
`.swiftLanguageMode(.v${target.languageMode})`,
|
|
523
|
+
...(target.mainActorIsolation ? ['.defaultIsolation(MainActor.self)'] : []),
|
|
524
|
+
...(target.defines ?? []).map((name) => `.define(${JSON.stringify(name)})`),
|
|
525
|
+
].join(', ')}]`
|
|
450
526
|
return [
|
|
451
527
|
'// swift-tools-version: 6.2',
|
|
452
528
|
'import PackageDescription',
|
|
453
529
|
'let package = Package(name: "app", targets: [',
|
|
454
|
-
` .executableTarget(name: "${layout.app.moduleName}", path: "${XCODE_APP_DIR}", ${settings(layout.app
|
|
530
|
+
` .executableTarget(name: "${layout.app.moduleName}", path: "${XCODE_APP_DIR}", ${settings(layout.app)}),`,
|
|
455
531
|
...layout.targets.map(
|
|
456
532
|
(target) =>
|
|
457
|
-
` .target(name: "${target.name}", path: "${target.path}", ${target.exclude.length > 0 ? `exclude: ${JSON.stringify(target.exclude)}, ` : ''}${target.resources ? 'resources: [], ' : ''}${settings(target
|
|
533
|
+
` .target(name: "${target.name}", path: "${target.path}", ${target.exclude.length > 0 ? `exclude: ${JSON.stringify(target.exclude)}, ` : ''}${target.resources ? 'resources: [], ' : ''}${settings(target)}),`,
|
|
458
534
|
),
|
|
459
535
|
'])',
|
|
460
536
|
'',
|
|
@@ -511,10 +587,12 @@ export function sourceFiles(root: string): string[] {
|
|
|
511
587
|
return packageFiles(root).filter((file) => file.endsWith('.swift'))
|
|
512
588
|
}
|
|
513
589
|
|
|
590
|
+
// project files and the xcconfigs their settings read are build inputs, never resources
|
|
514
591
|
function resourceCandidateFiles(root: string): string[] {
|
|
515
592
|
return packageFiles(root).filter(
|
|
516
593
|
(file) =>
|
|
517
594
|
!file.endsWith('.swift') &&
|
|
595
|
+
!file.endsWith('.xcconfig') &&
|
|
518
596
|
!['project.pbxproj', 'project.xcproj'].includes(path.basename(file)),
|
|
519
597
|
)
|
|
520
598
|
}
|
|
@@ -526,7 +604,11 @@ export function swiftProjectAppInfo(packagePath: string): {
|
|
|
526
604
|
} {
|
|
527
605
|
const registered = xcodeProjects.get(packagePath)
|
|
528
606
|
const app = registered
|
|
529
|
-
? readXcodeAppTarget(
|
|
607
|
+
? readXcodeAppTarget(
|
|
608
|
+
registered.xcodeproj,
|
|
609
|
+
registered.target,
|
|
610
|
+
registered.configuration,
|
|
611
|
+
)
|
|
530
612
|
: null
|
|
531
613
|
const files = app?.resources ?? resourceCandidateFiles(packagePath)
|
|
532
614
|
const catalogs = files.filter(
|
|
@@ -616,10 +698,12 @@ const RESOURCE_CONTENT_TYPES: Record<string, string> = {
|
|
|
616
698
|
}
|
|
617
699
|
|
|
618
700
|
export interface SwiftResourceTable {
|
|
619
|
-
/** bundle asset
|
|
620
|
-
table:
|
|
701
|
+
/** each bundle's asset names to their serving urls and scales. */
|
|
702
|
+
table: SwiftImageResources
|
|
621
703
|
/** the same rasters as compile-address inputs. */
|
|
622
704
|
images: Record<string, SwiftImageUpload>
|
|
705
|
+
metalSources: Record<string, SwiftMetalLibrarySource>
|
|
706
|
+
metalUploads: Record<string, string>
|
|
623
707
|
/** asset-catalog color name to its value. */
|
|
624
708
|
colors: Record<string, AppCatalogColor>
|
|
625
709
|
symbols: Record<string, SfSymbolVector>
|
|
@@ -634,6 +718,7 @@ export interface SwiftResourceTable {
|
|
|
634
718
|
export function buildSwiftResourceTable(
|
|
635
719
|
project: SwiftProject,
|
|
636
720
|
baseUrl: string,
|
|
721
|
+
inputs: Record<string, string>,
|
|
637
722
|
): SwiftResourceTable {
|
|
638
723
|
const limits = inputLimits(Boolean(project.hosted))
|
|
639
724
|
const absolute = resourceCandidateFiles(project.packagePath)
|
|
@@ -650,15 +735,77 @@ export function buildSwiftResourceTable(
|
|
|
650
735
|
'utf8',
|
|
651
736
|
)
|
|
652
737
|
}
|
|
653
|
-
const
|
|
654
|
-
const
|
|
655
|
-
const
|
|
656
|
-
|
|
738
|
+
const layout = xcodeLayout(project.packagePath)
|
|
739
|
+
const bundles = layout?.resourceBundles ?? swiftResourceBundles(inputs, relative)
|
|
740
|
+
const catalogFiles = relative.filter((file) => {
|
|
741
|
+
const disk = byRelative.get(file)
|
|
742
|
+
return !disk || !layout?.targetDirs.get(disk)?.startsWith(`${XCODE_FRAMEWORKS_DIR}/`)
|
|
743
|
+
})
|
|
744
|
+
const found = enumerateBundleImages(relative, readContents, (file) => {
|
|
745
|
+
const disk = byRelative.get(file)
|
|
746
|
+
if (!disk) throw new Error(`image source ${file} has no input file`)
|
|
747
|
+
const key = layout ? xcodeInputKey(layout, disk, file) : file
|
|
748
|
+
return swiftResourceBundleForFile(bundles, key)?.path ?? '.'
|
|
749
|
+
})
|
|
750
|
+
const colors = enumerateBundleColors(catalogFiles, readContents)
|
|
751
|
+
const symbols = enumerateBundleSymbols(catalogFiles, readContents, (file) => {
|
|
752
|
+
const disk = byRelative.get(file)
|
|
753
|
+
if (!disk) throw new Error(`symbol source ${file} has no input file`)
|
|
754
|
+
const key = layout ? xcodeInputKey(layout, disk, file) : file
|
|
755
|
+
return swiftResourceBundleForFile(bundles, key)?.path ?? '.'
|
|
756
|
+
})
|
|
757
|
+
const table: SwiftImageResources = Object.create(null)
|
|
657
758
|
const images: Record<string, SwiftImageUpload> = {}
|
|
759
|
+
const metalSources: Record<string, SwiftMetalLibrarySource> = {}
|
|
760
|
+
const metalUploads: Record<string, string> = {}
|
|
658
761
|
const watched: string[] = []
|
|
659
762
|
const registered = new Map<string, { bytes: Buffer; contentType: string }>()
|
|
763
|
+
const shaderFiles = relative.filter((file) => file.endsWith('.metal'))
|
|
764
|
+
const metalCandidates: Record<string, string> = {}
|
|
765
|
+
if (inputs['Package.swift'] !== undefined)
|
|
766
|
+
metalCandidates['Package.swift'] = inputs['Package.swift']
|
|
767
|
+
const metalInputs = new Map<string, { file: string; disk: string }>()
|
|
768
|
+
for (const file of shaderFiles) {
|
|
769
|
+
const disk = byRelative.get(file)
|
|
770
|
+
if (!disk) throw new Error(`metal source ${file} has no input file`)
|
|
771
|
+
const key = layout ? xcodeInputKey(layout, disk, file) : file
|
|
772
|
+
metalCandidates[key] = ''
|
|
773
|
+
metalInputs.set(key, { file, disk })
|
|
774
|
+
}
|
|
775
|
+
const metalFiles = Object.keys(swiftMetalSourceFiles(metalCandidates))
|
|
776
|
+
if (metalFiles.length > MAX_SWIFT_COMPILE_METAL_FILES)
|
|
777
|
+
throw new Error('metal source pack exceeds the compile service file cap')
|
|
778
|
+
let metalBytes = 0
|
|
779
|
+
for (const key of metalFiles) {
|
|
780
|
+
const input = metalInputs.get(key)
|
|
781
|
+
if (!input) throw new Error(`metal source ${key} has no input file`)
|
|
782
|
+
const { file, disk } = input
|
|
783
|
+
const bytes = readPackageFile(
|
|
784
|
+
project.packagePath,
|
|
785
|
+
disk,
|
|
786
|
+
MAX_SWIFT_COMPILE_METAL_BYTES,
|
|
787
|
+
)
|
|
788
|
+
metalBytes += bytes.length
|
|
789
|
+
if (metalBytes > MAX_SWIFT_COMPILE_METAL_TOTAL_BYTES)
|
|
790
|
+
throw new Error('metal source pack exceeds the compile service caps')
|
|
791
|
+
const source = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(
|
|
792
|
+
bytes,
|
|
793
|
+
)
|
|
794
|
+
const sha256 = createHash('sha256').update(bytes).digest('hex')
|
|
795
|
+
const bundle = swiftResourceBundleForFile(bundles, key)
|
|
796
|
+
if (!bundle && inputs['Package.swift'])
|
|
797
|
+
throw new Error(`metal source ${key} has no resource target bundle`)
|
|
798
|
+
metalSources[key] = {
|
|
799
|
+
sha256,
|
|
800
|
+
url: `${baseUrl}${RESOURCE_PATH}${sha256}.metal`,
|
|
801
|
+
bundlePath: bundle?.path ?? '.',
|
|
802
|
+
}
|
|
803
|
+
metalUploads[key] = source
|
|
804
|
+
watched.push(file)
|
|
805
|
+
registered.set(`${sha256}.metal`, { bytes, contentType: 'text/plain; charset=utf-8' })
|
|
806
|
+
}
|
|
660
807
|
let imageBytes = 0
|
|
661
|
-
for (const { name, file, scale } of found) {
|
|
808
|
+
for (const { name, file, scale, bundlePath } of found) {
|
|
662
809
|
const disk = byRelative.get(file)
|
|
663
810
|
if (!disk) continue
|
|
664
811
|
if (
|
|
@@ -671,8 +818,12 @@ export function buildSwiftResourceTable(
|
|
|
671
818
|
imageBytes += bytes.length
|
|
672
819
|
const hash = createHash('sha256').update(bytes).digest('hex').slice(0, 16)
|
|
673
820
|
const ext = path.posix.extname(file).toLowerCase()
|
|
674
|
-
table[
|
|
675
|
-
|
|
821
|
+
const bundle = table[bundlePath] ?? Object.create(null)
|
|
822
|
+
const variants = (bundle[name] ??= [])
|
|
823
|
+
variants.push({ uri: `${baseUrl}${RESOURCE_PATH}${hash}${ext}`, scale })
|
|
824
|
+
table[bundlePath] = bundle
|
|
825
|
+
const key = layout ? xcodeInputKey(layout, disk, file) : file
|
|
826
|
+
images[key] = {
|
|
676
827
|
file: path.posix.basename(file),
|
|
677
828
|
data: bytes.toString('base64'),
|
|
678
829
|
}
|
|
@@ -700,19 +851,17 @@ export function buildSwiftResourceTable(
|
|
|
700
851
|
project.resourcesPrevious = project.resourceFiles
|
|
701
852
|
project.resourceFiles = registered
|
|
702
853
|
}
|
|
703
|
-
return { table, images, colors, symbols, watched }
|
|
854
|
+
return { table, images, metalSources, metalUploads, colors, symbols, watched }
|
|
704
855
|
}
|
|
705
856
|
|
|
706
|
-
// the
|
|
707
|
-
//
|
|
708
|
-
// the namespace is flat like the bundle the wasm side reads: shallower
|
|
709
|
-
// paths pack first (the Resources root is the bundle root) with a lexical
|
|
710
|
-
// tiebreak, and the first spelling of a basename wins a collision. data json
|
|
857
|
+
// copied resources ride the entry module as base64 in their target bundle.
|
|
858
|
+
// each bundle keeps the existing shallow-first basename collision rule.
|
|
711
859
|
// bundle caps match the hosted compiler; oversized input refuses before reading.
|
|
712
860
|
|
|
713
861
|
export interface SwiftBundlePack {
|
|
714
|
-
/**
|
|
862
|
+
/** bundle-relative path to base64 bytes for the mount's /res. */
|
|
715
863
|
files: Record<string, string>
|
|
864
|
+
bundles: SwiftResourceBundle[]
|
|
716
865
|
/** project-relative json files this load's pack covers (for watching). */
|
|
717
866
|
watched: string[]
|
|
718
867
|
}
|
|
@@ -720,6 +869,7 @@ export interface SwiftBundlePack {
|
|
|
720
869
|
export function buildSwiftBundleFiles(
|
|
721
870
|
packagePath: string,
|
|
722
871
|
hosted: boolean,
|
|
872
|
+
inputs?: Record<string, string>,
|
|
723
873
|
): SwiftBundlePack {
|
|
724
874
|
packagePath = fs.realpathSync(packagePath)
|
|
725
875
|
const limits = inputLimits(hosted)
|
|
@@ -733,33 +883,57 @@ export function buildSwiftBundleFiles(
|
|
|
733
883
|
const watched: string[] = []
|
|
734
884
|
let total = 0
|
|
735
885
|
const xcode = xcodeLayout(packagePath)
|
|
886
|
+
const bundles =
|
|
887
|
+
xcode?.resourceBundles ??
|
|
888
|
+
swiftResourceBundles(inputs ?? packageSources(packagePath), relative)
|
|
889
|
+
const addFile = (key: string, bytes: Buffer) => {
|
|
890
|
+
if (
|
|
891
|
+
Object.keys(files).length >= limits.resources ||
|
|
892
|
+
bytes.length > limits.resourceBytes ||
|
|
893
|
+
total + bytes.length > limits.resourceTotalBytes
|
|
894
|
+
)
|
|
895
|
+
throw new Error(
|
|
896
|
+
`swift bundle pack exceeds ${limits.resources} files / ${limits.resourceTotalBytes} bytes`,
|
|
897
|
+
)
|
|
898
|
+
files[key] = bytes.toString('base64')
|
|
899
|
+
total += bytes.length
|
|
900
|
+
}
|
|
736
901
|
if (xcode) {
|
|
737
902
|
const bytes = Buffer.from(xcode.app.infoPlist)
|
|
738
903
|
if (bytes.length > limits.resourceBytes || bytes.length > limits.resourceTotalBytes)
|
|
739
904
|
throw new Error('swift launch Info.plist exceeds bundle resource limits')
|
|
740
|
-
|
|
741
|
-
total += bytes.length
|
|
905
|
+
addFile('Info.plist', bytes)
|
|
742
906
|
if (xcode.app.infoPlistFile)
|
|
743
907
|
watched.push(
|
|
744
908
|
path.relative(packagePath, xcode.app.infoPlistFile).split(path.sep).join('/'),
|
|
745
909
|
)
|
|
746
910
|
}
|
|
747
|
-
|
|
748
|
-
|
|
911
|
+
const groups = new Map<string, string[]>()
|
|
912
|
+
for (const file of relative) {
|
|
749
913
|
const disk = path.join(packagePath, ...file.split('/'))
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
)
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
914
|
+
const key = xcode ? xcodeInputKey(xcode, disk, file) : file
|
|
915
|
+
const bundle = swiftResourceBundleForFile(bundles, key)
|
|
916
|
+
const bundlePath = bundle?.path ?? '.'
|
|
917
|
+
const group = groups.get(bundlePath) ?? []
|
|
918
|
+
group.push(file)
|
|
919
|
+
groups.set(bundlePath, group)
|
|
920
|
+
}
|
|
921
|
+
for (const bundle of bundles) {
|
|
922
|
+
if (bundle.path === '.') continue
|
|
923
|
+
addFile(
|
|
924
|
+
`${bundle.path}/Info.plist`,
|
|
925
|
+
Buffer.from(swiftResourceBundleInfoPlist(bundle)),
|
|
926
|
+
)
|
|
927
|
+
}
|
|
928
|
+
for (const [bundlePath, paths] of groups) {
|
|
929
|
+
for (const { base, file } of enumerateBundleResources(paths)) {
|
|
930
|
+
watched.push(file)
|
|
931
|
+
const disk = path.join(packagePath, ...file.split('/'))
|
|
932
|
+
const bytes = readPackageFile(packagePath, disk, limits.resourceBytes)
|
|
933
|
+
addFile(bundlePath === '.' ? base : `${bundlePath}/${base}`, bytes)
|
|
757
934
|
}
|
|
758
|
-
const bytes = readPackageFile(packagePath, disk, limits.resourceBytes)
|
|
759
|
-
files[base] = bytes.toString('base64')
|
|
760
|
-
total += bytes.length
|
|
761
935
|
}
|
|
762
|
-
return { files, watched }
|
|
936
|
+
return { files, bundles, watched }
|
|
763
937
|
}
|
|
764
938
|
|
|
765
939
|
// the middleware's lookup, exported for the producer's own proof: a hit is
|
|
@@ -848,7 +1022,29 @@ export function icuUrl(origin: string, artifact: SwiftArtifact): string {
|
|
|
848
1022
|
: `${origin}${ICU_PATH}${artifact.icu.sha256}`
|
|
849
1023
|
}
|
|
850
1024
|
|
|
851
|
-
|
|
1025
|
+
// a c stand-in whose framework has a WebAssembly build links that library,
|
|
1026
|
+
// keyed by the stand-in target it links into; its own source then defines
|
|
1027
|
+
// nothing, so the library's functions run instead of the traps. one library
|
|
1028
|
+
// links once, through the first module its framework ships.
|
|
1029
|
+
function standinLibraries(layout: XcodeLayout): Map<string, SwiftStandin[]> {
|
|
1030
|
+
const linked = new Map<string, SwiftStandin[]>()
|
|
1031
|
+
for (const binary of layout.binaries) {
|
|
1032
|
+
const modules = layout.standins.filter(
|
|
1033
|
+
(standin) =>
|
|
1034
|
+
standin.target === binary.target && `${standin.module}.c` in standin.files,
|
|
1035
|
+
)
|
|
1036
|
+
if (modules.length === 0) continue
|
|
1037
|
+
const library = standinLibrary(binary, layout.app.rootDir)
|
|
1038
|
+
if (!library) continue
|
|
1039
|
+
linked.set(library, modules)
|
|
1040
|
+
}
|
|
1041
|
+
return linked
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
function packageSources(
|
|
1045
|
+
packagePath: string,
|
|
1046
|
+
linked: ReadonlySet<SwiftStandin> = new Set(),
|
|
1047
|
+
): Record<string, string> {
|
|
852
1048
|
const xcode = xcodeLayout(packagePath)
|
|
853
1049
|
const files: Record<string, string> = {}
|
|
854
1050
|
for (const file of sourceFiles(packagePath)) {
|
|
@@ -864,7 +1060,10 @@ function packageSources(packagePath: string): Record<string, string> {
|
|
|
864
1060
|
files['Package.swift'] = xcodeManifest(xcode)
|
|
865
1061
|
for (const standin of xcode.standins)
|
|
866
1062
|
for (const [file, text] of Object.entries(standin.files))
|
|
867
|
-
files[path.posix.join(XCODE_STANDINS_DIR, standin.module, file)] =
|
|
1063
|
+
files[path.posix.join(XCODE_STANDINS_DIR, standin.module, file)] =
|
|
1064
|
+
linked.has(standin) && file === `${standin.module}.c`
|
|
1065
|
+
? `// ${standin.target}'s WebAssembly library defines ${standin.module}'s functions.\n`
|
|
1066
|
+
: text
|
|
868
1067
|
}
|
|
869
1068
|
return files
|
|
870
1069
|
}
|
|
@@ -877,11 +1076,13 @@ interface SwiftPackageSnapshot {
|
|
|
877
1076
|
bundleFiles: SwiftBundlePack
|
|
878
1077
|
native: SwiftNativeModules | null
|
|
879
1078
|
glue?: string
|
|
1079
|
+
libraries?: Record<string, string>
|
|
880
1080
|
}
|
|
881
1081
|
|
|
882
1082
|
function packageSnapshot(project: SwiftProject, entry: string): SwiftPackageSnapshot {
|
|
883
|
-
const files = packageSources(project.packagePath)
|
|
884
1083
|
const layout = xcodeLayout(project.packagePath)
|
|
1084
|
+
const linked = layout ? standinLibraries(layout) : new Map<string, SwiftStandin[]>()
|
|
1085
|
+
const files = packageSources(project.packagePath, new Set([...linked.values()].flat()))
|
|
885
1086
|
const native = nativeSourceDescriptor(project.packagePath)
|
|
886
1087
|
return {
|
|
887
1088
|
files,
|
|
@@ -889,13 +1090,33 @@ function packageSnapshot(project: SwiftProject, entry: string): SwiftPackageSnap
|
|
|
889
1090
|
? xcodeInputKey(layout, path.resolve(project.packagePath, entry), entry)
|
|
890
1091
|
: entry,
|
|
891
1092
|
resourcePaths: swiftImplicitResourcePaths(
|
|
892
|
-
resourceCandidateFiles(project.packagePath).map((file) =>
|
|
893
|
-
|
|
894
|
-
|
|
1093
|
+
resourceCandidateFiles(project.packagePath).map((file) => {
|
|
1094
|
+
const relative = path
|
|
1095
|
+
.relative(project.packagePath, file)
|
|
1096
|
+
.split(path.sep)
|
|
1097
|
+
.join(path.posix.sep)
|
|
1098
|
+
return layout && file.endsWith('.metal')
|
|
1099
|
+
? xcodeInputKey(layout, file, relative)
|
|
1100
|
+
: relative
|
|
1101
|
+
}),
|
|
1102
|
+
),
|
|
1103
|
+
resources: buildSwiftResourceTable(project, '', files),
|
|
1104
|
+
bundleFiles: buildSwiftBundleFiles(
|
|
1105
|
+
project.packagePath,
|
|
1106
|
+
Boolean(project.hosted),
|
|
1107
|
+
files,
|
|
895
1108
|
),
|
|
896
|
-
resources: buildSwiftResourceTable(project, ''),
|
|
897
|
-
bundleFiles: buildSwiftBundleFiles(project.packagePath, Boolean(project.hosted)),
|
|
898
1109
|
native,
|
|
1110
|
+
...(linked.size > 0
|
|
1111
|
+
? {
|
|
1112
|
+
libraries: Object.fromEntries(
|
|
1113
|
+
[...linked].map(([library, [first]]) => [
|
|
1114
|
+
first!.module,
|
|
1115
|
+
fs.readFileSync(library).toString('base64'),
|
|
1116
|
+
]),
|
|
1117
|
+
),
|
|
1118
|
+
}
|
|
1119
|
+
: {}),
|
|
899
1120
|
...(native
|
|
900
1121
|
? {
|
|
901
1122
|
glue: readPackageFile(
|
|
@@ -911,11 +1132,14 @@ function packageSnapshot(project: SwiftProject, entry: string): SwiftPackageSnap
|
|
|
911
1132
|
function snapshotCompileInput(snapshot: SwiftPackageSnapshot): SwiftCompileInput {
|
|
912
1133
|
const input: SwiftCompileInput = {
|
|
913
1134
|
files: snapshot.files,
|
|
1135
|
+
metalSources: snapshot.resources.metalUploads,
|
|
914
1136
|
resourcePaths: snapshot.resourcePaths,
|
|
1137
|
+
resourceBundles: snapshot.bundleFiles.bundles,
|
|
915
1138
|
resources: snapshot.bundleFiles.files,
|
|
916
1139
|
images: snapshot.resources.images,
|
|
917
1140
|
entry: snapshot.entry,
|
|
918
1141
|
oneModule: true,
|
|
1142
|
+
...(snapshot.libraries ? { libraries: snapshot.libraries } : {}),
|
|
919
1143
|
}
|
|
920
1144
|
return snapshot.glue ? withNativeSourceGlue(input, snapshot.glue) : input
|
|
921
1145
|
}
|
|
@@ -935,6 +1159,7 @@ async function compile(
|
|
|
935
1159
|
table: snapshot.resources.table,
|
|
936
1160
|
colors: snapshot.resources.colors,
|
|
937
1161
|
symbols: snapshot.resources.symbols,
|
|
1162
|
+
metalSources: snapshot.resources.metalSources,
|
|
938
1163
|
watched: snapshot.resources.watched,
|
|
939
1164
|
}
|
|
940
1165
|
const content = {
|
|
@@ -1066,15 +1291,6 @@ export function swiftApiGapReport(output: string): string | null {
|
|
|
1066
1291
|
].join('\n')
|
|
1067
1292
|
}
|
|
1068
1293
|
|
|
1069
|
-
// the platform modules peach decided not to provide (plans/partners/triumph/
|
|
1070
|
-
// arcade-gaps.md, report 2): a shipped Darwin module would flip every
|
|
1071
|
-
// `canImport(Darwin)` branch in every dependency.
|
|
1072
|
-
const UNPROVIDED_PLATFORM_MODULES: Record<string, string> = {
|
|
1073
|
-
Darwin:
|
|
1074
|
-
'Peach compiles for WebAssembly, which has no Darwin; C library names come through Foundation',
|
|
1075
|
-
MachO: 'Peach compiles for WebAssembly, which has no Mach-O images',
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
1294
|
// the frameworks the iOS simulator SDK ships, so a report can say which
|
|
1079
1295
|
// missing modules are Apple's on any host, linux included. regenerated by
|
|
1080
1296
|
// scripts/ios-sdk-frameworks.ts.
|
|
@@ -1099,21 +1315,14 @@ async function missingModulesMessage(
|
|
|
1099
1315
|
] as const
|
|
1100
1316
|
}),
|
|
1101
1317
|
...[...missing.keys()].flatMap((name) =>
|
|
1102
|
-
|
|
1318
|
+
IOS_SDK_FRAMEWORKS.has(name)
|
|
1103
1319
|
? [
|
|
1104
1320
|
[
|
|
1105
1321
|
name,
|
|
1106
|
-
{ source: 'the iOS SDK', reason:
|
|
1322
|
+
{ source: 'the iOS SDK', reason: 'a framework Peach does not provide' },
|
|
1107
1323
|
] as const,
|
|
1108
1324
|
]
|
|
1109
|
-
:
|
|
1110
|
-
? [
|
|
1111
|
-
[
|
|
1112
|
-
name,
|
|
1113
|
-
{ source: 'the iOS SDK', reason: 'a framework Peach does not provide' },
|
|
1114
|
-
] as const,
|
|
1115
|
-
]
|
|
1116
|
-
: [],
|
|
1325
|
+
: [],
|
|
1117
1326
|
),
|
|
1118
1327
|
...(layout?.packages.modules ?? []),
|
|
1119
1328
|
...(layout?.packages.unavailable ?? []),
|
|
@@ -1123,9 +1332,7 @@ async function missingModulesMessage(
|
|
|
1123
1332
|
// such as FirebaseCore ships inside _FirebaseCore with no target of its
|
|
1124
1333
|
// own. the archives are read only for a module the sdk does not explain.
|
|
1125
1334
|
const packaged = new Set(
|
|
1126
|
-
[...missing.keys()].filter(
|
|
1127
|
-
(name) => !UNPROVIDED_PLATFORM_MODULES[name] && !IOS_SDK_FRAMEWORKS.has(name),
|
|
1128
|
-
),
|
|
1335
|
+
[...missing.keys()].filter((name) => !IOS_SDK_FRAMEWORKS.has(name)),
|
|
1129
1336
|
)
|
|
1130
1337
|
if (packaged.size > 0)
|
|
1131
1338
|
await Promise.all(
|
|
@@ -1209,7 +1416,9 @@ async function compileRemote(
|
|
|
1209
1416
|
submit,
|
|
1210
1417
|
{
|
|
1211
1418
|
files: snapshot.files,
|
|
1419
|
+
metalSources: snapshot.resources.metalUploads,
|
|
1212
1420
|
resourcePaths: snapshot.resourcePaths,
|
|
1421
|
+
resourceBundles: snapshot.bundleFiles.bundles,
|
|
1213
1422
|
resources: snapshot.bundleFiles.files,
|
|
1214
1423
|
images: snapshot.resources.images,
|
|
1215
1424
|
entry: snapshot.entry,
|
|
@@ -1361,13 +1570,18 @@ export async function swiftPackageMetadata(
|
|
|
1361
1570
|
hash: artifact.hash,
|
|
1362
1571
|
icuUrl: icuUrl(origin, artifact),
|
|
1363
1572
|
rootId: `${packageName}/${entry}`,
|
|
1364
|
-
resources:
|
|
1365
|
-
Object.entries(resources.table).map(([name, image]) => [
|
|
1366
|
-
name,
|
|
1367
|
-
{ ...image, uri: `${origin}${image.uri}` },
|
|
1368
|
-
]),
|
|
1369
|
-
),
|
|
1573
|
+
resources: resolveSwiftImageResourceUrls(resources.table, origin),
|
|
1370
1574
|
bundleFiles: bundleFiles.files,
|
|
1575
|
+
...(Object.keys(resources.metalSources).length === 0
|
|
1576
|
+
? {}
|
|
1577
|
+
: {
|
|
1578
|
+
metalSources: Object.fromEntries(
|
|
1579
|
+
Object.entries(resources.metalSources).map(([file, source]) => [
|
|
1580
|
+
file,
|
|
1581
|
+
{ ...source, url: `${origin}${source.url}` },
|
|
1582
|
+
]),
|
|
1583
|
+
),
|
|
1584
|
+
}),
|
|
1371
1585
|
colors: resources.colors,
|
|
1372
1586
|
symbols: resources.symbols,
|
|
1373
1587
|
native: artifact.package.native
|
|
@@ -1375,6 +1589,7 @@ export async function swiftPackageMetadata(
|
|
|
1375
1589
|
packageId: artifact.package.native.packageId,
|
|
1376
1590
|
contractHash: artifact.package.native.hash,
|
|
1377
1591
|
modules: artifact.package.native.modules,
|
|
1592
|
+
views: Object.keys(artifact.package.native.views),
|
|
1378
1593
|
defaultView: mains.length === 1,
|
|
1379
1594
|
}
|
|
1380
1595
|
: undefined,
|