peachsim 0.1.628 → 0.1.630

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 (111) hide show
  1. package/README.md +8 -4
  2. package/cli/bridge-flow-runner.ts +10 -3
  3. package/cli/cli-update.ts +2 -7
  4. package/cli/cloud-test-tunnel.ts +16 -3
  5. package/cli/commands/config.ts +1 -1
  6. package/cli/commands/control.ts +28 -3
  7. package/cli/commands/daemon-mac-app.ts +4 -2
  8. package/cli/commands/daemon.ts +4 -4
  9. package/cli/commands/device.ts +2 -3
  10. package/cli/commands/inspect/actions.ts +125 -90
  11. package/cli/commands/inspect/core.ts +5 -0
  12. package/cli/commands/inspect.ts +27 -13
  13. package/cli/commands/platform.ts +1 -1
  14. package/cli/commands/screenshot-layers.ts +1 -1
  15. package/cli/commands/screenshot.ts +1 -1
  16. package/cli/commands/skills.ts +0 -31
  17. package/cli/drivers/playwright-provisioning.ts +3 -2
  18. package/cli/drivers/playwright-sim-host.ts +25 -9
  19. package/cli/main.ts +8 -2
  20. package/cli/outbound-endpoints.ts +0 -4
  21. package/detox/index.ts +74 -43
  22. package/dist-lib/agent-daemon-client.cjs +1 -1
  23. package/dist-lib/agent-events.cjs +1 -1
  24. package/dist-lib/agent-identity.cjs +1 -1
  25. package/dist-lib/agent-sessions.cjs +1 -1
  26. package/dist-lib/attached-projects.cjs +1 -1
  27. package/dist-lib/auth/shared-session.cjs +1 -1
  28. package/dist-lib/backend-origin.cjs +1 -1
  29. package/dist-lib/beta.cjs +1 -1
  30. package/dist-lib/beta.mjs +1 -1
  31. package/dist-lib/bridge-constants.cjs +1 -1
  32. package/dist-lib/bridge-contract-input.cjs +1 -1
  33. package/dist-lib/bridge-contract-input.mjs +1 -1
  34. package/dist-lib/bridge-contract.cjs +1 -1
  35. package/dist-lib/bridge-contract.mjs +1 -1
  36. package/dist-lib/capture-contract.cjs +1 -1
  37. package/dist-lib/capture-contract.mjs +1 -1
  38. package/dist-lib/cli-constants.cjs +1 -1
  39. package/dist-lib/cloud-contract.cjs +1 -1
  40. package/dist-lib/cloud-contract.mjs +1 -1
  41. package/dist-lib/cloud-test-args.cjs +1 -1
  42. package/dist-lib/cloud-test-args.mjs +1 -1
  43. package/dist-lib/cloud.cjs +1 -1
  44. package/dist-lib/cloud.mjs +1 -1
  45. package/dist-lib/config.cjs +1 -1
  46. package/dist-lib/detox/index.cjs +129 -27
  47. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  48. package/dist-lib/home-paths.cjs +1 -1
  49. package/dist-lib/host/bridge-host.cjs +290 -315
  50. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  51. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  52. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  53. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  54. package/dist-lib/host/websocket-proxy.cjs +1 -1
  55. package/dist-lib/index.cjs +253 -121
  56. package/dist-lib/jump-to-source-babel.cjs +1 -1
  57. package/dist-lib/jump-to-source-native.cjs +1 -1
  58. package/dist-lib/{vite-kotlin.cjs → kotlin-host.cjs} +130 -19
  59. package/dist-lib/menu.cjs +1 -1
  60. package/dist-lib/menu.mjs +1 -1
  61. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  62. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  63. package/dist-lib/metro-production-bundle.cjs +1 -1
  64. package/dist-lib/metro-production-bundle.mjs +1 -1
  65. package/dist-lib/metro.cjs +132 -9
  66. package/dist-lib/native-app-identity.cjs +278 -0
  67. package/dist-lib/native-app-identity.mjs +245 -0
  68. package/dist-lib/profiles.cjs +1 -1
  69. package/dist-lib/public-brand.cjs +1 -1
  70. package/dist-lib/react-native-host-modules.cjs +1 -1
  71. package/dist-lib/react-native-host-modules.mjs +1 -1
  72. package/dist-lib/render-mode.cjs +1 -1
  73. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  74. package/dist-lib/sdk.cjs +110 -87
  75. package/dist-lib/sdk.mjs +110 -87
  76. package/dist-lib/skills.cjs +841 -643
  77. package/dist-lib/swift-compile.cjs +1 -1
  78. package/dist-lib/swift-compile.mjs +1 -1
  79. package/dist-lib/swift-package.cjs +1 -1
  80. package/dist-lib/swift-package.mjs +1 -1
  81. package/dist-lib/swift-submit.cjs +1 -1
  82. package/dist-lib/swift-submit.mjs +1 -1
  83. package/dist-lib/swift.cjs +282 -177
  84. package/dist-lib/vite-swift.cjs +1 -1
  85. package/dist-lib/vite.cjs +11 -28
  86. package/kotlin/README.md +32 -4
  87. package/kotlin/fixtures/counter/Counter.kt +26 -0
  88. package/kotlin/fixtures/counter/CounterScreen.kt +40 -0
  89. package/kotlin/fixtures/headless-counter/Headless.kt +228 -0
  90. package/kotlin/fixtures/runtime-state/RuntimeState.kt +200 -0
  91. package/kotlin/fork/LICENSE +178 -0
  92. package/kotlin/fork/NOTICE +25 -0
  93. package/kotlin/fork/README.md +59 -0
  94. package/kotlin/fork/build.sh +128 -0
  95. package/kotlin/fork/compose-worker-globals.patch +96 -0
  96. package/kotlin/fork/fork.json +33 -0
  97. package/kotlin/fork/publish.ts +77 -0
  98. package/kotlin/fork/skiko-worker-clock.patch +33 -0
  99. package/kotlin/toolchain.json +288 -0
  100. package/package.json +12 -5
  101. package/src/automatic-update-policy.ts +17 -0
  102. package/src/host/bridge-host.ts +3 -1
  103. package/src/{vite-plugin-kotlin.ts → kotlin-host.ts} +155 -12
  104. package/src/metro-plugin.ts +18 -0
  105. package/src/native-app-identity.ts +376 -0
  106. package/src/native-firebase-config.ts +90 -0
  107. package/src/screenshots/frame-compose.ts +5 -2
  108. package/src/screenshots/registry.ts +1 -1
  109. package/src/screenshots/schema.ts +2 -2
  110. package/src/vite-plugin-one.ts +11 -28
  111. package/src/vite-plugin.ts +6 -1
@@ -15,5 +15,293 @@
15
15
  "url": "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/atomicfu-wasm-js/0.32.1/atomicfu-wasm-js-0.32.1.klib",
16
16
  "sha256": "1bdc5a5216944b8f9a396d2f0c7df320b43d6921725baad1afc04cc8e2ae48e3"
17
17
  }
18
+ ],
19
+ "composeLibraries": [
20
+ {
21
+ "name": "ui-wasm-js-1.13.0-alpha01-peach-0e3c251301e0.klib",
22
+ "url": "https://r2.rnxsim.com/peach-kotlin-fork/0e3c251301e0df405e50d0aa7d45b401c1aa26f7ed0a7001c6ce2bc68f5d667b/ui-wasm-js-1.13.0-alpha01.klib",
23
+ "sha256": "0e3c251301e0df405e50d0aa7d45b401c1aa26f7ed0a7001c6ce2bc68f5d667b"
24
+ },
25
+ {
26
+ "name": "foundation-wasm-js-1.13.0-alpha01.klib",
27
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/foundation/foundation-wasm-js/1.13.0-alpha01/foundation-wasm-js-1.13.0-alpha01.klib",
28
+ "sha256": "d3469608beb11d460008b0902886080dd1b199b524edbe3a4073feaf6a00e259"
29
+ },
30
+ {
31
+ "name": "material3-wasm-js-1.13.0-alpha01.klib",
32
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/material3/material3-wasm-js/1.13.0-alpha01/material3-wasm-js-1.13.0-alpha01.klib",
33
+ "sha256": "6187e199922b061cffa16fd9ae2ed920d6a59f0b0f7c3207e829b983ff132d38"
34
+ },
35
+ {
36
+ "name": "skiko-wasm-js-0.152.0-alpha02-peach-a480f0730dab.klib",
37
+ "url": "https://r2.rnxsim.com/peach-kotlin-fork/a480f0730dabea887e2fa22f5f5683454d3594445557a8d8149647af90d3d312/skiko-wasm-js-0.152.0-alpha02.klib",
38
+ "sha256": "a480f0730dabea887e2fa22f5f5683454d3594445557a8d8149647af90d3d312"
39
+ },
40
+ {
41
+ "name": "annotation-wasm-js-1.9.1.klib",
42
+ "url": "https://dl.google.com/dl/android/maven2/androidx/annotation/annotation-wasm-js/1.9.1/annotation-wasm-js-1.9.1.klib",
43
+ "sha256": "5e87a5014d86c4a23b7dc08f049d39b38ec95d2cdf7ee63273f73ef04e3b08fd"
44
+ },
45
+ {
46
+ "name": "runtime-retain-wasm-js-1.13.0-alpha02.klib",
47
+ "url": "https://dl.google.com/dl/android/maven2/androidx/compose/runtime/runtime-retain-wasm-js/1.13.0-alpha02/runtime-retain-wasm-js-1.13.0-alpha02.klib",
48
+ "sha256": "734c5747b5d5f003ccf9b9a7a46f40f177272124c2306329a70be743e3602b80"
49
+ },
50
+ {
51
+ "name": "lifecycle-runtime-compose-wasm-js-2.9.6.klib",
52
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/androidx/lifecycle/lifecycle-runtime-compose-wasm-js/2.9.6/lifecycle-runtime-compose-wasm-js-2.9.6.klib",
53
+ "sha256": "315b22ed2b68ae42b6609bdfcf59cfb60419d396dffe461b111c7a335a9f606d"
54
+ },
55
+ {
56
+ "name": "runtime-saveable-wasm-js-1.13.0-alpha01.klib",
57
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/runtime/runtime-saveable-wasm-js/1.13.0-alpha01/runtime-saveable-wasm-js-1.13.0-alpha01.klib",
58
+ "sha256": "514ec901f159d5599a25456d4604492b1773bf30d6387aaa0c3173a143eb9d1e"
59
+ },
60
+ {
61
+ "name": "ui-geometry-wasm-js-1.13.0-alpha01.klib",
62
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-geometry-wasm-js/1.13.0-alpha01/ui-geometry-wasm-js-1.13.0-alpha01.klib",
63
+ "sha256": "27fa08a7adca6d217c81ab67b7339eb8e9067c9af21ebd338f136a4cb3466e98"
64
+ },
65
+ {
66
+ "name": "ui-graphics-wasm-js-1.13.0-alpha01.klib",
67
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-graphics-wasm-js/1.13.0-alpha01/ui-graphics-wasm-js-1.13.0-alpha01.klib",
68
+ "sha256": "63f16892ab6435778c60e217a0959516f4fcd46cad8862d6831f055ac30f09d8"
69
+ },
70
+ {
71
+ "name": "ui-skiko-wasm-js-1.13.0-alpha01.klib",
72
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-skiko-wasm-js/1.13.0-alpha01/ui-skiko-wasm-js-1.13.0-alpha01.klib",
73
+ "sha256": "dab0b337dd99ec99e8a3cc4efd365d8101db050971490eff6839fc566aeadc6c"
74
+ },
75
+ {
76
+ "name": "ui-text-wasm-js-1.13.0-alpha01-peach-a2c25f211136.klib",
77
+ "url": "https://r2.rnxsim.com/peach-kotlin-fork/a2c25f2111369c638e785f192312934a78fcacc15186da681429b580b143ddd7/ui-text-wasm-js-1.13.0-alpha01.klib",
78
+ "sha256": "a2c25f2111369c638e785f192312934a78fcacc15186da681429b580b143ddd7"
79
+ },
80
+ {
81
+ "name": "ui-unit-wasm-js-1.13.0-alpha01.klib",
82
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-unit-wasm-js/1.13.0-alpha01/ui-unit-wasm-js-1.13.0-alpha01.klib",
83
+ "sha256": "ea8b94a6a8c5ecc3a81ad3e9ca915bf71d565430d1a44b653f40674eeb1c3898"
84
+ },
85
+ {
86
+ "name": "ui-util-wasm-js-1.13.0-alpha01.klib",
87
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-util-wasm-js/1.13.0-alpha01/ui-util-wasm-js-1.13.0-alpha01.klib",
88
+ "sha256": "b82d203d6b3f09638aa4582e363bc5b4cf679f6ec0cafb5730dfb8e83c8b790b"
89
+ },
90
+ {
91
+ "name": "kotlinx-browser-wasm-js-0.5.0.klib",
92
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-browser-wasm-js/0.5.0/kotlinx-browser-wasm-js-0.5.0.klib",
93
+ "sha256": "00d542206fff41458574ab7341e80f13629743af68621dd5d3750cd836ca70e5"
94
+ },
95
+ {
96
+ "name": "collection-wasm-js-1.5.0.klib",
97
+ "url": "https://dl.google.com/dl/android/maven2/androidx/collection/collection-wasm-js/1.5.0/collection-wasm-js-1.5.0.klib",
98
+ "sha256": "d9683654846b8fdf82f412841351f7df77fbafa105f9022f84697d9a35746610"
99
+ },
100
+ {
101
+ "name": "lifecycle-viewmodel-compose-wasm-js-2.11.0.klib",
102
+ "url": "https://dl.google.com/dl/android/maven2/androidx/lifecycle/lifecycle-viewmodel-compose-wasm-js/2.11.0/lifecycle-viewmodel-compose-wasm-js-2.11.0.klib",
103
+ "sha256": "626eef5d606751a9e9d8481456c67286ca46fa6662b7f52fabd7bfd862ee7989"
104
+ },
105
+ {
106
+ "name": "lifecycle-viewmodel-savedstate-wasm-js-2.11.0.klib",
107
+ "url": "https://dl.google.com/dl/android/maven2/androidx/lifecycle/lifecycle-viewmodel-savedstate-wasm-js/2.11.0/lifecycle-viewmodel-savedstate-wasm-js-2.11.0.klib",
108
+ "sha256": "b0798ce9ab60c54408c7ad034010583d4284105e9ae6910724235a00bb787e36"
109
+ },
110
+ {
111
+ "name": "lifecycle-viewmodel-wasm-js-2.9.6.klib",
112
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/androidx/lifecycle/lifecycle-viewmodel-wasm-js/2.9.6/lifecycle-viewmodel-wasm-js-2.9.6.klib",
113
+ "sha256": "0abcd3610e6c2aad806f74e28894ec6f9c6801e2907f6502ecf615af8093d779"
114
+ },
115
+ {
116
+ "name": "lifecycle-viewmodel-savedstate-wasm-js-2.9.6.klib",
117
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/androidx/lifecycle/lifecycle-viewmodel-savedstate-wasm-js/2.9.6/lifecycle-viewmodel-savedstate-wasm-js-2.9.6.klib",
118
+ "sha256": "fb731668d9f08db92a3ce6ada46fc43dc18fc8e12023f991bc8adc3d6f34e7ba"
119
+ },
120
+ {
121
+ "name": "navigationevent-compose-wasm-js-1.1.0.klib",
122
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/androidx/navigationevent/navigationevent-compose-wasm-js/1.1.0/navigationevent-compose-wasm-js-1.1.0.klib",
123
+ "sha256": "6e7d98425e402a4ec15a2151ff2cda820c25b751018c24dff989caaf12dca3d2"
124
+ },
125
+ {
126
+ "name": "annotation-wasm-js-1.10.0.klib",
127
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/annotation-internal/annotation-wasm-js/1.10.0/annotation-wasm-js-1.10.0.klib",
128
+ "sha256": "e198217f9b872a94baa3cea1bb51865ea65a4a94ab9ba9ccec66be9f43728d90"
129
+ },
130
+ {
131
+ "name": "collection-wasm-js-1.10.0.klib",
132
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/collection-internal/collection-wasm-js/1.10.0/collection-wasm-js-1.10.0.klib",
133
+ "sha256": "66ec177eb2c1bff4075dfbca127d260a6eb190256025f00aea7179d09a74aafa"
134
+ },
135
+ {
136
+ "name": "runtime-wasm-js-1.13.0-alpha01.klib",
137
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/runtime/runtime-wasm-js/1.13.0-alpha01/runtime-wasm-js-1.13.0-alpha01.klib",
138
+ "sha256": "a9bcc52f6401d000e40d609e9c6e523fea7073f714cbe688df4431ee3cf9eb59"
139
+ },
140
+ {
141
+ "name": "ui-backhandler-wasm-js-1.13.0-alpha01.klib",
142
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-backhandler-wasm-js/1.13.0-alpha01/ui-backhandler-wasm-js-1.13.0-alpha01.klib",
143
+ "sha256": "4b378d74977f99911ae3add4d33f805339bbedc2002de26d22f41eba48729605"
144
+ },
145
+ {
146
+ "name": "animation-wasm-js-1.13.0-alpha01.klib",
147
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/animation/animation-wasm-js/1.13.0-alpha01/animation-wasm-js-1.13.0-alpha01.klib",
148
+ "sha256": "ad682f57dd9d5e47d052c3461cc3c6dfd1fb8afa6299e27ca8c41f661085d74c"
149
+ },
150
+ {
151
+ "name": "foundation-layout-wasm-js-1.13.0-alpha01.klib",
152
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/foundation/foundation-layout-wasm-js/1.13.0-alpha01/foundation-layout-wasm-js-1.13.0-alpha01.klib",
153
+ "sha256": "fd2c8b1841199fe4bdf4f97eb150681500816102ef0ad65eb6e8274eae9fd695"
154
+ },
155
+ {
156
+ "name": "graphics-shapes-wasm-js-1.1.0.klib",
157
+ "url": "https://dl.google.com/dl/android/maven2/androidx/graphics/graphics-shapes-wasm-js/1.1.0/graphics-shapes-wasm-js-1.1.0.klib",
158
+ "sha256": "80274d9f044765896f0efd1e62205b8cdcf982fcfa20cc6f8562d373ec185d9e"
159
+ },
160
+ {
161
+ "name": "material-ripple-wasm-js-1.13.0-alpha01.klib",
162
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/material/material-ripple-wasm-js/1.13.0-alpha01/material-ripple-wasm-js-1.13.0-alpha01.klib",
163
+ "sha256": "f8f5f5f98b646beca11c375bbb0ca57592ee3b4b2e52164c17ddf7192dc7cb63"
164
+ },
165
+ {
166
+ "name": "animation-core-wasm-js-1.13.0-alpha01.klib",
167
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/animation/animation-core-wasm-js/1.13.0-alpha01/animation-core-wasm-js-1.13.0-alpha01.klib",
168
+ "sha256": "756349d87f7f118fdd8730ae089417f4abb03c27201b7b3131492924fc1e3b44"
169
+ },
170
+ {
171
+ "name": "material3-ripple-wasm-js-1.13.0-alpha01.klib",
172
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/compose/material3/material3-ripple-wasm-js/1.13.0-alpha01/material3-ripple-wasm-js-1.13.0-alpha01.klib",
173
+ "sha256": "00486418ef2eda46067c91998fd96e9490ae1deb2284a19cdcbf7f963dbf1d5f"
174
+ },
175
+ {
176
+ "name": "kotlinx-datetime-wasm-js-0.7.1.klib",
177
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-datetime-wasm-js/0.7.1/kotlinx-datetime-wasm-js-0.7.1.klib",
178
+ "sha256": "f65802db1f945d5c8f99cfed76408d2853076787132cbb7674ac672646eaa99a"
179
+ },
180
+ {
181
+ "name": "runtime-wasm-js-1.13.0-alpha02.klib",
182
+ "url": "https://dl.google.com/dl/android/maven2/androidx/compose/runtime/runtime-wasm-js/1.13.0-alpha02/runtime-wasm-js-1.13.0-alpha02.klib",
183
+ "sha256": "e80449bdc34d7fb093659c22c0504873836958a31ad9794677fe23b80a89273c"
184
+ },
185
+ {
186
+ "name": "lifecycle-runtime-wasm-js-2.9.6.klib",
187
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/androidx/lifecycle/lifecycle-runtime-wasm-js/2.9.6/lifecycle-runtime-wasm-js-2.9.6.klib",
188
+ "sha256": "297fa51eaa893495f548e0e9e0fe66f5d11dd21bb55800a55efadc66d71a92b2"
189
+ },
190
+ {
191
+ "name": "lifecycle-common-wasm-js-2.9.6.klib",
192
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/androidx/lifecycle/lifecycle-common-wasm-js/2.9.6/lifecycle-common-wasm-js-2.9.6.klib",
193
+ "sha256": "56b33bc48c54f1fa12df387eaf2af7c0d930154232d3206483998d1d07a83753"
194
+ },
195
+ {
196
+ "name": "runtime-saveable-wasm-js-1.13.0-alpha02.klib",
197
+ "url": "https://dl.google.com/dl/android/maven2/androidx/compose/runtime/runtime-saveable-wasm-js/1.13.0-alpha02/runtime-saveable-wasm-js-1.13.0-alpha02.klib",
198
+ "sha256": "5a9f215453fcfdb0b5cd2c7bc35a52b398cb018a3ae6fae4d69856bfd214c681"
199
+ },
200
+ {
201
+ "name": "savedstate-compose-wasm-js-1.3.6.klib",
202
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/androidx/savedstate/savedstate-compose-wasm-js/1.3.6/savedstate-compose-wasm-js-1.3.6.klib",
203
+ "sha256": "fff664515a087776e5c1bb925bbd3131008b6f3b3a4c9ad7d7723c34daa80bce"
204
+ },
205
+ {
206
+ "name": "lifecycle-common-wasm-js-2.11.0.klib",
207
+ "url": "https://dl.google.com/dl/android/maven2/androidx/lifecycle/lifecycle-common-wasm-js/2.11.0/lifecycle-common-wasm-js-2.11.0.klib",
208
+ "sha256": "9dd925f7c94d5e40a0fd0f93829005a1af0bbbcf385ff73c63612a46cec6894b"
209
+ },
210
+ {
211
+ "name": "lifecycle-viewmodel-wasm-js-2.11.0.klib",
212
+ "url": "https://dl.google.com/dl/android/maven2/androidx/lifecycle/lifecycle-viewmodel-wasm-js/2.11.0/lifecycle-viewmodel-wasm-js-2.11.0.klib",
213
+ "sha256": "c4c967eb36e83c1a26f7b813d717f18559e156d6fc615fa6e6610a0a2f6da964"
214
+ },
215
+ {
216
+ "name": "kotlinx-serialization-core-wasm-js-1.7.3.klib",
217
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-core-wasm-js/1.7.3/kotlinx-serialization-core-wasm-js-1.7.3.klib",
218
+ "sha256": "4737e08c15e6c8bfd5d283152f3b9e56aaa9f1ef881748d3df0f3e8e5f06a3b5"
219
+ },
220
+ {
221
+ "name": "lifecycle-runtime-compose-wasm-js-2.11.0.klib",
222
+ "url": "https://dl.google.com/dl/android/maven2/androidx/lifecycle/lifecycle-runtime-compose-wasm-js/2.11.0/lifecycle-runtime-compose-wasm-js-2.11.0.klib",
223
+ "sha256": "4c0b9069472156409ba765d4c16b6cb802980606f70e834098bd6e8b28d48d53"
224
+ },
225
+ {
226
+ "name": "savedstate-wasm-js-1.3.6.klib",
227
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/androidx/savedstate/savedstate-wasm-js/1.3.6/savedstate-wasm-js-1.3.6.klib",
228
+ "sha256": "3903e1da0ad516f607ba8cd5a9bfcf46bdf83ad495e85eb8d48a3cd048f281a4"
229
+ },
230
+ {
231
+ "name": "navigationevent-compose-wasm-js-1.1.1.klib",
232
+ "url": "https://dl.google.com/dl/android/maven2/androidx/navigationevent/navigationevent-compose-wasm-js/1.1.1/navigationevent-compose-wasm-js-1.1.1.klib",
233
+ "sha256": "f6b515ad2f45464df805f3d8cda612c3f2bbe437e24e7bdd521c617344408b32"
234
+ },
235
+ {
236
+ "name": "runtime-annotation-wasm-js-1.13.0-alpha02.klib",
237
+ "url": "https://dl.google.com/dl/android/maven2/androidx/compose/runtime/runtime-annotation-wasm-js/1.13.0-alpha02/runtime-annotation-wasm-js-1.13.0-alpha02.klib",
238
+ "sha256": "a0136b86702ec7e7b054329e09a7b70e6fab6970bf6ac6af8c5f64d4a59e264b"
239
+ },
240
+ {
241
+ "name": "savedstate-compose-wasm-js-1.5.0.klib",
242
+ "url": "https://dl.google.com/dl/android/maven2/androidx/savedstate/savedstate-compose-wasm-js/1.5.0/savedstate-compose-wasm-js-1.5.0.klib",
243
+ "sha256": "7cc6d441d3f029e56f55c7452613c6c59de3aaa18e6d8346df679c13849eb19c"
244
+ },
245
+ {
246
+ "name": "lifecycle-runtime-wasm-js-2.11.0.klib",
247
+ "url": "https://dl.google.com/dl/android/maven2/androidx/lifecycle/lifecycle-runtime-wasm-js/2.11.0/lifecycle-runtime-wasm-js-2.11.0.klib",
248
+ "sha256": "cd5be533d2b73bfd432e5968cf724979f36378492491cbeea4594bcc9a7b9ea3"
249
+ },
250
+ {
251
+ "name": "navigationevent-wasm-js-1.1.1.klib",
252
+ "url": "https://dl.google.com/dl/android/maven2/androidx/navigationevent/navigationevent-wasm-js/1.1.1/navigationevent-wasm-js-1.1.1.klib",
253
+ "sha256": "b449f3fcf62a633aec3e7d1d57b8aeaf32742d89bb1da21e4815d7aa001c40db"
254
+ },
255
+ {
256
+ "name": "savedstate-wasm-js-1.5.0.klib",
257
+ "url": "https://dl.google.com/dl/android/maven2/androidx/savedstate/savedstate-wasm-js/1.5.0/savedstate-wasm-js-1.5.0.klib",
258
+ "sha256": "02bb90d1173b771a9eb4ff9d2440bbe50202f0d9b0578abb2f5b47b1c27285ef"
259
+ }
260
+ ],
261
+ "compose": {
262
+ "multiplatform": "1.13.0-alpha01",
263
+ "android": {
264
+ "ui": "1.13.0-alpha02",
265
+ "foundation": "1.13.0-alpha02",
266
+ "runtime": "1.13.0-alpha02",
267
+ "material3": "1.5.0-alpha27",
268
+ "materialRipple": "1.13.0-alpha02",
269
+ "material3Ripple": "1.5.0-alpha27"
270
+ },
271
+ "mappingSources": [
272
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-android/1.13.0-alpha01/ui-android-1.13.0-alpha01.module",
273
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/foundation/foundation-android/1.13.0-alpha01/foundation-android-1.13.0-alpha01.module",
274
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/material3/material3-android/1.13.0-alpha01/material3-android-1.13.0-alpha01.module",
275
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/runtime/runtime-saveable-android/1.13.0-alpha01/runtime-saveable-android-1.13.0-alpha01.module",
276
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-geometry-android/1.13.0-alpha01/ui-geometry-android-1.13.0-alpha01.module",
277
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-graphics-android/1.13.0-alpha01/ui-graphics-android-1.13.0-alpha01.module",
278
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-skiko-android/1.13.0-alpha01/ui-skiko-android-1.13.0-alpha01.module",
279
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-text-android/1.13.0-alpha01/ui-text-android-1.13.0-alpha01.module",
280
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-unit-android/1.13.0-alpha01/ui-unit-android-1.13.0-alpha01.module",
281
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-util-android/1.13.0-alpha01/ui-util-android-1.13.0-alpha01.module",
282
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/runtime/runtime-android/1.13.0-alpha01/runtime-android-1.13.0-alpha01.module",
283
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-backhandler-android/1.13.0-alpha01/ui-backhandler-android-1.13.0-alpha01.module",
284
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/animation/animation-android/1.13.0-alpha01/animation-android-1.13.0-alpha01.module",
285
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/foundation/foundation-layout-android/1.13.0-alpha01/foundation-layout-android-1.13.0-alpha01.module",
286
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/material/material-ripple-android/1.13.0-alpha01/material-ripple-android-1.13.0-alpha01.module",
287
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/animation/animation-core-android/1.13.0-alpha01/animation-core-android-1.13.0-alpha01.module",
288
+ "https://repo1.maven.org/maven2/org/jetbrains/compose/material3/material3-ripple-android/1.13.0-alpha01/material3-ripple-android-1.13.0-alpha01.module"
289
+ ],
290
+ "skiko": "0.152.0-alpha02"
291
+ },
292
+ "composeRuntime": {
293
+ "name": "skiko-wasm-0.152.0-alpha02.jar",
294
+ "url": "https://repo1.maven.org/maven2/org/jetbrains/skiko/skiko-wasm-js/0.152.0-alpha02/skiko-wasm-js-0.152.0-alpha02-skiko-runtime.jar",
295
+ "sha256": "14e37c567f10d906a10a74df80b44ee5a5dd5e3a75929f351a32d5b123dad643"
296
+ },
297
+ "composeJsLibraries": [
298
+ {
299
+ "name": "js-joda-core-3.2.0.tgz",
300
+ "url": "https://registry.npmjs.org/@js-joda/core/-/core-3.2.0.tgz",
301
+ "sha256": "853990e161b83efc5c38b26e6ad5d88d380803aff8dbed1aedcefda2360f31be",
302
+ "module": "@js-joda/core",
303
+ "file": "js-joda-core.mjs",
304
+ "archiveEntry": "package/dist/js-joda.esm.js"
305
+ }
18
306
  ]
19
307
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peachsim",
3
- "version": "0.1.628",
3
+ "version": "0.1.630",
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",
@@ -47,10 +47,10 @@
47
47
  "source": "./src/vite-plugin-swift.ts",
48
48
  "default": "./dist-lib/vite-swift.cjs"
49
49
  },
50
- "./vite-kotlin": {
51
- "types": "./src/vite-plugin-kotlin.ts",
52
- "source": "./src/vite-plugin-kotlin.ts",
53
- "default": "./dist-lib/vite-kotlin.cjs"
50
+ "./kotlin-host": {
51
+ "types": "./src/kotlin-host.ts",
52
+ "source": "./src/kotlin-host.ts",
53
+ "default": "./dist-lib/kotlin-host.cjs"
54
54
  },
55
55
  "./swift-submit": {
56
56
  "types": "./src/swift-submit.ts",
@@ -84,6 +84,13 @@
84
84
  "import": "./dist-lib/metro-production-bundle.mjs",
85
85
  "default": "./dist-lib/metro-production-bundle.cjs"
86
86
  },
87
+ "./native-app-identity": {
88
+ "types": "./src/native-app-identity.ts",
89
+ "source": "./src/native-app-identity.ts",
90
+ "bun": "./src/native-app-identity.ts",
91
+ "import": "./dist-lib/native-app-identity.mjs",
92
+ "default": "./dist-lib/native-app-identity.cjs"
93
+ },
87
94
  "./metro-fingerprint-registry": {
88
95
  "types": "./src/metro-fingerprint-registry.ts",
89
96
  "source": "./src/metro-fingerprint-registry.ts",
@@ -0,0 +1,17 @@
1
+ import { existsSync } from 'node:fs'
2
+ import { join } from 'node:path'
3
+ import { rnxHomeDir } from './home-paths'
4
+
5
+ // one policy for automatic CLI checks, runtime updates, and their notices.
6
+ // explicit install, version, and upgrade commands remain user-directed.
7
+ export function automaticPeachUpdatesEnabled(
8
+ env: Readonly<Record<string, string | undefined>> = process.env,
9
+ ): boolean {
10
+ const value = env.PEACH_UPDATE_CHECK?.toLowerCase()
11
+ return (
12
+ value !== '0' &&
13
+ value !== 'false' &&
14
+ value !== 'off' &&
15
+ !existsSync(join(rnxHomeDir(), 'runtime-update-disabled'))
16
+ )
17
+ }
@@ -8,6 +8,7 @@ import {
8
8
  type DiscoveredServer,
9
9
  } from '../../scripts/dev-server-scanner.ts'
10
10
  import { buildBrowserAssetProxyUrl } from '../backend-origin.ts'
11
+ import { automaticPeachUpdatesEnabled } from '../automatic-update-policy.ts'
11
12
  import {
12
13
  AUTOMATION_SIM_IDLE_REAP_TTL_MS,
13
14
  DEFAULT_SOOTSIM_BRIDGE_PORT,
@@ -1342,7 +1343,7 @@ export class SootSimBridgeHost {
1342
1343
 
1343
1344
  private startRuntimeUpdater() {
1344
1345
  if (!this.shouldWriteLockfile || this.runtimeUpdateTimer) return
1345
- if (fs.existsSync(path.join(rnxHomeDir(), 'runtime-update-disabled'))) {
1346
+ if (!automaticPeachUpdatesEnabled()) {
1346
1347
  this.bootstrapping = false
1347
1348
  if (this.httpServer) this.writeLockfileSnapshot()
1348
1349
  return
@@ -1365,6 +1366,7 @@ export class SootSimBridgeHost {
1365
1366
  }
1366
1367
 
1367
1368
  private runRuntimeUpdate(reason: 'startup' | 'periodic'): Promise<void> {
1369
+ if (!automaticPeachUpdatesEnabled()) return Promise.resolve()
1368
1370
  if (this.runtimeUpdateInFlight) return this.runtimeUpdateInFlight
1369
1371
  this.runtimeUpdateInFlight = (async () => {
1370
1372
  try {
@@ -1,8 +1,8 @@
1
1
  // Peach's Kotlin host for One apps on an Android device: every Kotlin source
2
2
  // the app holds compiles, with One's generated dispatch glue, into one
3
3
  // Kotlin/Wasm module, as prebuild compiles them all into the one app process.
4
- // the vite plugin loads this on the first /__peach/kotlin request, so an app
5
- // with no Kotlin never evaluates it.
4
+ // any http host loads this on the first /__peach/kotlin request and answers
5
+ // it with serveKotlinRequest, so an app with no Kotlin never evaluates it.
6
6
 
7
7
  import { execFile } from 'node:child_process'
8
8
  import { createHash } from 'node:crypto'
@@ -26,6 +26,14 @@ interface Download {
26
26
  interface KotlinToolchain {
27
27
  compiler: Download & { version: string }
28
28
  libraries: (Download & { name: string })[]
29
+ composeLibraries: (Download & { name: string })[]
30
+ composeRuntime: Download & { name: string }
31
+ composeJsLibraries: (Download & {
32
+ name: string
33
+ module: string
34
+ file: string
35
+ archiveEntry: string
36
+ })[]
29
37
  }
30
38
 
31
39
  export interface KotlinArtifact {
@@ -49,17 +57,49 @@ function readToolchain(moduleRoot: string): KotlinToolchain {
49
57
  )
50
58
  return { url: value.url, sha256: value.sha256 }
51
59
  }
52
- if (!isRecord(parsed) || !isRecord(parsed.compiler) || !Array.isArray(parsed.libraries))
60
+ if (
61
+ !isRecord(parsed) ||
62
+ !isRecord(parsed.compiler) ||
63
+ !Array.isArray(parsed.libraries) ||
64
+ !Array.isArray(parsed.composeLibraries) ||
65
+ !Array.isArray(parsed.composeJsLibraries) ||
66
+ !isRecord(parsed.composeRuntime) ||
67
+ typeof parsed.composeRuntime.name !== 'string'
68
+ )
53
69
  throw new Error('peachsim kotlin/toolchain.json has no compiler and libraries')
54
70
  const version = parsed.compiler.version
55
71
  if (typeof version !== 'string')
56
72
  throw new Error('peachsim kotlin/toolchain.json has no compiler version')
57
- return {
58
- compiler: { ...download(parsed.compiler), version },
59
- libraries: parsed.libraries.map((library) => {
73
+ const libraries = (values: unknown[]) =>
74
+ values.map((library) => {
60
75
  if (!isRecord(library) || typeof library.name !== 'string')
61
76
  throw new Error('peachsim kotlin/toolchain.json names a library without a name')
62
77
  return { ...download(library), name: library.name }
78
+ })
79
+ return {
80
+ compiler: { ...download(parsed.compiler), version },
81
+ libraries: libraries(parsed.libraries),
82
+ composeLibraries: libraries(parsed.composeLibraries),
83
+ composeRuntime: {
84
+ ...download(parsed.composeRuntime),
85
+ name: parsed.composeRuntime.name,
86
+ },
87
+ composeJsLibraries: parsed.composeJsLibraries.map((library) => {
88
+ if (
89
+ !isRecord(library) ||
90
+ typeof library.name !== 'string' ||
91
+ typeof library.module !== 'string' ||
92
+ typeof library.file !== 'string' ||
93
+ typeof library.archiveEntry !== 'string'
94
+ )
95
+ throw new Error('peachsim kotlin/toolchain.json has an incomplete JS library')
96
+ return {
97
+ ...download(library),
98
+ name: library.name,
99
+ module: library.module,
100
+ file: library.file,
101
+ archiveEntry: library.archiveEntry,
102
+ }
63
103
  }),
64
104
  }
65
105
  }
@@ -207,7 +247,7 @@ function entrySource(ids: string[]): string {
207
247
  ' } else {',
208
248
  ' reply.put("ok", true).put("value", dispatch.call(module, method, argsJson))',
209
249
  ' }',
210
- ' } catch (error: Exception) {',
250
+ ' } catch (error: Throwable) {',
211
251
  ' reply.put("ok", false).put("code", "E_NATIVE_SOURCE").put("error", "$module.$method: ${error.message}")',
212
252
  ' }',
213
253
  ' reply.toString().toJsString()',
@@ -216,7 +256,7 @@ function entrySource(ids: string[]): string {
216
256
  ].join('\n')
217
257
  }
218
258
 
219
- const BUILD_FORMAT = 1
259
+ const BUILD_FORMAT = 4
220
260
  const builds = new Map<string, Promise<KotlinArtifact>>()
221
261
 
222
262
  function buildsDir(): string {
@@ -238,8 +278,11 @@ export async function kotlinArtifact(
238
278
  if (sources.length === 0) throw new Error(`${root} holds no Kotlin sources`)
239
279
  const generated: Record<string, string> = {}
240
280
  const ids: string[] = []
281
+ let usesCompose = false
241
282
  for (const file of sources) {
242
- const contract = nativeSourceContract(file, fs.readFileSync(file, 'utf8'))
283
+ const source = fs.readFileSync(file, 'utf8')
284
+ if (/\bandroidx\.compose\./.test(source)) usesCompose = true
285
+ const contract = nativeSourceContract(file, source)
243
286
  if (contract.modules.length === 0) continue
244
287
  const id = kotlinSourceId(root, file)
245
288
  ids.push(id)
@@ -255,25 +298,54 @@ export async function kotlinArtifact(
255
298
  for (const [name, text] of Object.entries(generated))
256
299
  digest.update(`${name}\0${text}\0`)
257
300
  const hash = digest.digest('hex').slice(0, 24)
258
- const artifact = { url: `${origin}${KOTLIN_ARTIFACT_PREFIX}${hash}/app.mjs`, hash }
301
+ const artifact = {
302
+ url: `${origin}${KOTLIN_ARTIFACT_PREFIX}${hash}/app.mjs`,
303
+ hash,
304
+ }
259
305
  const out = path.join(buildsDir(), hash)
260
306
  if (fs.existsSync(path.join(out, 'js', 'app.wasm'))) return artifact
261
307
  const pending = builds.get(hash)
262
308
  if (pending) return pending
263
309
  const build = (async () => {
264
- const { kotlinc, libraries } = await ensureToolchain(toolchain)
310
+ const ready = await ensureToolchain(toolchain)
311
+ const { kotlinc } = ready
312
+ const libraries = [...ready.libraries]
313
+ const composeRuntime = path.join(
314
+ kotlinHome(),
315
+ toolchain.compiler.version,
316
+ toolchain.composeRuntime.name,
317
+ )
318
+ if (usesCompose) {
319
+ for (const library of toolchain.composeLibraries) {
320
+ const target = path.join(kotlinHome(), toolchain.compiler.version, library.name)
321
+ await fetchVerified(library, target)
322
+ libraries.push(target)
323
+ }
324
+ await fetchVerified(toolchain.composeRuntime, composeRuntime)
325
+ }
265
326
  fs.mkdirSync(buildsDir(), { recursive: true })
266
327
  const work = fs.mkdtempSync(path.join(buildsDir(), `${hash}-`))
267
328
  const generatedDir = path.join(work, 'generated')
268
329
  fs.mkdirSync(generatedDir)
269
330
  for (const [name, text] of Object.entries(generated))
270
331
  fs.writeFileSync(path.join(generatedDir, name), text)
271
- const common = ['-Xwasm-target=js', '-libraries', libraries.join(path.delimiter)]
332
+ const common = [
333
+ // the full upstream Compose graph exceeds kotlinc's 512 mib default heap.
334
+ '-J-Xmx2g',
335
+ '-Xwasm-target=js',
336
+ '-libraries',
337
+ libraries.join(path.delimiter),
338
+ ]
272
339
  try {
273
340
  await run(
274
341
  kotlinc,
275
342
  [
276
343
  ...common,
344
+ ...(usesCompose
345
+ ? [
346
+ `-Xplugin=${path.resolve(path.dirname(kotlinc), '../lib/compose-compiler-plugin.jar')}`,
347
+ ]
348
+ : []),
277
349
  '-language-version',
278
350
  language,
279
351
  '-api-version',
@@ -304,6 +376,45 @@ export async function kotlinArtifact(
304
376
  ],
305
377
  { maxBuffer: 16 * 1024 * 1024 },
306
378
  )
379
+ if (usesCompose)
380
+ await run('unzip', [
381
+ '-q',
382
+ '-j',
383
+ composeRuntime,
384
+ 'skiko.mjs',
385
+ 'skiko.wasm',
386
+ '-d',
387
+ path.join(work, 'js'),
388
+ ])
389
+ // kotlin's npm externals remain bare imports after linking. publish the
390
+ // exact upstream ES modules beside the generated loader for workers.
391
+ if (usesCompose) {
392
+ for (const library of toolchain.composeJsLibraries) {
393
+ for (const file of fs.readdirSync(path.join(work, 'js'))) {
394
+ if (!file.endsWith('.mjs')) continue
395
+ const target = path.join(work, 'js', file)
396
+ const source = fs.readFileSync(target, 'utf8')
397
+ let next = source
398
+ for (const quote of ["'", '"'])
399
+ next = next.replaceAll(
400
+ `from ${quote}${library.module}${quote}`,
401
+ `from ${quote}./${library.file}${quote}`,
402
+ )
403
+ if (next === source) continue
404
+ const archive = path.join(
405
+ kotlinHome(),
406
+ toolchain.compiler.version,
407
+ library.name,
408
+ )
409
+ await fetchVerified(library, archive)
410
+ const { stdout } = await run('tar', ['-xOf', archive, library.archiveEntry], {
411
+ maxBuffer: 16 * 1024 * 1024,
412
+ })
413
+ fs.writeFileSync(path.join(work, 'js', library.file), stdout)
414
+ fs.writeFileSync(target, next)
415
+ }
416
+ }
417
+ }
307
418
  } catch (error) {
308
419
  fs.rmSync(work, { recursive: true, force: true })
309
420
  const output = isRecord(error)
@@ -374,3 +485,35 @@ export function serveKotlinArtifact(pathname: string, res: ServerResponse): bool
374
485
  res.end(fs.readFileSync(target))
375
486
  return true
376
487
  }
488
+
489
+ export const KOTLIN_PACKAGE_PATH = '/__peach/kotlin-package'
490
+
491
+ // peachsim's own Kotlin module (toolchain pins and shims) beside the app's
492
+ // installed peachsim
493
+ export function peachKotlinModuleRoot(root: string): string {
494
+ const peachsimPackage = createRequire(path.join(root, 'package.json')).resolve(
495
+ 'peachsim/package.json',
496
+ )
497
+ return path.join(path.dirname(peachsimPackage), 'kotlin')
498
+ }
499
+
500
+ // answers one /__peach/kotlin* request: the app's compiled module description,
501
+ // then the files it names. false leaves the request to the host.
502
+ export async function serveKotlinRequest(
503
+ pathname: string,
504
+ res: ServerResponse,
505
+ app: { root: string; moduleRoot: string; origin: string; hmrPath: string },
506
+ ): Promise<boolean> {
507
+ if (serveKotlinArtifact(pathname, res)) return true
508
+ if (pathname !== KOTLIN_PACKAGE_PATH) return false
509
+ res.setHeader('access-control-allow-origin', '*')
510
+ try {
511
+ const artifact = await kotlinArtifact(app.root, app.moduleRoot, app.origin)
512
+ res.setHeader('content-type', 'application/json')
513
+ res.end(JSON.stringify({ ...artifact, hmrPath: app.hmrPath }))
514
+ } catch (error) {
515
+ res.statusCode = 500
516
+ res.end(error instanceof Error ? error.message : String(error))
517
+ }
518
+ return true
519
+ }
@@ -24,6 +24,7 @@ import {
24
24
  toRNXProductionBundleUrl,
25
25
  type RNXMetroModuleIdentityMetadata,
26
26
  } from './metro-production-bundle'
27
+ import { readNativeFirebaseConfig } from './native-firebase-config'
27
28
  import {
28
29
  isRootRuntimeAssetPath,
29
30
  resolveRuntimeFilePath,
@@ -249,6 +250,23 @@ export function withRNX<T extends Record<string, unknown>>(config: T): T {
249
250
  return
250
251
  }
251
252
 
253
+ if ((req.url || '').split('?')[0] === '/__peach-native-firebase-config') {
254
+ try {
255
+ res.setHeader('Content-Type', 'application/json')
256
+ res.setHeader('Cache-Control', 'no-store')
257
+ res.setHeader('Access-Control-Allow-Origin', '*')
258
+ res.end(JSON.stringify(readNativeFirebaseConfig(cfgProjectRoot)))
259
+ } catch (error) {
260
+ res.statusCode = 400
261
+ res.end(
262
+ JSON.stringify({
263
+ error: error instanceof Error ? error.message : String(error),
264
+ }),
265
+ )
266
+ }
267
+ return
268
+ }
269
+
252
270
  const url = req.url || ''
253
271
  const pathname = url.split('?')[0]
254
272