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
|
@@ -448,55 +448,27 @@ export async function discoverListeningPorts(
|
|
|
448
448
|
return processes.map((p) => p.port)
|
|
449
449
|
}
|
|
450
450
|
|
|
451
|
-
/**
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
|
|
455
|
-
* so the local address is the 4th column with a DOT before the port (which is
|
|
456
|
-
* what keeps port 8137 from matching a row for 18137), and the owner is the
|
|
457
|
-
* only token shaped "<name>:<pid>".
|
|
458
|
-
*
|
|
459
|
-
* exported because this column layout is the fragile part and a child process
|
|
460
|
-
* cannot exercise it under bun's test runner, which hands back empty stdout. */
|
|
461
|
-
export function pidFromNetstat(stdout: string, port: number): number | null {
|
|
462
|
-
for (const line of stdout.split('\n')) {
|
|
463
|
-
if (!line.includes('LISTEN')) continue
|
|
464
|
-
const parts = line.trim().split(/\s+/)
|
|
465
|
-
if (!parts[3]?.endsWith(`.${port}`)) continue
|
|
466
|
-
for (const token of parts) {
|
|
467
|
-
const owner = token.match(/^\S+:(\d+)$/)
|
|
468
|
-
if (owner) {
|
|
469
|
-
const pid = Number(owner[1])
|
|
470
|
-
if (pid > 0) return pid
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
return null
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
/** resolve the pid of the process listening on one local port.
|
|
478
|
-
*
|
|
479
|
-
* `lsof` walks every descriptor of every process, which measures 2-4s on a
|
|
480
|
-
* loaded machine — longer than any timeout worth giving it, so
|
|
481
|
-
* `discoverListeningProcesses` above degrades to its pid-less port list
|
|
482
|
-
* exactly when the machine is busy. netstat (macOS/BSD) and ss (linux) read
|
|
483
|
-
* the kernel socket table instead and answer in well under a second, and both
|
|
484
|
-
* carry the owning pid. use this whenever the question is "who owns this one
|
|
485
|
-
* port"; `discoverListeningProcesses` answers the different question of what
|
|
486
|
-
* is listening at all. */
|
|
451
|
+
/** resolve the pid listening on one local port without scanning unrelated fds.
|
|
452
|
+
* macOS netstat can return empty stdout to child processes, so resolve its
|
|
453
|
+
* listener through the targeted lsof query. Linux exposes ownership through ss.
|
|
454
|
+
*/
|
|
487
455
|
export async function resolveListeningPid(port: number): Promise<number | null> {
|
|
488
456
|
if (!Number.isInteger(port) || port <= 0) return null
|
|
489
457
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
458
|
+
if (process.platform === 'darwin') {
|
|
459
|
+
try {
|
|
460
|
+
const { stdout } = await execGuarded(
|
|
461
|
+
`lsof -nP -a -iTCP:${port} -sTCP:LISTEN -t 2>/dev/null`,
|
|
462
|
+
8000,
|
|
463
|
+
)
|
|
464
|
+
const pids = [...new Set(stdout.trim().split(/\s+/).map(Number))]
|
|
465
|
+
return pids.length === 1 && Number.isInteger(pids[0]) && pids[0]! > 0
|
|
466
|
+
? pids[0]!
|
|
467
|
+
: null
|
|
468
|
+
} catch {
|
|
469
|
+
return null
|
|
470
|
+
}
|
|
471
|
+
}
|
|
500
472
|
|
|
501
473
|
// linux ss: 'LISTEN 0 511 0.0.0.0:8081 0.0.0.0:* users:(("node",pid=1234,fd=5))'
|
|
502
474
|
try {
|
|
@@ -846,7 +818,7 @@ async function fetchManifestEnrichment(
|
|
|
846
818
|
}
|
|
847
819
|
|
|
848
820
|
// ports confirmed to be running a non-sootsim dev server — safe to skip the
|
|
849
|
-
// /
|
|
821
|
+
// /__peachsim/ probe on subsequent scans. cleared when the port disappears from the
|
|
850
822
|
// listening set (process restarted, could now be a different server).
|
|
851
823
|
const knownNonPatched = new Set<number>()
|
|
852
824
|
|
|
@@ -868,7 +840,7 @@ const knownOne = new Set<number>()
|
|
|
868
840
|
// fire signature probes in waves and pick the best match by precedence:
|
|
869
841
|
// 1. expo manifest (JSON manifest at /)
|
|
870
842
|
// 2. metro/expo (packager-status:running on /status)
|
|
871
|
-
// 3. sootsim-patched (/
|
|
843
|
+
// 3. sootsim-patched (/__peachsim/)
|
|
872
844
|
// 4. one/vxrn (HEAD on /node_modules/one/metro-entry.bundle) — only
|
|
873
845
|
// fires as a true last resort; on expo apps this probe
|
|
874
846
|
// crashes metro by triggering HmrServer.registerEntryPoint
|
|
@@ -905,21 +877,75 @@ export async function probePort(
|
|
|
905
877
|
const onePath = `/node_modules/one/metro-entry.bundle?platform=ios&dev=true`
|
|
906
878
|
|
|
907
879
|
// wave 1 — safe parallel probes. none of these mutate metro state.
|
|
908
|
-
const [sootsimRes, statusRes, manifestRes, expoRes, swiftRes] =
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
880
|
+
const [sootsimRes, statusRes, manifestRes, expoRes, swiftRes, oneScanRes] =
|
|
881
|
+
await Promise.all([
|
|
882
|
+
knownNonPatched.has(port)
|
|
883
|
+
? Promise.resolve(null)
|
|
884
|
+
: httpGet(probeHostname, port, '/__peachsim/'),
|
|
885
|
+
httpGet(probeHostname, port, '/status'),
|
|
886
|
+
knownOne.has(port)
|
|
887
|
+
? Promise.resolve(null)
|
|
888
|
+
: httpGet(probeHostname, port, '/', 'GET', MANIFEST_TIMEOUT_MS, {
|
|
889
|
+
'expo-platform': 'ios',
|
|
890
|
+
}),
|
|
891
|
+
knownNonExpo.has(port)
|
|
892
|
+
? Promise.resolve(null)
|
|
893
|
+
: httpGet(probeHostname, port, '/_expo/status'),
|
|
894
|
+
httpGet(probeHostname, port, SWIFT_DISCOVERY_PATH),
|
|
895
|
+
httpGet(probeHostname, port, '/__server-scan', 'GET', MANIFEST_TIMEOUT_MS),
|
|
896
|
+
])
|
|
897
|
+
|
|
898
|
+
// the One plugin advertises its exact native entry, including replacement
|
|
899
|
+
// identity. native.app's Expo Go manifest can instead advertise index.bundle.
|
|
900
|
+
const oneScan =
|
|
901
|
+
oneScanRes?.statusCode === 200 ? safeParseManifest(oneScanRes.body) : null
|
|
902
|
+
if (Array.isArray(oneScan)) {
|
|
903
|
+
for (const entry of oneScan) {
|
|
904
|
+
if (
|
|
905
|
+
!entry ||
|
|
906
|
+
typeof entry !== 'object' ||
|
|
907
|
+
entry.framework !== 'one' ||
|
|
908
|
+
entry.port !== port ||
|
|
909
|
+
typeof entry.bundleUrl !== 'string'
|
|
910
|
+
)
|
|
911
|
+
continue
|
|
912
|
+
let bundle: URL
|
|
913
|
+
try {
|
|
914
|
+
bundle = new URL(entry.bundleUrl)
|
|
915
|
+
} catch {
|
|
916
|
+
continue
|
|
917
|
+
}
|
|
918
|
+
if (
|
|
919
|
+
bundle.protocol !== 'http:' ||
|
|
920
|
+
!isLoopbackHost(bundle.hostname) ||
|
|
921
|
+
bundle.port !== String(port) ||
|
|
922
|
+
!bundle.pathname.endsWith('/one/metro-entry.bundle')
|
|
923
|
+
)
|
|
924
|
+
continue
|
|
925
|
+
knownOne.add(port)
|
|
926
|
+
return enrichWithManifest(
|
|
927
|
+
applyManifest(
|
|
928
|
+
{
|
|
929
|
+
port,
|
|
930
|
+
framework: 'one',
|
|
931
|
+
bundleUrl: withRuntimeConfig(
|
|
932
|
+
port,
|
|
933
|
+
alignLoopbackBundleUrlWithProbe(
|
|
934
|
+
bundle.href,
|
|
935
|
+
buildLoopbackProbeBaseUrl('http:', probeHostname, port),
|
|
936
|
+
),
|
|
937
|
+
owner.cwd,
|
|
938
|
+
),
|
|
939
|
+
lastSeen: Date.now(),
|
|
940
|
+
...owner,
|
|
941
|
+
},
|
|
942
|
+
manifestRes,
|
|
943
|
+
buildIconProxyUrl,
|
|
944
|
+
),
|
|
945
|
+
buildIconProxyUrl,
|
|
946
|
+
)
|
|
947
|
+
}
|
|
948
|
+
}
|
|
923
949
|
|
|
924
950
|
const swift =
|
|
925
951
|
swiftRes?.statusCode === 200
|
|
@@ -1043,7 +1069,7 @@ export async function probePort(
|
|
|
1043
1069
|
)
|
|
1044
1070
|
}
|
|
1045
1071
|
|
|
1046
|
-
// patched sootsim — fallback for legacy /
|
|
1072
|
+
// patched sootsim — fallback for legacy /__peachsim/ patched servers. also
|
|
1047
1073
|
// checked before the one HEAD for the same reason.
|
|
1048
1074
|
if (
|
|
1049
1075
|
sootsimRes &&
|
|
@@ -1058,7 +1084,7 @@ export async function probePort(
|
|
|
1058
1084
|
framework: 'one',
|
|
1059
1085
|
bundleUrl: withRuntimeConfig(
|
|
1060
1086
|
port,
|
|
1061
|
-
`${buildLoopbackProbeBaseUrl('http:', probeHostname, port)}/
|
|
1087
|
+
`${buildLoopbackProbeBaseUrl('http:', probeHostname, port)}/__peachsim/bundle.js`,
|
|
1062
1088
|
owner.cwd,
|
|
1063
1089
|
),
|
|
1064
1090
|
hmrUrl: `${buildLoopbackProbeBaseUrl('ws:', probeHostname, port)}/hot`,
|
|
@@ -1296,7 +1322,7 @@ export async function scanDevServers(
|
|
|
1296
1322
|
}
|
|
1297
1323
|
// pid changed or cache expired — drop any endpoint-specific verdicts so
|
|
1298
1324
|
// the re-probe starts from scratch. otherwise a restarted process that
|
|
1299
|
-
// swapped frameworks keeps the old skip-/
|
|
1325
|
+
// swapped frameworks keeps the old skip-/__peachsim/ or skip-/_expo/status
|
|
1300
1326
|
// decisions, and the scanner never discovers the new server.
|
|
1301
1327
|
if (cached && cached.pid !== pid) {
|
|
1302
1328
|
knownNonPatched.delete(port)
|
package/skills/contrast/SKILL.md
CHANGED
|
@@ -101,8 +101,8 @@ skills for working with the Peach native preview engine:
|
|
|
101
101
|
|
|
102
102
|
| skill | description |
|
|
103
103
|
| --- | --- |
|
|
104
|
-
| `/peach-debug` | Debug rendering, animation, gesture, performance, and accessibility issues in a React Native app
|
|
105
|
-
| `/peach-perf` | Optimize Peach engine and app performance
|
|
104
|
+
| `/peach-debug` | Debug rendering, animation, gesture, performance, and accessibility issues in a React Native app under Peach. Use when an animation janks, snaps, or stalls, a gesture misbehaves, scrolling drops frames, the tree or props look wrong, or a screen reader cannot reach something. Use the peach CLI first. |
|
|
105
|
+
| `/peach-perf` | Optimize Peach engine and app performance: scroll jank, dropped frames, slow animation, idle CPU, memory growth, and lag under load. Covers measuring on the right thread, proving perf tiers engage via counters, a CPU-contention harness, and perf machinery. For debugging load peach-debug first. |
|
|
106
106
|
| `/peach-setup` | Get Peach connected to your React Native app with no project setup |
|
|
107
107
|
| `/peach-test` | Run automated tests against your React Native app under Peach with Maestro YAML or Detox/Jest |
|
|
108
108
|
| `/peach-visual` | Pixel-level rendering comparison between Peach and native iOS — fonts, gradients, shadows, image fidelity |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: peach-debug
|
|
3
3
|
model: sm
|
|
4
|
-
description: Debug rendering, animation, gesture, performance, and accessibility issues in a React Native app
|
|
4
|
+
description: Debug rendering, animation, gesture, performance, and accessibility issues in a React Native app under Peach. Use when an animation janks, snaps, or stalls, a gesture misbehaves, scrolling drops frames, the tree or props look wrong, or a screen reader cannot reach something. Use the peach CLI first.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Peach debug
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: peach-perf
|
|
3
3
|
model: sm
|
|
4
|
-
description: Optimize Peach engine and app performance
|
|
4
|
+
description: Optimize Peach engine and app performance: scroll jank, dropped frames, slow animation, idle CPU, memory growth, and lag under load. Covers measuring on the right thread, proving perf tiers engage via counters, a CPU-contention harness, and perf machinery. For debugging load peach-debug first.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Peach performance
|
|
@@ -56,7 +56,8 @@ debugging or `/peach-test` for writing tests.
|
|
|
56
56
|
`--new`, `--profile`, and `--ephemeral` create another isolated browser
|
|
57
57
|
tree. use them only when separate storage or a genuinely concurrent sim is
|
|
58
58
|
required. repeated new trees consume enough memory and CPU to starve other
|
|
59
|
-
work on a shared machine.
|
|
59
|
+
work on a shared machine. `--ephemeral` also boots on default settings and
|
|
60
|
+
keeps its setting changes to itself, so use it for proof captures.
|
|
60
61
|
- **pin the sim before driving it.** `peach open` records the new sim for the
|
|
61
62
|
current CLI identity. read its id and pin it explicitly before a longer flow:
|
|
62
63
|
|
|
@@ -39,6 +39,14 @@ Do not invent a third runner for how a Maestro flow was authored.
|
|
|
39
39
|
- **pin a sim before running a suite.** parallel CI jobs colliding
|
|
40
40
|
on the default bridge port is the #1 flake source. pass `--port` in
|
|
41
41
|
CI and `peach use <id>` locally.
|
|
42
|
+
- **admit a bounded stack and flow together.** if your environment requires
|
|
43
|
+
resource admission, keep stack startup, readiness, sim opening and pinning,
|
|
44
|
+
the flow, and cleanup of your owned stack in one admitted process group.
|
|
45
|
+
A stack started in an admitted background command can hold the slot that a
|
|
46
|
+
later tool call needs for the flow. Nested commands must inherit the real
|
|
47
|
+
admission; never set admission flags by hand. Before the flow, confirm
|
|
48
|
+
`peach describe --sim <id>` returns a tree: a saved sim id does not prove
|
|
49
|
+
the connection survived the wait.
|
|
42
50
|
- **every flow ends with an assert, not a screenshot.** a screenshot
|
|
43
51
|
passes as long as the flow didn't throw. `assertVisible` (or
|
|
44
52
|
`expect(...).toBeVisible()`) actually verifies the happy path.
|
|
@@ -4,6 +4,46 @@ export interface SwiftImageSource {
|
|
|
4
4
|
scale: number
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
// the scale variants stay available until the runtime knows its device.
|
|
8
|
+
export type SwiftImageVariants = SwiftImageSource[]
|
|
9
|
+
|
|
10
|
+
export function isSwiftImageVariants(value: unknown): value is SwiftImageVariants {
|
|
11
|
+
return (
|
|
12
|
+
Array.isArray(value) &&
|
|
13
|
+
value.length > 0 &&
|
|
14
|
+
value.every(
|
|
15
|
+
(image) =>
|
|
16
|
+
typeof image === 'object' &&
|
|
17
|
+
image !== null &&
|
|
18
|
+
typeof image.uri === 'string' &&
|
|
19
|
+
typeof image.scale === 'number' &&
|
|
20
|
+
Number.isFinite(image.scale) &&
|
|
21
|
+
image.scale > 0,
|
|
22
|
+
)
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// react native's asset scale rule, shared by metro and native catalog images.
|
|
27
|
+
export function assetScaleForDevice(scales: readonly number[], target: number): number {
|
|
28
|
+
for (const scale of scales) if (scale >= target) return scale
|
|
29
|
+
return scales[scales.length - 1] ?? 1
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function scaledImageSource(
|
|
33
|
+
variants: SwiftImageVariants | undefined,
|
|
34
|
+
deviceScale: number,
|
|
35
|
+
): SwiftImageSource | undefined {
|
|
36
|
+
if (!variants) return undefined
|
|
37
|
+
const scale = assetScaleForDevice(
|
|
38
|
+
variants.map((image) => image.scale),
|
|
39
|
+
deviceScale,
|
|
40
|
+
)
|
|
41
|
+
return variants.find((image) => image.scale === scale)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// relative bundle path to the asset names owned by that bundle; '.' is main.
|
|
45
|
+
export type SwiftImageResources = Record<string, Record<string, SwiftImageVariants>>
|
|
46
|
+
|
|
7
47
|
// an app catalog color resolves by appearance or names a system color.
|
|
8
48
|
export type AppCatalogColor = { light: string; dark: string } | { system: string }
|
|
9
49
|
|
|
@@ -11,6 +51,7 @@ export type AppCatalogColor = { light: string; dark: string } | { system: string
|
|
|
11
51
|
export interface SfSymbolImageDrawing {
|
|
12
52
|
referencePointSize: number
|
|
13
53
|
basePointSize: number
|
|
54
|
+
baselineOffsetUnrounded: number
|
|
14
55
|
referenceCanvasSize: readonly [number, number]
|
|
15
56
|
insets: readonly [number, number, number, number]
|
|
16
57
|
layers: readonly { d: string; opacity: number; eraser: boolean }[]
|
|
@@ -26,8 +67,9 @@ export function sfSymbolImageDimensions(
|
|
|
26
67
|
scale: number,
|
|
27
68
|
) {
|
|
28
69
|
const glyphScale = (pointSize * scale) / drawing.referencePointSize
|
|
70
|
+
// negative alignment bearings do not become negative UIImage content padding.
|
|
29
71
|
const insets = drawing.insets.map((inset) =>
|
|
30
|
-
Math.round((inset * pointSize * scale) / drawing.basePointSize),
|
|
72
|
+
Math.max(0, Math.round((inset * pointSize * scale) / drawing.basePointSize)),
|
|
31
73
|
)
|
|
32
74
|
return {
|
|
33
75
|
glyphScale,
|
|
@@ -64,6 +64,17 @@ function optionalNumber(
|
|
|
64
64
|
: numberValue(record[key], `${path}.${key}`)
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
function optionalPointerId(
|
|
68
|
+
record: Record<string, unknown>,
|
|
69
|
+
path: string,
|
|
70
|
+
): number | undefined {
|
|
71
|
+
const pointerId = optionalNumber(record, 'pointerId', path)
|
|
72
|
+
if (pointerId !== undefined && !Number.isSafeInteger(pointerId)) {
|
|
73
|
+
validationFailure(`${path}.pointerId`, 'must be a safe integer')
|
|
74
|
+
}
|
|
75
|
+
return pointerId
|
|
76
|
+
}
|
|
77
|
+
|
|
67
78
|
function optionalBoolean(
|
|
68
79
|
record: Record<string, unknown>,
|
|
69
80
|
key: string,
|
|
@@ -96,7 +107,7 @@ export function parsePerformStep(value: unknown, index: number): SimPerformStep
|
|
|
96
107
|
case 'touchDown':
|
|
97
108
|
case 'touchMove':
|
|
98
109
|
case 'touchUp': {
|
|
99
|
-
const pointerId =
|
|
110
|
+
const pointerId = optionalPointerId(step, path)
|
|
100
111
|
return {
|
|
101
112
|
type,
|
|
102
113
|
x: numberValue(step.x, `${path}.x`),
|
|
@@ -105,7 +116,7 @@ export function parsePerformStep(value: unknown, index: number): SimPerformStep
|
|
|
105
116
|
}
|
|
106
117
|
}
|
|
107
118
|
case 'touchCancel': {
|
|
108
|
-
const pointerId =
|
|
119
|
+
const pointerId = optionalPointerId(step, path)
|
|
109
120
|
return { type, ...(pointerId === undefined ? {} : { pointerId }) }
|
|
110
121
|
}
|
|
111
122
|
case 'tap':
|
|
@@ -282,38 +293,54 @@ export function parsePerformStep(value: unknown, index: number): SimPerformStep
|
|
|
282
293
|
}
|
|
283
294
|
}
|
|
284
295
|
|
|
285
|
-
//
|
|
286
|
-
//
|
|
287
|
-
|
|
288
|
-
// touchUp or touchCancel in the same batch is rejected before anything runs.
|
|
289
|
-
export function findUnbalancedTouchDown(
|
|
296
|
+
// every batch is self-contained, so a pointer must be opened before it moves
|
|
297
|
+
// or closes and every opened pointer must close before the batch ends.
|
|
298
|
+
export function findInvalidPointerSequence(
|
|
290
299
|
steps: readonly SimPerformStep[],
|
|
291
|
-
): { index: number;
|
|
300
|
+
): { index: number; error: string } | null {
|
|
292
301
|
const open = new Map<number, number>()
|
|
293
|
-
const
|
|
302
|
+
for (const [index, step] of steps.entries()) {
|
|
294
303
|
if (
|
|
295
304
|
step.type !== 'touchDown' &&
|
|
296
305
|
step.type !== 'touchMove' &&
|
|
297
306
|
step.type !== 'touchUp' &&
|
|
298
307
|
step.type !== 'touchCancel'
|
|
299
308
|
) {
|
|
300
|
-
|
|
309
|
+
continue
|
|
301
310
|
}
|
|
302
311
|
const pointerId = step.pointerId ?? 999
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
312
|
+
if (!Number.isSafeInteger(pointerId)) {
|
|
313
|
+
return {
|
|
314
|
+
index,
|
|
315
|
+
error: `perform.steps[${index}] (${step.type}) has an invalid pointer id`,
|
|
316
|
+
}
|
|
317
|
+
}
|
|
306
318
|
if (step.type === 'touchDown') {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
319
|
+
if (open.has(pointerId)) {
|
|
320
|
+
return {
|
|
321
|
+
index,
|
|
322
|
+
error: `perform.steps[${index}] (touchDown) starts pointer ${pointerId} before its previous touchUp or touchCancel`,
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
open.set(pointerId, index)
|
|
326
|
+
continue
|
|
327
|
+
}
|
|
328
|
+
if (!open.has(pointerId)) {
|
|
329
|
+
return {
|
|
330
|
+
index,
|
|
331
|
+
error: `perform.steps[${index}] (${step.type}) has no matching touchDown for pointer ${pointerId}`,
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
if (step.type === 'touchUp' || step.type === 'touchCancel') {
|
|
335
|
+
open.delete(pointerId)
|
|
312
336
|
}
|
|
313
337
|
}
|
|
314
338
|
const next = open.entries().next()
|
|
315
339
|
if (next.done) return null
|
|
316
|
-
return {
|
|
340
|
+
return {
|
|
341
|
+
index: next.value[1],
|
|
342
|
+
error: `perform.steps[${next.value[1]}] (touchDown) has no matching touchUp or touchCancel for pointer ${next.value[0]}`,
|
|
343
|
+
}
|
|
317
344
|
}
|
|
318
345
|
|
|
319
346
|
export function parseStateOptions(value: unknown): SimStateOptions {
|
package/src/bridge-contract.ts
CHANGED
|
@@ -374,7 +374,6 @@ export const SEMANTIC_READY_CONTENT_NODE_FLOOR = 100
|
|
|
374
374
|
export const SEMANTIC_READY_NODE_STABLE_MS = 750
|
|
375
375
|
export const SEMANTIC_READY_POLL_MS = 150
|
|
376
376
|
|
|
377
|
-
export const PUBLIC_NO_NETWORK_MARKER = 'public Peach Cloud simulators have no network'
|
|
378
377
|
export const HEADLESS_TENANT_FETCH_HUNG_MARKER = 'headless tenant fetch hung'
|
|
379
378
|
|
|
380
379
|
export function readyProbeHasContent(
|