peachsim 0.1.658 → 0.1.659

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist-lib/agent-daemon-client.cjs +1 -1
  2. package/dist-lib/agent-events.cjs +1 -1
  3. package/dist-lib/agent-identity.cjs +1 -1
  4. package/dist-lib/agent-sessions.cjs +1 -1
  5. package/dist-lib/attached-projects.cjs +1 -1
  6. package/dist-lib/auth/shared-session.cjs +1 -1
  7. package/dist-lib/backend-origin.cjs +1 -1
  8. package/dist-lib/beta.cjs +1 -1
  9. package/dist-lib/beta.mjs +1 -1
  10. package/dist-lib/bridge-constants.cjs +1 -1
  11. package/dist-lib/bridge-contract-input.cjs +1 -1
  12. package/dist-lib/bridge-contract-input.mjs +1 -1
  13. package/dist-lib/bridge-contract.cjs +1 -1
  14. package/dist-lib/bridge-contract.mjs +1 -1
  15. package/dist-lib/capture-contract.cjs +1 -1
  16. package/dist-lib/capture-contract.mjs +1 -1
  17. package/dist-lib/cli-constants.cjs +1 -1
  18. package/dist-lib/cloud-contract.cjs +1 -1
  19. package/dist-lib/cloud-contract.mjs +1 -1
  20. package/dist-lib/cloud-test-args.cjs +1 -1
  21. package/dist-lib/cloud-test-args.mjs +1 -1
  22. package/dist-lib/cloud.cjs +1 -1
  23. package/dist-lib/cloud.mjs +1 -1
  24. package/dist-lib/config.cjs +1 -1
  25. package/dist-lib/detox/index.cjs +2 -2
  26. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  27. package/dist-lib/home-paths.cjs +1 -1
  28. package/dist-lib/host/bridge-host.cjs +1 -1
  29. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  30. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  31. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  32. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  33. package/dist-lib/host/websocket-proxy.cjs +1 -1
  34. package/dist-lib/index.cjs +1 -1
  35. package/dist-lib/jump-to-source-babel.cjs +1 -1
  36. package/dist-lib/jump-to-source-native.cjs +1 -1
  37. package/dist-lib/kotlin-host.cjs +7 -1
  38. package/dist-lib/menu.cjs +1 -1
  39. package/dist-lib/menu.mjs +1 -1
  40. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  41. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  42. package/dist-lib/metro-production-bundle.cjs +1 -1
  43. package/dist-lib/metro-production-bundle.mjs +1 -1
  44. package/dist-lib/metro.cjs +1 -1
  45. package/dist-lib/native-app-identity.cjs +1 -1
  46. package/dist-lib/native-app-identity.mjs +1 -1
  47. package/dist-lib/plist.cjs +1 -1
  48. package/dist-lib/plist.mjs +1 -1
  49. package/dist-lib/profiles.cjs +1 -1
  50. package/dist-lib/public-brand.cjs +1 -1
  51. package/dist-lib/react-native-host-modules.cjs +1 -1
  52. package/dist-lib/react-native-host-modules.mjs +1 -1
  53. package/dist-lib/render-mode.cjs +1 -1
  54. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  55. package/dist-lib/sdk.cjs +1 -1
  56. package/dist-lib/sdk.mjs +1 -1
  57. package/dist-lib/skills.cjs +8 -8
  58. package/dist-lib/swift-compile.cjs +1 -1
  59. package/dist-lib/swift-compile.mjs +1 -1
  60. package/dist-lib/swift-package.cjs +1 -1
  61. package/dist-lib/swift-package.mjs +1 -1
  62. package/dist-lib/swift-submit.cjs +1 -1
  63. package/dist-lib/swift-submit.mjs +1 -1
  64. package/dist-lib/swift.cjs +1 -1
  65. package/dist-lib/vite-swift.cjs +1 -1
  66. package/dist-lib/vite.cjs +1 -1
  67. package/kotlin/AppSources/android/app/Activity.kt +44 -0
  68. package/kotlin/AppSources/android/os/Bundle.kt +9 -3
  69. package/kotlin/AppSources/androidx/activity/BackEventCompat.kt +17 -0
  70. package/kotlin/AppSources/androidx/activity/Cancellable.kt +5 -0
  71. package/kotlin/AppSources/androidx/activity/ComponentActivity.kt +22 -3
  72. package/kotlin/AppSources/androidx/activity/OnBackPressedCallback.kt +28 -0
  73. package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcher.kt +144 -0
  74. package/kotlin/AppSources/androidx/activity/OnBackPressedDispatcherOwner.kt +7 -0
  75. package/kotlin/AppSources/androidx/activity/compose/BackHandler.kt +55 -0
  76. package/kotlin/AppSources/dev/peach/app/PeachApp.kt +51 -1
  77. package/kotlin/AppSources/java/lang/Runnable.kt +6 -0
  78. package/package.json +1 -1
  79. package/src/kotlin-app.ts +11 -0
  80. package/src/kotlin-host.ts +6 -0
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/beta.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/beta.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/beta.ts
4
4
  var IS_BETA = true;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var SIM_LONG_PRESS_MAX_MS = 5e3;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/bridge-contract.ts
4
4
  var REFUSED_PERFORM_STEP_TYPES = [
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/capture-contract.ts
4
4
  var RNX_SCREEN_CAPTURE_VERSION = 1;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/cloud-contract.ts
4
4
  var RNX_CLOUD_MAX_ARTIFACT_BYTES = 20 * 1024 * 1024;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/cloud-test-args.ts
4
4
  var CLOUD_TEST_ARGS_MAX_COUNT = 32;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -269,7 +269,7 @@ function processIdentity(pid) {
269
269
  }
270
270
  function softwareChromeAllowed(runtime = currentRuntime()) {
271
271
  if (runtime.platform !== "linux") return false;
272
- return runtime.env.GITHUB_ACTIONS === "true" && runtime.env.RUNNER_OS === "Linux" || runtime.env.CONTRAST_CF_FACTORY_CONTAINER === "1";
272
+ return runtime.env.GITHUB_ACTIONS === "true" && runtime.env.RUNNER_OS === "Linux" || runtime.env.CONTRAST_CF_FACTORY_CONTAINER === "1" || runtime.env.PEACH_NATIVE_COMPOSITOR === "1";
273
273
  }
274
274
  function isSoftwareRendererArgument(value) {
275
275
  const arg = String(value);
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/host/fetch-proxy-overrides.ts
4
4
  var FETCH_PROXY_BROWSER_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -309,6 +309,12 @@ async function kotlinAppArtifact(app, moduleRoot, origin) {
309
309
  " ),",
310
310
  " density, fontScale, locale, backend, stencilBits, regular, medium, bold, statusBar, navigationBar, night, invalidate,",
311
311
  ")",
312
+ "",
313
+ "@JsExport",
314
+ `fun peachAppBack(): Boolean = dev.peach.app.peachAppBack(${app.predictiveBack})`,
315
+ "",
316
+ "@JsExport",
317
+ "fun peachAppTask(foreground: Boolean) = dev.peach.app.peachAppTask(foreground)",
312
318
  ""
313
319
  ].join("\n")
314
320
  };
package/dist-lib/menu.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/menu.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/public-brand.ts
4
4
  var name = "Peach";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/is-record.ts
4
4
  function isRecord(value) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/metro-production-bundle.ts
4
4
  var RNXSIM_METRO_MODULE_PATHS_PREFIX = "globalThis.__sootsimModulePaths=";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/native-app-identity.ts
4
4
  var NATIVE_APP_IDENTITY_PREFIX = "globalThis.__sootsimNativeAppIdentity=";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/plist.ts
4
4
  import plistModule from "@expo/plist";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/react-native-host-modules.ts
4
4
  var REACT_NATIVE_PASSTHROUGH_SPECIFIERS = [
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
package/dist-lib/sdk.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
package/dist-lib/sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -58,7 +58,7 @@ function processIdentity(pid) {
58
58
  }
59
59
  function softwareChromeAllowed(runtime = currentRuntime()) {
60
60
  if (runtime.platform !== "linux") return false;
61
- return runtime.env.GITHUB_ACTIONS === "true" && runtime.env.RUNNER_OS === "Linux" || runtime.env.CONTRAST_CF_FACTORY_CONTAINER === "1";
61
+ return runtime.env.GITHUB_ACTIONS === "true" && runtime.env.RUNNER_OS === "Linux" || runtime.env.CONTRAST_CF_FACTORY_CONTAINER === "1" || runtime.env.PEACH_NATIVE_COMPOSITOR === "1";
62
62
  }
63
63
  function isSoftwareRendererArgument(value) {
64
64
  const arg = String(value);
@@ -8896,16 +8896,16 @@ var init_registry = __esm({
8896
8896
  {
8897
8897
  range: ">=2.0.0 <3.0.0",
8898
8898
  coverage: 0,
8899
- note: "native seam: published JavaScript loads against the Compressor Nitro hybrid object; native media and filesystem operations reject explicitly",
8900
- working: "published Image, Video, Audio and utility exports load; transcoding rejects with UNSUPPORTED_OPERATION instead of returning an unchanged asset as a success",
8901
- missing: "native media transcoding, metadata, thumbnails, cache files, upload/download and background execution"
8899
+ note: "native seam: published JavaScript runs over the Compressor Nitro object; worker WebCodecs and a lazy container backend export H.264 MP4 and AAC M4A files",
8900
+ working: "image encoding; video/audio transcoding to writable file URIs; native bitrate, resize, quality, sample rate and channel options; progress and UUID cancellation; real metadata; 512px thumbnails; fetch upload/download and cache utilities",
8901
+ missing: "PhotoKit assets, EXIF preservation, UIApplication background assertions; encoding depends on browser H.264/AAC codec availability"
8902
8902
  },
8903
8903
  {
8904
8904
  range: ">=1.0.0 <2.0.0",
8905
8905
  coverage: 0.78,
8906
- note: "native-seam: real package JS runs from the bundle; the Compressor TurboModule is browser-backed (canvas raster compression, HTMLVideoElement metadata/thumbnail, fetch upload/download)",
8907
- working: "Image.compress loads uri/base64 inputs, preserves aspect ratio, resizes/re-encodes jpg/png, returns uri or base64; getImageMetaData/getVideoMetaData report real dimensions+size; createVideoThumbnail captures the first frame; clearCache resolves (composer onClose); Video.compress passes through and drives progress to completion; backgroundUpload/download use fetch",
8908
- missing: "native cache file paths, EXIF preservation, ph:// assets, native video/audio transcoding, granular byte-level progress events, background execution beyond browser fetch"
8906
+ note: "native seam: published JavaScript runs over the browser-backed Compressor TurboModule; worker media decoding and H.264/AAC export use the v1 native bitrate and resize rules",
8907
+ working: "Image.compress resizes/re-encodes jpg/png and returns URI/base64; video/audio export writes MP4/M4A files; video progress and UUID cancellation; missing metadata rejects -15; real dimensions, duration and size; 512px thumbnails; cache, upload and download operations",
8908
+ missing: "EXIF preservation, PhotoKit assets, granular upload byte progress and UIApplication background assertions; encoding depends on browser H.264/AAC codec availability"
8909
8909
  }
8910
8910
  ]
8911
8911
  },
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-compile.ts
4
4
  import { execFile as execFile2 } from "node:child_process";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-package.ts
4
4
  function isSwiftManifestFile(file) {
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
 
3
3
  // src/swift-submit.ts
4
4
  var SWIFT_COMPILE_PATH = "/api/swift-compile";
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __defProp = Object.defineProperty;
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
package/dist-lib/vite.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! rnx v0.1.658 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
1
+ /*! rnx v0.1.659 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
2
  let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
3
3
  "use strict";
4
4
  var __create = Object.create;
@@ -48,12 +48,30 @@ open class Activity : ContextWrapper() {
48
48
  protected open fun onPostCreate(savedInstanceState: Bundle?) { called = true }
49
49
  protected open fun onResume() { called = true }
50
50
  protected open fun onPostResume() { called = true }
51
+ protected open fun onPause() { called = true }
52
+ protected open fun onStop() { called = true }
53
+ protected open fun onRestart() { called = true }
54
+
55
+ // Activity's own save writes the window's view hierarchy state; the decor
56
+ // window here holds no view state of its own
57
+ protected open fun onSaveInstanceState(outState: Bundle) {}
58
+
59
+ // a back the window's callbacks left: the activity asks the task manager,
60
+ // which moves a root launcher task to the back rather than finishing it
61
+ // (from Android 12). the only activity Peach runs is that task's root.
62
+ open fun onBackPressed() {
63
+ movedTaskToBack = true
64
+ }
65
+
66
+ internal var movedTaskToBack = false
51
67
 
52
68
  // ActivityLifecycleCallbacks' post events; ComponentActivity's lifecycle
53
69
  // moves on these, as its ReportFragment does from API 29.
54
70
  internal open fun dispatchActivityPostCreated() {}
55
71
  internal open fun dispatchActivityPostStarted() {}
56
72
  internal open fun dispatchActivityPostResumed() {}
73
+ internal open fun dispatchActivityPrePaused() {}
74
+ internal open fun dispatchActivityPreStopped() {}
57
75
 
58
76
  private fun require(method: String, call: () -> Unit) {
59
77
  called = false
@@ -77,6 +95,32 @@ open class Activity : ContextWrapper() {
77
95
  require("onPostCreate") { onPostCreate(icicle) }
78
96
  }
79
97
 
98
+ internal fun performPause() {
99
+ dispatchActivityPrePaused()
100
+ require("onPause") { onPause() }
101
+ }
102
+
103
+ private var stopped = false
104
+
105
+ internal fun performStop() {
106
+ dispatchActivityPreStopped()
107
+ require("onStop") { onStop() }
108
+ stopped = true
109
+ }
110
+
111
+ internal fun performSaveInstanceState(outState: Bundle) {
112
+ onSaveInstanceState(outState)
113
+ }
114
+
115
+ // ActivityThread brings a stopped activity back with onRestart, then
116
+ // onStart; one that never stopped has nothing to restart
117
+ internal fun performRestart() {
118
+ if (!stopped) return
119
+ stopped = false
120
+ require("onRestart") { onRestart() }
121
+ performStart()
122
+ }
123
+
80
124
  internal fun performResume() {
81
125
  require("onResume") { onResume() }
82
126
  require("onPostResume") { onPostResume() }
@@ -1,5 +1,11 @@
1
1
  package android.os
2
2
 
3
- // a cold start has no saved instance state, so the launcher receives null;
4
- // the type exists for the signatures that name it.
5
- class Bundle
3
+ import androidx.savedstate.SavedState
4
+ import androidx.savedstate.savedState
5
+
6
+ // on Android androidx's SavedState is Bundle; here a Bundle holds the
7
+ // multiplatform SavedState that a save writes into. a cold start has no saved
8
+ // instance state, so the launcher receives null.
9
+ class Bundle internal constructor(internal val state: SavedState) {
10
+ constructor() : this(savedState())
11
+ }
@@ -0,0 +1,17 @@
1
+ package androidx.activity
2
+
3
+ // androidx.activity's BackEventCompat: one predictive back gesture sample
4
+ class BackEventCompat(
5
+ val touchX: Float,
6
+ val touchY: Float,
7
+ val progress: Float,
8
+ val swipeEdge: Int,
9
+ ) {
10
+ override fun toString(): String =
11
+ "BackEventCompat{touchX=$touchX, touchY=$touchY, progress=$progress, swipeEdge=$swipeEdge}"
12
+
13
+ companion object {
14
+ const val EDGE_LEFT = 0
15
+ const val EDGE_RIGHT = 1
16
+ }
17
+ }
@@ -0,0 +1,5 @@
1
+ package androidx.activity
2
+
3
+ internal interface Cancellable {
4
+ fun cancel()
5
+ }
@@ -21,10 +21,11 @@ import androidx.savedstate.SavedStateRegistryOwner
21
21
 
22
22
  // androidx.activity's ComponentActivity owners, on the multiplatform
23
23
  // lifecycle, viewmodel and savedstate libraries: the registry attaches in the
24
- // constructor and restores in onCreate before super, the lifecycle moves on
25
- // the post callbacks, and destroy clears the view model store.
24
+ // constructor and restores in onCreate before super, the lifecycle moves up on
25
+ // the post callbacks and down on the pre callbacks, as ReportFragment does from
26
+ // API 29, and destroy clears the view model store.
26
27
  open class ComponentActivity : Activity(), LifecycleOwner, ViewModelStoreOwner,
27
- HasDefaultViewModelProviderFactory, SavedStateRegistryOwner {
28
+ HasDefaultViewModelProviderFactory, SavedStateRegistryOwner, OnBackPressedDispatcherOwner {
28
29
  private val lifecycleRegistry = LifecycleRegistry(this)
29
30
  private val savedStateRegistryController = SavedStateRegistryController.create(this)
30
31
 
@@ -51,7 +52,25 @@ open class ComponentActivity : Activity(), LifecycleOwner, ViewModelStoreOwner,
51
52
  super.onCreate(savedInstanceState)
52
53
  }
53
54
 
55
+ override fun onSaveInstanceState(outState: Bundle) {
56
+ lifecycleRegistry.currentState = Lifecycle.State.CREATED
57
+ super.onSaveInstanceState(outState)
58
+ savedStateRegistryController.performSave(outState.state)
59
+ }
60
+
61
+ // the dispatcher gets the back first; without an enabled callback it falls
62
+ // back to Activity's own
63
+ override fun onBackPressed() {
64
+ onBackPressedDispatcher.onBackPressed()
65
+ }
66
+
67
+ final override val onBackPressedDispatcher: OnBackPressedDispatcher by lazy {
68
+ OnBackPressedDispatcher { super@ComponentActivity.onBackPressed() }
69
+ }
70
+
54
71
  override fun dispatchActivityPostCreated() = lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
55
72
  override fun dispatchActivityPostStarted() = lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
56
73
  override fun dispatchActivityPostResumed() = lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
74
+ override fun dispatchActivityPrePaused() = lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
75
+ override fun dispatchActivityPreStopped() = lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
57
76
  }
@@ -0,0 +1,28 @@
1
+ package androidx.activity
2
+
3
+ // androidx.activity 1.9.3's OnBackPressedCallback
4
+ abstract class OnBackPressedCallback(enabled: Boolean) {
5
+ var isEnabled: Boolean = enabled
6
+ set(value) {
7
+ field = value
8
+ enabledChangedCallback?.invoke()
9
+ }
10
+
11
+ private val cancellables = mutableListOf<Cancellable>()
12
+ internal var enabledChangedCallback: (() -> Unit)? = null
13
+
14
+ fun remove() = cancellables.toList().forEach { it.cancel() }
15
+
16
+ open fun handleOnBackStarted(backEvent: BackEventCompat) {}
17
+ open fun handleOnBackProgressed(backEvent: BackEventCompat) {}
18
+ abstract fun handleOnBackPressed()
19
+ open fun handleOnBackCancelled() {}
20
+
21
+ internal fun addCancellable(cancellable: Cancellable) {
22
+ cancellables.add(cancellable)
23
+ }
24
+
25
+ internal fun removeCancellable(cancellable: Cancellable) {
26
+ cancellables.remove(cancellable)
27
+ }
28
+ }
@@ -0,0 +1,144 @@
1
+ package androidx.activity
2
+
3
+ import java.lang.Runnable
4
+ import androidx.lifecycle.Lifecycle
5
+ import androidx.lifecycle.LifecycleEventObserver
6
+ import androidx.lifecycle.LifecycleOwner
7
+
8
+ // androidx.activity 1.9.3's OnBackPressedDispatcher. the device's back
9
+ // dispatch stands in for its OnBackInvokedDispatcher registration: a window
10
+ // with predictive back gives this dispatcher the back only while it has an
11
+ // enabled callback (hasEnabledCallbacks), as the registered callback does.
12
+ class OnBackPressedDispatcher(
13
+ private val fallbackOnBackPressed: Runnable?,
14
+ private val onHasEnabledCallbacksChanged: ((Boolean) -> Unit)?,
15
+ ) {
16
+ private val onBackPressedCallbacks = ArrayDeque<OnBackPressedCallback>()
17
+ private var inProgressCallback: OnBackPressedCallback? = null
18
+ private var hasEnabledCallbacks = false
19
+
20
+ constructor(fallbackOnBackPressed: Runnable? = null) : this(fallbackOnBackPressed, null)
21
+
22
+ private fun updateEnabledCallbacks() {
23
+ val hadEnabledCallbacks = hasEnabledCallbacks
24
+ val hasEnabledCallbacks = onBackPressedCallbacks.any { it.isEnabled }
25
+ this.hasEnabledCallbacks = hasEnabledCallbacks
26
+ if (hasEnabledCallbacks != hadEnabledCallbacks)
27
+ onHasEnabledCallbacksChanged?.invoke(hasEnabledCallbacks)
28
+ }
29
+
30
+ fun addCallback(onBackPressedCallback: OnBackPressedCallback) {
31
+ addCancellableCallback(onBackPressedCallback)
32
+ }
33
+
34
+ internal fun addCancellableCallback(onBackPressedCallback: OnBackPressedCallback): Cancellable {
35
+ onBackPressedCallbacks.add(onBackPressedCallback)
36
+ val cancellable = OnBackPressedCancellable(onBackPressedCallback)
37
+ onBackPressedCallback.addCancellable(cancellable)
38
+ updateEnabledCallbacks()
39
+ onBackPressedCallback.enabledChangedCallback = ::updateEnabledCallbacks
40
+ return cancellable
41
+ }
42
+
43
+ fun addCallback(owner: LifecycleOwner, onBackPressedCallback: OnBackPressedCallback) {
44
+ val lifecycle = owner.lifecycle
45
+ if (lifecycle.currentState === Lifecycle.State.DESTROYED) return
46
+ onBackPressedCallback.addCancellable(LifecycleOnBackPressedCancellable(lifecycle, onBackPressedCallback))
47
+ updateEnabledCallbacks()
48
+ onBackPressedCallback.enabledChangedCallback = ::updateEnabledCallbacks
49
+ }
50
+
51
+ fun hasEnabledCallbacks(): Boolean = hasEnabledCallbacks
52
+
53
+ fun dispatchOnBackStarted(backEvent: BackEventCompat) {
54
+ val callback = onBackPressedCallbacks.lastOrNull { it.isEnabled }
55
+ if (inProgressCallback != null) dispatchOnBackCancelled()
56
+ inProgressCallback = callback
57
+ callback?.handleOnBackStarted(backEvent)
58
+ }
59
+
60
+ fun dispatchOnBackProgressed(backEvent: BackEventCompat) {
61
+ val callback = inProgressCallback ?: onBackPressedCallbacks.lastOrNull { it.isEnabled }
62
+ callback?.handleOnBackProgressed(backEvent)
63
+ }
64
+
65
+ fun onBackPressed() {
66
+ val callback = inProgressCallback ?: onBackPressedCallbacks.lastOrNull { it.isEnabled }
67
+ inProgressCallback = null
68
+ if (callback != null) {
69
+ callback.handleOnBackPressed()
70
+ return
71
+ }
72
+ fallbackOnBackPressed?.run()
73
+ }
74
+
75
+ fun dispatchOnBackCancelled() {
76
+ val callback = inProgressCallback ?: onBackPressedCallbacks.lastOrNull { it.isEnabled }
77
+ inProgressCallback = null
78
+ callback?.handleOnBackCancelled()
79
+ }
80
+
81
+ private inner class OnBackPressedCancellable(
82
+ private val onBackPressedCallback: OnBackPressedCallback,
83
+ ) : Cancellable {
84
+ override fun cancel() {
85
+ onBackPressedCallbacks.remove(onBackPressedCallback)
86
+ if (inProgressCallback == onBackPressedCallback) {
87
+ onBackPressedCallback.handleOnBackCancelled()
88
+ inProgressCallback = null
89
+ }
90
+ onBackPressedCallback.removeCancellable(this)
91
+ onBackPressedCallback.enabledChangedCallback?.invoke()
92
+ onBackPressedCallback.enabledChangedCallback = null
93
+ }
94
+ }
95
+
96
+ // a lifecycle-bound callback receives back only between ON_START and ON_STOP
97
+ private inner class LifecycleOnBackPressedCancellable(
98
+ private val lifecycle: Lifecycle,
99
+ private val onBackPressedCallback: OnBackPressedCallback,
100
+ ) : LifecycleEventObserver, Cancellable {
101
+ private var currentCancellable: Cancellable? = null
102
+
103
+ init {
104
+ lifecycle.addObserver(this)
105
+ }
106
+
107
+ override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
108
+ if (event === Lifecycle.Event.ON_START) {
109
+ currentCancellable = addCancellableCallback(onBackPressedCallback)
110
+ } else if (event === Lifecycle.Event.ON_STOP) {
111
+ currentCancellable?.cancel()
112
+ } else if (event === Lifecycle.Event.ON_DESTROY) {
113
+ cancel()
114
+ }
115
+ }
116
+
117
+ override fun cancel() {
118
+ lifecycle.removeObserver(this)
119
+ onBackPressedCallback.removeCancellable(this)
120
+ currentCancellable?.cancel()
121
+ currentCancellable = null
122
+ }
123
+ }
124
+ }
125
+
126
+ // androidx.activity's Kotlin registration: a callback from a lambda, bound to
127
+ // owner's lifecycle when one is given
128
+ fun OnBackPressedDispatcher.addCallback(
129
+ owner: LifecycleOwner? = null,
130
+ enabled: Boolean = true,
131
+ onBackPressed: OnBackPressedCallback.() -> Unit
132
+ ): OnBackPressedCallback {
133
+ val callback = object : OnBackPressedCallback(enabled) {
134
+ override fun handleOnBackPressed() {
135
+ onBackPressed()
136
+ }
137
+ }
138
+ if (owner != null) {
139
+ addCallback(owner, callback)
140
+ } else {
141
+ addCallback(callback)
142
+ }
143
+ return callback
144
+ }
@@ -0,0 +1,7 @@
1
+ package androidx.activity
2
+
3
+ import androidx.lifecycle.LifecycleOwner
4
+
5
+ interface OnBackPressedDispatcherOwner : LifecycleOwner {
6
+ val onBackPressedDispatcher: OnBackPressedDispatcher
7
+ }
@@ -0,0 +1,55 @@
1
+ package androidx.activity.compose
2
+
3
+ import androidx.activity.OnBackPressedCallback
4
+ import androidx.activity.OnBackPressedDispatcherOwner
5
+ import androidx.compose.runtime.Composable
6
+ import androidx.compose.runtime.DisposableEffect
7
+ import androidx.compose.runtime.ProvidedValue
8
+ import androidx.compose.runtime.SideEffect
9
+ import androidx.compose.runtime.compositionLocalOf
10
+ import androidx.compose.runtime.getValue
11
+ import androidx.compose.runtime.remember
12
+ import androidx.compose.runtime.rememberUpdatedState
13
+ import androidx.lifecycle.compose.LocalLifecycleOwner
14
+
15
+ // activity-compose 1.9.3's LocalOnBackPressedDispatcherOwner. on the device
16
+ // an unprovided value resolves from the view tree or the context, both of
17
+ // which reach the activity that set the content; the window host provides that
18
+ // activity here.
19
+ object LocalOnBackPressedDispatcherOwner {
20
+ private val LocalOnBackPressedDispatcherOwner =
21
+ compositionLocalOf<OnBackPressedDispatcherOwner?> { null }
22
+
23
+ val current: OnBackPressedDispatcherOwner?
24
+ @Composable
25
+ get() = LocalOnBackPressedDispatcherOwner.current
26
+
27
+ infix fun provides(dispatcherOwner: OnBackPressedDispatcherOwner): ProvidedValue<OnBackPressedDispatcherOwner?> =
28
+ LocalOnBackPressedDispatcherOwner.provides(dispatcherOwner)
29
+ }
30
+
31
+ // activity-compose 1.9.3's BackHandler
32
+ @Composable
33
+ fun BackHandler(enabled: Boolean = true, onBack: () -> Unit) {
34
+ val currentOnBack by rememberUpdatedState(onBack)
35
+ val backCallback = remember {
36
+ object : OnBackPressedCallback(enabled) {
37
+ override fun handleOnBackPressed() {
38
+ currentOnBack()
39
+ }
40
+ }
41
+ }
42
+ SideEffect {
43
+ backCallback.isEnabled = enabled
44
+ }
45
+ val backDispatcher = checkNotNull(LocalOnBackPressedDispatcherOwner.current) {
46
+ "No OnBackPressedDispatcherOwner was provided via LocalOnBackPressedDispatcherOwner"
47
+ }.onBackPressedDispatcher
48
+ val lifecycleOwner = LocalLifecycleOwner.current
49
+ DisposableEffect(lifecycleOwner, backDispatcher) {
50
+ backDispatcher.addCallback(lifecycleOwner, backCallback)
51
+ onDispose {
52
+ backCallback.remove()
53
+ }
54
+ }
55
+ }
@@ -2,6 +2,8 @@
2
2
 
3
3
  package dev.peach.app
4
4
 
5
+ import android.os.Bundle
6
+
5
7
  import android.app.Activity
6
8
  import android.app.Application
7
9
  import android.content.ComponentName
@@ -13,6 +15,9 @@ import android.view.ViewGroup
13
15
  import android.view.Window
14
16
  import android.view.WindowTheme
15
17
  import androidx.activity.ComponentActivity
18
+ import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
19
+ import androidx.compose.runtime.Composable
20
+ import androidx.compose.runtime.CompositionLocalProvider
16
21
  import androidx.compose.ui.platform.ComposeView
17
22
  import androidx.compose.ui.platform.PlatformArchitectureComponentsOwner
18
23
  import androidx.compose.ui.platform.PlatformInsets
@@ -117,14 +122,22 @@ internal fun peachStartApp(
117
122
  activity.performStart()
118
123
  activity.performPostCreate(null)
119
124
  activity.performResume()
125
+ running = activity
120
126
  mount = PeachComposeMount(
121
127
  density, fontScale, locale, backend == "graphite", stencilBits, fonts, invalidate,
122
128
  owners = componentActivity?.let(::ActivityOwners),
123
129
  insets = SystemBarInsets(window, statusBar, navigationBar),
124
130
  clockRunning = { componentActivity == null || componentActivity.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) },
125
131
  )
126
- mount.setContent { held?.let { view -> key(view) { view.Content() } } }
132
+ mount.setContent {
133
+ val content = @Composable { held?.let { view -> key(view) { view.Content() } }; Unit }
134
+ // the content view's tree resolves the activity as its back dispatcher owner
135
+ if (componentActivity != null)
136
+ CompositionLocalProvider(LocalOnBackPressedDispatcherOwner provides componentActivity, content = content)
137
+ else content()
138
+ }
127
139
  mountId = addMount(mount)
140
+ runningMount = mount
128
141
  window.addToWindowManager()
129
142
  val view = checkNotNull(held) {
130
143
  "${spec.component.flattenToShortString()} set no ComposeView as its content; Peach composes only ComposeView content"
@@ -139,3 +152,40 @@ internal fun peachStartApp(
139
152
  .put("error", "${error::class.simpleName}: ${error.message}").toString()
140
153
  }
141
154
  }
155
+
156
+ // the activity the app runs, once started, and the scene its window composes
157
+ private var running: Activity? = null
158
+ private var runningMount: PeachComposeMount? = null
159
+
160
+ // the device's back: an activity with predictive back gets it through its
161
+ // window's back dispatch, where ComponentActivity's dispatcher takes it only
162
+ // while a callback is enabled and the activity's own default handles the
163
+ // rest; without predictive back the key reaches onBackPressed. false when the
164
+ // task moved to the back, which the device then shows as home.
165
+ internal fun peachAppBack(predictive: Boolean): Boolean {
166
+ val activity = checkNotNull(running) { "the app is not running" }
167
+ activity.movedTaskToBack = false
168
+ val dispatcher = (activity as? ComponentActivity)?.onBackPressedDispatcher
169
+ if (!predictive) activity.onBackPressed()
170
+ else if (dispatcher?.hasEnabledCallbacks() == true) dispatcher.onBackPressed()
171
+ else activity.movedTaskToBack = true
172
+ return !activity.movedTaskToBack
173
+ }
174
+
175
+ // the task left the foreground (onPause, onStop, onSaveInstanceState) or came back to it
176
+ // (onRestart, onStart, onResume, onPostResume), as ActivityThread drives it
177
+ internal fun peachAppTask(foreground: Boolean) {
178
+ val activity = checkNotNull(running) { "the app is not running" }
179
+ if (foreground) {
180
+ activity.performRestart()
181
+ activity.performResume()
182
+ // the frame clock runs again once the activity is started
183
+ checkNotNull(runningMount).invalidate(false)
184
+ } else {
185
+ activity.performPause()
186
+ activity.performStop()
187
+ // from API 28 an activity that stops saves its state after onStop;
188
+ // ActivityThread keeps it for a relaunch, which no path here takes yet
189
+ activity.performSaveInstanceState(Bundle())
190
+ }
191
+ }
@@ -0,0 +1,6 @@
1
+ package java.lang
2
+
3
+ // java.lang.Runnable, which the platform and androidx signatures name
4
+ fun interface Runnable {
5
+ fun run()
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peachsim",
3
- "version": "0.1.658",
3
+ "version": "0.1.659",
4
4
  "description": "Vite and Metro plugins, testing drivers, and SDK exports for peach.",
5
5
  "author": "Tamagui LLC",
6
6
  "license": "SEE LICENSE IN LICENSE",
package/src/kotlin-app.ts CHANGED
@@ -29,6 +29,9 @@ export interface KotlinAppProject {
29
29
  }
30
30
  applicationClass: string | null
31
31
  launcher: { name: string; targetClass: string }
32
+ // back reaches the activity through its window's back dispatch rather than
33
+ // the back key's onBackPressed
34
+ predictiveBack: boolean
32
35
  }
33
36
 
34
37
  export interface ComposeAndroidPins {
@@ -392,6 +395,13 @@ export function readKotlinApp(
392
395
  themeOwner?.attributes[`${ANDROID_NS}theme`] ??
393
396
  application.attributes[`${ANDROID_NS}theme`]
394
397
  const applicationName = application.attributes[`${ANDROID_NS}name`]
398
+ // ParsingPackageUtils: the application's enableOnBackInvokedCallback
399
+ // defaults on above target SDK 35; ParsedActivityUtils: an activity's own
400
+ // value overrides it
401
+ const predictiveBack =
402
+ (themeOwner?.attributes[`${ANDROID_NS}enableOnBackInvokedCallback`] ??
403
+ application.attributes[`${ANDROID_NS}enableOnBackInvokedCallback`] ??
404
+ String(targetSdk > 35)) === 'true'
395
405
 
396
406
  const sources: string[] = []
397
407
  for (const set of ['java', 'kotlin']) {
@@ -421,5 +431,6 @@ export function readKotlinApp(
421
431
  window: readWindowTheme(moduleDir, theme, targetSdk),
422
432
  applicationClass: applicationName ? className(applicationName) : null,
423
433
  launcher: { name: launcherName, targetClass },
434
+ predictiveBack,
424
435
  }
425
436
  }
@@ -353,6 +353,12 @@ export async function kotlinAppArtifact(
353
353
  ' density, fontScale, locale, backend, stencilBits, regular, medium, bold, statusBar, navigationBar, night, invalidate,',
354
354
  ')',
355
355
  '',
356
+ '@JsExport',
357
+ `fun peachAppBack(): Boolean = dev.peach.app.peachAppBack(${app.predictiveBack})`,
358
+ '',
359
+ '@JsExport',
360
+ 'fun peachAppTask(foreground: Boolean) = dev.peach.app.peachAppTask(foreground)',
361
+ '',
356
362
  ].join('\n'),
357
363
  }
358
364
  const shims = [