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/vite.d.ts
CHANGED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import { createRequire } from 'node:module'
|
|
3
|
+
import { Worker } from 'node:worker_threads'
|
|
4
|
+
import { rollup } from 'rollup'
|
|
5
|
+
import { isRecord } from './is-record'
|
|
6
|
+
|
|
7
|
+
const require = createRequire(import.meta.url)
|
|
8
|
+
const systemRuntime = fs.readFileSync(require.resolve('systemjs/dist/s.min.js'), 'utf8')
|
|
9
|
+
const minifierModule = require.resolve('terser')
|
|
10
|
+
type MinifiedWorkerChunk = { code: string; map: string }
|
|
11
|
+
const minifierWorker = `
|
|
12
|
+
const { parentPort, workerData } = require('node:worker_threads');
|
|
13
|
+
const { minify } = require(workerData.module);
|
|
14
|
+
parentPort.on('message', async ({ code, map, keepNames }) => {
|
|
15
|
+
try {
|
|
16
|
+
const result = await minify(code, {
|
|
17
|
+
module: true,
|
|
18
|
+
compress: { passes: 2 },
|
|
19
|
+
mangle: true,
|
|
20
|
+
keep_fnames: keepNames,
|
|
21
|
+
keep_classnames: keepNames,
|
|
22
|
+
sourceMap: { content: map },
|
|
23
|
+
});
|
|
24
|
+
parentPort.postMessage({ code: result.code, map: result.map });
|
|
25
|
+
} catch (error) {
|
|
26
|
+
parentPort.postMessage({ error: error instanceof Error ? error.message : String(error) });
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
`
|
|
30
|
+
type MinifierJob = {
|
|
31
|
+
code: string
|
|
32
|
+
map: string
|
|
33
|
+
keepNames: boolean
|
|
34
|
+
resolve: (result: MinifiedWorkerChunk) => void
|
|
35
|
+
reject: (error: Error) => void
|
|
36
|
+
}
|
|
37
|
+
type MinifierSlot = {
|
|
38
|
+
worker: Worker
|
|
39
|
+
job: MinifierJob | undefined
|
|
40
|
+
failure: Error | undefined
|
|
41
|
+
}
|
|
42
|
+
// share two reusable isolates across every worker build in this vite process.
|
|
43
|
+
const minifiers = new Set<MinifierSlot>()
|
|
44
|
+
const pendingMinifiers: MinifierJob[] = []
|
|
45
|
+
|
|
46
|
+
function runMinifiers() {
|
|
47
|
+
while (pendingMinifiers.length) {
|
|
48
|
+
let slot = [...minifiers].find((candidate) => !candidate.job && !candidate.failure)
|
|
49
|
+
if (!slot) {
|
|
50
|
+
if (minifiers.size === 2) return
|
|
51
|
+
let worker: Worker
|
|
52
|
+
try {
|
|
53
|
+
worker = new Worker(minifierWorker, {
|
|
54
|
+
eval: true,
|
|
55
|
+
execArgv: [],
|
|
56
|
+
workerData: { module: minifierModule },
|
|
57
|
+
})
|
|
58
|
+
} catch (error) {
|
|
59
|
+
pendingMinifiers
|
|
60
|
+
.shift()
|
|
61
|
+
?.reject(error instanceof Error ? error : new Error(String(error)))
|
|
62
|
+
continue
|
|
63
|
+
}
|
|
64
|
+
const created: MinifierSlot = { worker, job: undefined, failure: undefined }
|
|
65
|
+
minifiers.add(created)
|
|
66
|
+
worker.on('message', (message: unknown) => {
|
|
67
|
+
if (created.failure) return
|
|
68
|
+
const job = created.job
|
|
69
|
+
let result: MinifiedWorkerChunk | Error
|
|
70
|
+
if (isRecord(message) && typeof message.error === 'string') {
|
|
71
|
+
result = new Error(message.error)
|
|
72
|
+
} else if (
|
|
73
|
+
isRecord(message) &&
|
|
74
|
+
typeof message.code === 'string' &&
|
|
75
|
+
message.code &&
|
|
76
|
+
typeof message.map === 'string'
|
|
77
|
+
) {
|
|
78
|
+
result = { code: message.code, map: message.map }
|
|
79
|
+
} else {
|
|
80
|
+
created.failure = new Error(
|
|
81
|
+
'worker minification produced no code or source map',
|
|
82
|
+
)
|
|
83
|
+
void worker.terminate()
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
if (!job) {
|
|
87
|
+
created.failure = new Error('worker minifier returned an unexpected result')
|
|
88
|
+
void worker.terminate()
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
created.job = undefined
|
|
92
|
+
// idle isolates must not keep a completed build process alive.
|
|
93
|
+
worker.unref()
|
|
94
|
+
if (result instanceof Error) job.reject(result)
|
|
95
|
+
else job.resolve(result)
|
|
96
|
+
runMinifiers()
|
|
97
|
+
})
|
|
98
|
+
worker.on('error', (error) => {
|
|
99
|
+
created.failure = error instanceof Error ? error : new Error(String(error))
|
|
100
|
+
})
|
|
101
|
+
// a failed isolate owns its slot until its thread has actually exited.
|
|
102
|
+
worker.once('exit', (status) => {
|
|
103
|
+
minifiers.delete(created)
|
|
104
|
+
created.job?.reject(
|
|
105
|
+
created.failure ??
|
|
106
|
+
new Error(`worker minifier exited ${status} without a result`),
|
|
107
|
+
)
|
|
108
|
+
runMinifiers()
|
|
109
|
+
})
|
|
110
|
+
slot = created
|
|
111
|
+
}
|
|
112
|
+
const job = pendingMinifiers.shift()
|
|
113
|
+
if (!job) return
|
|
114
|
+
slot.job = job
|
|
115
|
+
slot.worker.ref()
|
|
116
|
+
try {
|
|
117
|
+
slot.worker.postMessage({ code: job.code, map: job.map, keepNames: job.keepNames })
|
|
118
|
+
} catch (error) {
|
|
119
|
+
slot.failure = error instanceof Error ? error : new Error(String(error))
|
|
120
|
+
void slot.worker.terminate()
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// systemjs owns linking, live exports, cycles and evaluation identity. its
|
|
126
|
+
// instantiate hook uses the same fetch and script evaluation in every worker
|
|
127
|
+
// host, including public JavaScriptCore. each fetch captures its own anonymous
|
|
128
|
+
// registration so concurrent chunks cannot consume one another's declarations.
|
|
129
|
+
const workerLoader = `
|
|
130
|
+
// chunk fetching yields before the worker's message listener is installed.
|
|
131
|
+
// retain the payloads and transferred ports until linking ends. intercepted
|
|
132
|
+
// events keep their immediate-propagation flag, so replay fresh native events.
|
|
133
|
+
const pendingWorkerMessages = [];
|
|
134
|
+
const WorkerMessageEvent = globalThis.MessageEvent;
|
|
135
|
+
const dispatchWorkerMessage = globalThis.dispatchEvent.bind(globalThis);
|
|
136
|
+
const removeWorkerMessageListener = globalThis.removeEventListener.bind(globalThis);
|
|
137
|
+
function bufferWorkerMessage(event) {
|
|
138
|
+
pendingWorkerMessages.push(new WorkerMessageEvent('message', {
|
|
139
|
+
data: event.data,
|
|
140
|
+
origin: event.origin,
|
|
141
|
+
lastEventId: event.lastEventId,
|
|
142
|
+
source: event.source,
|
|
143
|
+
ports: event.ports,
|
|
144
|
+
}));
|
|
145
|
+
event.stopImmediatePropagation();
|
|
146
|
+
}
|
|
147
|
+
globalThis.addEventListener('message', bufferWorkerMessage, true);
|
|
148
|
+
const workerEntryUrl = globalThis.location.href;
|
|
149
|
+
const workerEntryRegistration = System.getRegister();
|
|
150
|
+
System.instantiate = async function(url) {
|
|
151
|
+
if (url === workerEntryUrl) return workerEntryRegistration;
|
|
152
|
+
const response = await fetch(url, { credentials: 'same-origin' });
|
|
153
|
+
if (!response.ok) throw new Error(url + ': HTTP ' + response.status);
|
|
154
|
+
let registration;
|
|
155
|
+
new Function('System', await response.text())({
|
|
156
|
+
register(dependencies, declare) { registration = [dependencies, declare]; }
|
|
157
|
+
});
|
|
158
|
+
if (!registration) throw new Error(url + ': missing worker registration');
|
|
159
|
+
return registration;
|
|
160
|
+
};
|
|
161
|
+
await System.import(workerEntryUrl);
|
|
162
|
+
removeWorkerMessageListener('message', bufferWorkerMessage, true);
|
|
163
|
+
for (const event of pendingWorkerMessages) dispatchWorkerMessage(event);
|
|
164
|
+
pendingWorkerMessages.length = 0;
|
|
165
|
+
`
|
|
166
|
+
|
|
167
|
+
export async function renderWorkerSystemChunk(
|
|
168
|
+
code: string,
|
|
169
|
+
isEntry: boolean,
|
|
170
|
+
keepNames = false,
|
|
171
|
+
) {
|
|
172
|
+
const entry = '\0peach-worker-chunk'
|
|
173
|
+
const bundle = await rollup({
|
|
174
|
+
input: entry,
|
|
175
|
+
treeshake: false,
|
|
176
|
+
plugins: [
|
|
177
|
+
{
|
|
178
|
+
name: 'peach-worker-system-chunk',
|
|
179
|
+
resolveId(id) {
|
|
180
|
+
return id === entry ? id : { id, external: true }
|
|
181
|
+
},
|
|
182
|
+
load(id) {
|
|
183
|
+
return id === entry ? code : null
|
|
184
|
+
},
|
|
185
|
+
renderDynamicImport({ targetModuleId }) {
|
|
186
|
+
// runtime-supplied URLs name ES modules outside the generated graph.
|
|
187
|
+
// generated chunk imports retain their SystemJS registration loader.
|
|
188
|
+
if (targetModuleId === null) return { left: 'import(', right: ')' }
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
})
|
|
193
|
+
let loweredCode: string
|
|
194
|
+
let loweredMap: string
|
|
195
|
+
try {
|
|
196
|
+
const { output } = await bundle.generate({
|
|
197
|
+
format: 'system',
|
|
198
|
+
sourcemap: true,
|
|
199
|
+
banner: isEntry ? systemRuntime : undefined,
|
|
200
|
+
footer: isEntry ? workerLoader : undefined,
|
|
201
|
+
})
|
|
202
|
+
const chunk = output[0]
|
|
203
|
+
if (!chunk || chunk.type !== 'chunk' || !chunk.map)
|
|
204
|
+
throw new Error('worker module lowering produced no chunk or source map')
|
|
205
|
+
loweredCode = chunk.code
|
|
206
|
+
loweredMap = chunk.map.toString()
|
|
207
|
+
} finally {
|
|
208
|
+
await bundle.close()
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return new Promise<MinifiedWorkerChunk>((resolve, reject) => {
|
|
212
|
+
pendingMinifiers.push({
|
|
213
|
+
code: loweredCode,
|
|
214
|
+
map: loweredMap,
|
|
215
|
+
keepNames,
|
|
216
|
+
resolve,
|
|
217
|
+
reject,
|
|
218
|
+
})
|
|
219
|
+
runMinifiers()
|
|
220
|
+
})
|
|
221
|
+
}
|
|
@@ -12,14 +12,14 @@ function isNode(value: unknown): value is SyntaxNode {
|
|
|
12
12
|
)
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
function childNodes(value: unknown): SyntaxNode[] {
|
|
16
|
+
return Array.isArray(value) ? value.filter(isNode) : []
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function identifierName(node: unknown): string | undefined {
|
|
20
|
+
if (!isNode(node) || node.type !== 'Identifier') return undefined
|
|
21
|
+
const name = Reflect.get(node, 'name')
|
|
22
|
+
return typeof name === 'string' ? name : undefined
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function propertyName(node: unknown): string | undefined {
|
|
@@ -28,48 +28,358 @@ function propertyName(node: unknown): string | undefined {
|
|
|
28
28
|
return typeof name === 'string' ? name : undefined
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
|
|
31
|
+
// the static name a member or property key selects. a computed identifier names a
|
|
32
|
+
// variable, not a key, so it has none.
|
|
33
|
+
function keyName(owner: SyntaxNode, key: unknown): string | undefined {
|
|
34
|
+
if (Reflect.get(owner, 'computed') === true && isNode(key) && key.type === 'Identifier')
|
|
35
|
+
return undefined
|
|
36
|
+
return propertyName(key)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// the names a binding pattern declares or an assignment target writes.
|
|
40
|
+
function patternNames(node: unknown): string[] {
|
|
41
|
+
if (!isNode(node)) return []
|
|
42
|
+
switch (node.type) {
|
|
43
|
+
case 'Identifier': {
|
|
44
|
+
const name = identifierName(node)
|
|
45
|
+
return name === undefined ? [] : [name]
|
|
46
|
+
}
|
|
47
|
+
case 'AssignmentPattern':
|
|
48
|
+
return patternNames(Reflect.get(node, 'left'))
|
|
49
|
+
case 'RestElement':
|
|
50
|
+
return patternNames(Reflect.get(node, 'argument'))
|
|
51
|
+
case 'ArrayPattern':
|
|
52
|
+
return childNodes(Reflect.get(node, 'elements')).flatMap(patternNames)
|
|
53
|
+
case 'ObjectPattern':
|
|
54
|
+
return childNodes(Reflect.get(node, 'properties')).flatMap((property) =>
|
|
55
|
+
patternNames(
|
|
56
|
+
property.type === 'Property' || property.type === 'ObjectProperty'
|
|
57
|
+
? Reflect.get(property, 'value')
|
|
58
|
+
: property,
|
|
59
|
+
),
|
|
60
|
+
)
|
|
61
|
+
default:
|
|
62
|
+
return []
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// a scope holds the names declared directly in one scope-owning node. `hoist`
|
|
67
|
+
// marks where `var` lands: a function body or the program.
|
|
68
|
+
interface Scope {
|
|
69
|
+
parent: Scope | undefined
|
|
70
|
+
hoist: boolean
|
|
71
|
+
names: Map<string, Binding>
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
type Binding =
|
|
75
|
+
| { kind: 'value'; init: SyntaxNode; scope: Scope }
|
|
76
|
+
// `key` is set when the parameter is a destructured property of that argument.
|
|
77
|
+
| { kind: 'param'; fn: SyntaxNode; index: number; key?: string }
|
|
78
|
+
| { kind: 'opaque' }
|
|
79
|
+
|
|
80
|
+
interface InitCollection {
|
|
81
|
+
// the right side of each `x.__initData = ...`, with the scope it evaluates in.
|
|
82
|
+
inits: Array<{ value: SyntaxNode; scope: Scope }>
|
|
83
|
+
// each immediately invoked function, keyed by its callee, with the call and its scope.
|
|
84
|
+
immediate: Map<SyntaxNode, { call: SyntaxNode; scope: Scope }>
|
|
85
|
+
// names written by assignment, resolved after the walk.
|
|
86
|
+
writes: Array<{ name: string; scope: Scope }>
|
|
87
|
+
// bindings written after their declaration; their value is not static.
|
|
88
|
+
reassigned: Set<Binding>
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const FUNCTION_TYPES = new Set([
|
|
92
|
+
'FunctionDeclaration',
|
|
93
|
+
'FunctionExpression',
|
|
94
|
+
'ArrowFunctionExpression',
|
|
95
|
+
])
|
|
96
|
+
const MAX_RESOLUTION_DEPTH = 32
|
|
97
|
+
|
|
98
|
+
function newScope(parent: Scope | undefined, hoist: boolean): Scope {
|
|
99
|
+
return { parent, hoist, names: new Map() }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function hoistScope(scope: Scope): Scope {
|
|
103
|
+
let current = scope
|
|
104
|
+
while (!current.hoist && current.parent) current = current.parent
|
|
105
|
+
return current
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// a second declaration of one name in one scope leaves its value order-dependent,
|
|
109
|
+
// so the name stays opaque rather than picking either declaration.
|
|
110
|
+
function declare(scope: Scope, name: string, binding: Binding): void {
|
|
111
|
+
scope.names.set(name, scope.names.has(name) ? { kind: 'opaque' } : binding)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function declareOpaque(scope: Scope, names: string[]): void {
|
|
115
|
+
for (const name of names) declare(scope, name, { kind: 'opaque' })
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function lookup(scope: Scope, name: string): Binding | undefined {
|
|
119
|
+
for (let current: Scope | undefined = scope; current; current = current.parent) {
|
|
120
|
+
const binding = current.names.get(name)
|
|
121
|
+
if (binding) return binding
|
|
122
|
+
}
|
|
123
|
+
return undefined
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// a destructured parameter binds each plain property to that key of its argument.
|
|
127
|
+
// rest elements, defaults and nested patterns stay opaque.
|
|
128
|
+
function declareParam(inner: Scope, fn: SyntaxNode, index: number, param: unknown): void {
|
|
129
|
+
const name = identifierName(param)
|
|
130
|
+
if (name !== undefined) {
|
|
131
|
+
declare(inner, name, { kind: 'param', fn, index })
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
if (!isNode(param) || param.type !== 'ObjectPattern') {
|
|
135
|
+
declareOpaque(inner, patternNames(param))
|
|
136
|
+
return
|
|
137
|
+
}
|
|
138
|
+
for (const property of childNodes(Reflect.get(param, 'properties'))) {
|
|
139
|
+
const key = keyName(property, Reflect.get(property, 'key'))
|
|
140
|
+
const value: unknown = Reflect.get(property, 'value')
|
|
141
|
+
const valueName = identifierName(value)
|
|
142
|
+
if (
|
|
143
|
+
key !== undefined &&
|
|
144
|
+
valueName !== undefined &&
|
|
145
|
+
['Property', 'ObjectProperty'].includes(property.type)
|
|
146
|
+
)
|
|
147
|
+
declare(inner, valueName, { kind: 'param', fn, index, key })
|
|
148
|
+
else
|
|
149
|
+
declareOpaque(
|
|
150
|
+
inner,
|
|
151
|
+
patternNames(property.type === 'RestElement' ? property : value),
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// the scope a node's children are visited in, after declaring the names it binds.
|
|
157
|
+
function enter(node: SyntaxNode, scope: Scope): Scope {
|
|
158
|
+
switch (node.type) {
|
|
159
|
+
case 'FunctionDeclaration':
|
|
160
|
+
case 'FunctionExpression':
|
|
161
|
+
case 'ArrowFunctionExpression': {
|
|
162
|
+
const inner = newScope(scope, true)
|
|
163
|
+
const params = Reflect.get(node, 'params')
|
|
164
|
+
if (Array.isArray(params)) {
|
|
165
|
+
params.forEach((param: unknown, index) => declareParam(inner, node, index, param))
|
|
166
|
+
}
|
|
167
|
+
const id = Reflect.get(node, 'id')
|
|
168
|
+
if (node.type === 'FunctionExpression') declareOpaque(inner, patternNames(id))
|
|
169
|
+
if (node.type === 'FunctionDeclaration') {
|
|
170
|
+
declareOpaque(scope, patternNames(id))
|
|
171
|
+
declareOpaque(hoistScope(scope), patternNames(id))
|
|
172
|
+
}
|
|
173
|
+
return inner
|
|
174
|
+
}
|
|
175
|
+
case 'BlockStatement':
|
|
176
|
+
case 'ForStatement':
|
|
177
|
+
case 'ForInStatement':
|
|
178
|
+
case 'ForOfStatement':
|
|
179
|
+
case 'SwitchStatement':
|
|
180
|
+
case 'StaticBlock':
|
|
181
|
+
return newScope(scope, false)
|
|
182
|
+
case 'CatchClause': {
|
|
183
|
+
const inner = newScope(scope, false)
|
|
184
|
+
declareOpaque(inner, patternNames(Reflect.get(node, 'param')))
|
|
185
|
+
return inner
|
|
186
|
+
}
|
|
187
|
+
case 'VariableDeclaration': {
|
|
188
|
+
const target = Reflect.get(node, 'kind') === 'var' ? hoistScope(scope) : scope
|
|
189
|
+
for (const declarator of childNodes(Reflect.get(node, 'declarations'))) {
|
|
190
|
+
const id = Reflect.get(declarator, 'id')
|
|
191
|
+
const init = Reflect.get(declarator, 'init')
|
|
192
|
+
const name = identifierName(id)
|
|
193
|
+
if (name !== undefined && isNode(init))
|
|
194
|
+
declare(target, name, { kind: 'value', init, scope })
|
|
195
|
+
else declareOpaque(target, patternNames(id))
|
|
196
|
+
}
|
|
197
|
+
return scope
|
|
198
|
+
}
|
|
199
|
+
case 'ImportDeclaration':
|
|
200
|
+
for (const specifier of childNodes(Reflect.get(node, 'specifiers')))
|
|
201
|
+
declareOpaque(scope, patternNames(Reflect.get(specifier, 'local')))
|
|
202
|
+
return scope
|
|
203
|
+
case 'ClassDeclaration':
|
|
204
|
+
declareOpaque(scope, patternNames(Reflect.get(node, 'id')))
|
|
205
|
+
return scope
|
|
206
|
+
default:
|
|
207
|
+
return scope
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function recordWrites(target: unknown, scope: Scope, collection: InitCollection): void {
|
|
212
|
+
for (const name of patternNames(target)) collection.writes.push({ name, scope })
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// facts read where they occur: init assignments, immediate calls and writes.
|
|
216
|
+
function record(node: SyntaxNode, scope: Scope, collection: InitCollection): void {
|
|
217
|
+
switch (node.type) {
|
|
218
|
+
case 'AssignmentExpression': {
|
|
219
|
+
const left = Reflect.get(node, 'left')
|
|
220
|
+
const right = Reflect.get(node, 'right')
|
|
221
|
+
if (
|
|
222
|
+
isNode(left) &&
|
|
223
|
+
left.type === 'MemberExpression' &&
|
|
224
|
+
keyName(left, Reflect.get(left, 'property')) === '__initData' &&
|
|
225
|
+
isNode(right)
|
|
226
|
+
)
|
|
227
|
+
collection.inits.push({ value: right, scope })
|
|
228
|
+
recordWrites(left, scope, collection)
|
|
229
|
+
return
|
|
230
|
+
}
|
|
231
|
+
case 'UpdateExpression':
|
|
232
|
+
recordWrites(Reflect.get(node, 'argument'), scope, collection)
|
|
233
|
+
return
|
|
234
|
+
case 'ForInStatement':
|
|
235
|
+
case 'ForOfStatement':
|
|
236
|
+
recordWrites(Reflect.get(node, 'left'), scope, collection)
|
|
237
|
+
return
|
|
238
|
+
case 'CallExpression': {
|
|
239
|
+
const callee = Reflect.get(node, 'callee')
|
|
240
|
+
if (isNode(callee) && FUNCTION_TYPES.has(callee.type))
|
|
241
|
+
collection.immediate.set(callee, { call: node, scope })
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
default:
|
|
245
|
+
return
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function visit(node: SyntaxNode, scope: Scope, collection: InitCollection): void {
|
|
250
|
+
record(node, scope, collection)
|
|
251
|
+
const inner = enter(node, scope)
|
|
252
|
+
for (const value of Object.values(node)) {
|
|
253
|
+
if (isNode(value)) visit(value, inner, collection)
|
|
254
|
+
else for (const child of childNodes(value)) visit(child, inner, collection)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function collectInitData(root: SyntaxNode): InitCollection {
|
|
259
|
+
const collection: InitCollection = {
|
|
260
|
+
inits: [],
|
|
261
|
+
immediate: new Map(),
|
|
262
|
+
writes: [],
|
|
263
|
+
reassigned: new Set(),
|
|
264
|
+
}
|
|
265
|
+
visit(root, newScope(undefined, true), collection)
|
|
266
|
+
for (const { name, scope } of collection.writes) {
|
|
267
|
+
const binding = lookup(scope, name)
|
|
268
|
+
if (binding) collection.reassigned.add(binding)
|
|
269
|
+
}
|
|
270
|
+
return collection
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// the argument an immediately invoked function passes to one parameter.
|
|
274
|
+
function immediateArgument(
|
|
275
|
+
fn: SyntaxNode,
|
|
276
|
+
index: number,
|
|
277
|
+
collection: InitCollection,
|
|
278
|
+
): { argument: unknown; scope: Scope } | undefined {
|
|
279
|
+
const immediate = collection.immediate.get(fn)
|
|
280
|
+
const args: unknown = immediate && Reflect.get(immediate.call, 'arguments')
|
|
281
|
+
if (!immediate || !Array.isArray(args)) return undefined
|
|
282
|
+
// a spread before the parameter shifts every later argument position.
|
|
283
|
+
const preceding: unknown[] = args.slice(0, index + 1)
|
|
284
|
+
if (preceding.some((arg) => isNode(arg) && arg.type === 'SpreadElement'))
|
|
285
|
+
return undefined
|
|
286
|
+
return { argument: args[index], scope: immediate.scope }
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// the value a literal holds under a static name. the last duplicate wins, as it
|
|
290
|
+
// does at run time. a spread makes the literal's keys unknown.
|
|
291
|
+
function propertyValue(object: SyntaxNode, name: string): SyntaxNode | undefined {
|
|
292
|
+
let value: SyntaxNode | undefined
|
|
293
|
+
for (const property of childNodes(Reflect.get(object, 'properties'))) {
|
|
294
|
+
if (property.type === 'SpreadElement') return undefined
|
|
295
|
+
if (!['Property', 'ObjectProperty'].includes(property.type)) continue
|
|
296
|
+
if (keyName(property, Reflect.get(property, 'key')) !== name) continue
|
|
297
|
+
const next: unknown = Reflect.get(property, 'value')
|
|
298
|
+
value = isNode(next) ? next : undefined
|
|
299
|
+
}
|
|
300
|
+
return value
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
interface ResolvedObject {
|
|
304
|
+
object: SyntaxNode
|
|
305
|
+
scope: Scope
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// the object literal under one static key of a resolved owner.
|
|
309
|
+
function resolveProperty(
|
|
310
|
+
owner: ResolvedObject | undefined,
|
|
311
|
+
name: string,
|
|
312
|
+
collection: InitCollection,
|
|
313
|
+
depth: number,
|
|
314
|
+
): ResolvedObject | undefined {
|
|
315
|
+
if (!owner) return undefined
|
|
316
|
+
const value = propertyValue(owner.object, name)
|
|
317
|
+
return value && resolveObject(value, owner.scope, collection, depth + 1)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// the object literal an expression yields, when it is statically known: a literal,
|
|
321
|
+
// a binding whose value is one, a parameter of an immediately invoked function
|
|
322
|
+
// bound to its argument (or to a key of it), or a static member of one of those.
|
|
323
|
+
function resolveObject(
|
|
324
|
+
expression: SyntaxNode,
|
|
325
|
+
scope: Scope,
|
|
326
|
+
collection: InitCollection,
|
|
327
|
+
depth: number,
|
|
328
|
+
): ResolvedObject | undefined {
|
|
329
|
+
if (depth > MAX_RESOLUTION_DEPTH) return undefined
|
|
330
|
+
if (expression.type === 'ObjectExpression') return { object: expression, scope }
|
|
331
|
+
if (expression.type === 'Identifier') {
|
|
332
|
+
const name = identifierName(expression)
|
|
333
|
+
const binding = name === undefined ? undefined : lookup(scope, name)
|
|
334
|
+
if (!binding || collection.reassigned.has(binding)) return undefined
|
|
335
|
+
if (binding.kind === 'value')
|
|
336
|
+
return resolveObject(binding.init, binding.scope, collection, depth + 1)
|
|
337
|
+
if (binding.kind === 'param') {
|
|
338
|
+
const passed = immediateArgument(binding.fn, binding.index, collection)
|
|
339
|
+
if (!passed || !isNode(passed.argument)) return undefined
|
|
340
|
+
const argument = resolveObject(passed.argument, passed.scope, collection, depth + 1)
|
|
341
|
+
return binding.key === undefined
|
|
342
|
+
? argument
|
|
343
|
+
: resolveProperty(argument, binding.key, collection, depth)
|
|
344
|
+
}
|
|
345
|
+
return undefined
|
|
346
|
+
}
|
|
347
|
+
if (expression.type === 'MemberExpression') {
|
|
348
|
+
const name = keyName(expression, Reflect.get(expression, 'property'))
|
|
349
|
+
const object: unknown = Reflect.get(expression, 'object')
|
|
350
|
+
if (name === undefined || !isNode(object)) return undefined
|
|
351
|
+
const owner = resolveObject(object, scope, collection, depth + 1)
|
|
352
|
+
return resolveProperty(owner, name, collection, depth)
|
|
353
|
+
}
|
|
354
|
+
return undefined
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// collect upstream init records by their actual __initData assignments. each
|
|
358
|
+
// assigned expression resolves lexically to an inline literal, a variable or
|
|
359
|
+
// parameter, or a member of an immediately invoked function's argument, which is
|
|
360
|
+
// how minified bundles pass their init records. babel and acorn share these shapes.
|
|
361
|
+
export function workletExecutableBodies(
|
|
362
|
+
syntax: unknown,
|
|
363
|
+
includeCompiled = false,
|
|
364
|
+
): Array<{
|
|
34
365
|
initData: SyntaxNode
|
|
35
366
|
codeProperty: SyntaxNode
|
|
36
367
|
code: string
|
|
37
368
|
}> {
|
|
38
369
|
if (!isNode(syntax)) throw new Error('peach: expected worklet syntax')
|
|
39
|
-
const
|
|
40
|
-
const initNames = new Set<string>()
|
|
370
|
+
const collection = collectInitData(syntax)
|
|
41
371
|
const objects = new Set<SyntaxNode>()
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
!isNode(left) ||
|
|
47
|
-
left.type !== 'MemberExpression' ||
|
|
48
|
-
propertyName(Reflect.get(left, 'property')) !== '__initData'
|
|
49
|
-
)
|
|
50
|
-
return
|
|
51
|
-
const right = Reflect.get(node, 'right')
|
|
52
|
-
if (!isNode(right)) return
|
|
53
|
-
if (right.type === 'ObjectExpression') objects.add(right)
|
|
54
|
-
else if (right.type === 'Identifier') {
|
|
55
|
-
const name = propertyName(right)
|
|
56
|
-
if (name) initNames.add(name)
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
walk(tree, (node) => {
|
|
60
|
-
if (node.type !== 'VariableDeclarator') return
|
|
61
|
-
const name = propertyName(Reflect.get(node, 'id'))
|
|
62
|
-
const init = Reflect.get(node, 'init')
|
|
63
|
-
if (name && initNames.has(name) && isNode(init) && init.type === 'ObjectExpression') {
|
|
64
|
-
objects.add(init)
|
|
65
|
-
}
|
|
66
|
-
})
|
|
372
|
+
for (const { value, scope } of collection.inits) {
|
|
373
|
+
const resolved = resolveObject(value, scope, collection, 0)
|
|
374
|
+
if (resolved) objects.add(resolved.object)
|
|
375
|
+
}
|
|
67
376
|
const bodies: Array<{ initData: SyntaxNode; codeProperty: SyntaxNode; code: string }> =
|
|
68
377
|
[]
|
|
69
378
|
for (const object of objects) {
|
|
70
379
|
const properties = Reflect.get(object, 'properties')
|
|
71
380
|
if (!Array.isArray(properties)) continue
|
|
72
381
|
if (
|
|
382
|
+
!includeCompiled &&
|
|
73
383
|
properties.some(
|
|
74
384
|
(property) =>
|
|
75
385
|
isNode(property) &&
|
package/src/worklets-babel.ts
CHANGED
|
@@ -93,7 +93,7 @@ function isTypescriptFile(id: string): boolean {
|
|
|
93
93
|
// normal dev rebuild changes a handful of files and replays the rest.
|
|
94
94
|
export type WorkletBodyMode = 'executable' | 'transport'
|
|
95
95
|
|
|
96
|
-
const CACHE_SCHEMA = '
|
|
96
|
+
const CACHE_SCHEMA = 'v5'
|
|
97
97
|
const CACHE_ROOT = path.resolve(
|
|
98
98
|
workspaceRoot,
|
|
99
99
|
'node_modules',
|