@callstack/react-native-brownfield 5.0.1 → 5.1.0
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/CHANGELOG.md +381 -0
- package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt +25 -0
- package/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeFragment.kt +20 -0
- package/gradle-plugin/brownfield/gradlew +0 -0
- package/ios/BrownfieldReactHostPreloader.h +30 -0
- package/ios/BrownfieldReactHostPreloader.m +113 -0
- package/ios/Expo/ExpoHostRuntime.swift +70 -8
- package/ios/JSBundleLoadObserver.swift +64 -17
- package/ios/ReactHostPreloading.swift +177 -0
- package/ios/ReactNativeBrownfield.swift +36 -1
- package/ios/Vanilla/ReactNativeHostRuntime.swift +28 -6
- package/lib/commonjs/expo-config-plugin/template/android/ReactNativeHostManager.post55.kt +6 -1
- package/lib/commonjs/scripts/brownfield.js +0 -0
- package/lib/module/expo-config-plugin/template/android/ReactNativeHostManager.post55.kt +6 -1
- package/package.json +3 -3
- package/src/expo-config-plugin/template/android/ReactNativeHostManager.post55.kt +6 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# @callstack/react-native-brownfield
|
|
2
|
+
|
|
3
|
+
## 5.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#450](https://github.com/callstack/react-native-brownfield/pull/450) [`4846a05`](https://github.com/callstack/react-native-brownfield/commit/4846a055eb06f8c8dea08b33d0bb0d1b2a2f2f86) Thanks [@borisyankov](https://github.com/borisyankov)! - Add `preloadBundle` to `startReactNative` on iOS. Without a preload, `startReactNative` only makes the factory, and React Native loads the JavaScript bundle when it creates the first React Native view. `startReactNative(launchOptions:preloadBundle:onBundleLoaded:)` moves that work to the app launch: the call starts the React Host, and React Native evaluates the bundle on the JavaScript thread, in parallel with the remainder of the app launch. On Android, `ReactNativeBrownfield.initialize` does the same operation. This shape of `startReactNative` also takes the launch options for the React Host.
|
|
8
|
+
|
|
9
|
+
`onBundleLoaded` now runs on the main thread, and not on the JavaScript thread. A callback that you add after React Native loaded the bundle runs in the next turn of the main run loop.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#381](https://github.com/callstack/react-native-brownfield/pull/381) [`b8e8da5`](https://github.com/callstack/react-native-brownfield/commit/b8e8da50fbf20058c5c2745981c7deb5cb33061a) Thanks [@alpharius-ck](https://github.com/alpharius-ck)! - e2e tests for android
|
|
14
|
+
- Updated dependencies []:
|
|
15
|
+
- @callstack/brownfield-cli@5.1.0
|
|
16
|
+
|
|
17
|
+
## 5.0.2
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#449](https://github.com/callstack/react-native-brownfield/pull/449) [`83657e7`](https://github.com/callstack/react-native-brownfield/commit/83657e7c0d209161561bff39d6e043a154e350d0) Thanks [@hurali97](https://github.com/hurali97)! - Fix npm publishing by upgrading to Changesets v3 (Yarn rewrites `workspace:` ranges on publish) and correcting package `repository` metadata required for npm provenance.
|
|
22
|
+
- Updated dependencies [[`83657e7`](https://github.com/callstack/react-native-brownfield/commit/83657e7c0d209161561bff39d6e043a154e350d0)]:
|
|
23
|
+
- @callstack/brownfield-cli@5.0.2
|
|
24
|
+
|
|
25
|
+
## 5.0.1
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- [#442](https://github.com/callstack/react-native-brownfield/pull/442) [`7898f8a`](https://github.com/callstack/react-native-brownfield/commit/7898f8a4921a725dd4143516a0d187f0605540c2) Thanks [@janicduplessis](https://github.com/janicduplessis)! - feat: allow extending the list of .so files kept out of the AAR
|
|
30
|
+
|
|
31
|
+
Adds a `reactBrownfield.ignoreEmbeddedLibs` option so a project can name additional native libraries that should not be embedded, next to the built-in `IGNORE_EMBEDDED_LIBS` list.
|
|
32
|
+
|
|
33
|
+
- Updated dependencies []:
|
|
34
|
+
- @callstack/brownfield-cli@5.0.1
|
|
35
|
+
|
|
36
|
+
## 5.0.0
|
|
37
|
+
|
|
38
|
+
### Major Changes
|
|
39
|
+
|
|
40
|
+
- [#424](https://github.com/callstack/react-native-brownfield/pull/424) [`af2b20c`](https://github.com/callstack/react-native-brownfield/commit/af2b20c8e921f702b4c2ce27bf82cd43cb82d068) Thanks [@hurali97](https://github.com/hurali97)! - feat: drop support for Expo SDK 55
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- [#434](https://github.com/callstack/react-native-brownfield/pull/434) [`1183202`](https://github.com/callstack/react-native-brownfield/commit/118320245741d337bf9d6202eb27ee60cc7faa47) Thanks [@hurali97](https://github.com/hurali97)! - fix: dependabot alerts
|
|
45
|
+
|
|
46
|
+
- Updated dependencies [[`1183202`](https://github.com/callstack/react-native-brownfield/commit/118320245741d337bf9d6202eb27ee60cc7faa47)]:
|
|
47
|
+
- @callstack/brownfield-cli@5.0.0
|
|
48
|
+
|
|
49
|
+
## 4.3.0
|
|
50
|
+
|
|
51
|
+
### Minor Changes
|
|
52
|
+
|
|
53
|
+
- [#422](https://github.com/callstack/react-native-brownfield/pull/422) [`8894482`](https://github.com/callstack/react-native-brownfield/commit/8894482efb68d745dd1f8e7433b7a67d94440f0a) Thanks [@hurali97](https://github.com/hurali97)! - feat: support proguard/R8 minification
|
|
54
|
+
|
|
55
|
+
### Patch Changes
|
|
56
|
+
|
|
57
|
+
- Updated dependencies [[`627fcbc`](https://github.com/callstack/react-native-brownfield/commit/627fcbce9811ca12773b3caee319ed4cd610123e), [`8894482`](https://github.com/callstack/react-native-brownfield/commit/8894482efb68d745dd1f8e7433b7a67d94440f0a)]:
|
|
58
|
+
- @callstack/brownfield-cli@4.3.0
|
|
59
|
+
|
|
60
|
+
## 4.2.0
|
|
61
|
+
|
|
62
|
+
### Minor Changes
|
|
63
|
+
|
|
64
|
+
- [#413](https://github.com/callstack/react-native-brownfield/pull/413) [`39cf6a7`](https://github.com/callstack/react-native-brownfield/commit/39cf6a751c62ee701c96468a5a701c0bdf96463b) Thanks [@hurali97](https://github.com/hurali97)! - feat: add option to use local maven
|
|
65
|
+
|
|
66
|
+
### Patch Changes
|
|
67
|
+
|
|
68
|
+
- Updated dependencies [[`39cf6a7`](https://github.com/callstack/react-native-brownfield/commit/39cf6a751c62ee701c96468a5a701c0bdf96463b)]:
|
|
69
|
+
- @callstack/brownfield-cli@4.2.0
|
|
70
|
+
|
|
71
|
+
## 4.1.0
|
|
72
|
+
|
|
73
|
+
### Minor Changes
|
|
74
|
+
|
|
75
|
+
- [#367](https://github.com/callstack/react-native-brownfield/pull/367) [`dd1082a`](https://github.com/callstack/react-native-brownfield/commit/dd1082a42c83f2cb8fd7f03df05a6e0a13e8833c) Thanks [@hurali97](https://github.com/hurali97)! - refactor: remove deprecated APIs
|
|
76
|
+
|
|
77
|
+
### Patch Changes
|
|
78
|
+
|
|
79
|
+
- [#417](https://github.com/callstack/react-native-brownfield/pull/417) [`28b534e`](https://github.com/callstack/react-native-brownfield/commit/28b534ea3f1bfd298b89049a6733eb23b9f7d9fc) Thanks [@hurali97](https://github.com/hurali97)! - fix: merge classes to contain third party libs classes
|
|
80
|
+
|
|
81
|
+
- Updated dependencies [[`dd1082a`](https://github.com/callstack/react-native-brownfield/commit/dd1082a42c83f2cb8fd7f03df05a6e0a13e8833c)]:
|
|
82
|
+
- @callstack/brownfield-cli@4.1.0
|
|
83
|
+
|
|
84
|
+
## 4.0.0
|
|
85
|
+
|
|
86
|
+
### Major Changes
|
|
87
|
+
|
|
88
|
+
- [#407](https://github.com/callstack/react-native-brownfield/pull/407) [`dee9559`](https://github.com/callstack/react-native-brownfield/commit/dee9559d6a1a1169c0824542ec8d2ea5ef6475e7) Thanks [@hurali97](https://github.com/hurali97)! - feat: drop support for expo sdk 54
|
|
89
|
+
|
|
90
|
+
### Patch Changes
|
|
91
|
+
|
|
92
|
+
- [#414](https://github.com/callstack/react-native-brownfield/pull/414) [`803f8ca`](https://github.com/callstack/react-native-brownfield/commit/803f8ca488515d7589d3b36e4ebb57d77df1d43d) Thanks [@artus9033](https://github.com/artus9033)! - fix: duplicated JNI libs on cold publish
|
|
93
|
+
|
|
94
|
+
- Updated dependencies [[`dee9559`](https://github.com/callstack/react-native-brownfield/commit/dee9559d6a1a1169c0824542ec8d2ea5ef6475e7)]:
|
|
95
|
+
- @callstack/brownfield-cli@4.0.0
|
|
96
|
+
|
|
97
|
+
## 3.15.0
|
|
98
|
+
|
|
99
|
+
### Minor Changes
|
|
100
|
+
|
|
101
|
+
- [#410](https://github.com/callstack/react-native-brownfield/pull/410) [`03c2496`](https://github.com/callstack/react-native-brownfield/commit/03c2496989fdafdc0863a97f01df9b7f5cd78a55) Thanks [@hurali97](https://github.com/hurali97)! - bump brownfield-gradle-plugin
|
|
102
|
+
|
|
103
|
+
### Patch Changes
|
|
104
|
+
|
|
105
|
+
- Updated dependencies []:
|
|
106
|
+
- @callstack/brownfield-cli@3.15.0
|
|
107
|
+
|
|
108
|
+
## 3.14.0
|
|
109
|
+
|
|
110
|
+
### Minor Changes
|
|
111
|
+
|
|
112
|
+
- [#360](https://github.com/callstack/react-native-brownfield/pull/360) [`10ff597`](https://github.com/callstack/react-native-brownfield/commit/10ff597c057c04aa093b4e5ae8c5334b169d3d56) Thanks [@adamTrz](https://github.com/adamTrz)! - Expo SDK 56 support
|
|
113
|
+
|
|
114
|
+
### Patch Changes
|
|
115
|
+
|
|
116
|
+
- Updated dependencies [[`10ff597`](https://github.com/callstack/react-native-brownfield/commit/10ff597c057c04aa093b4e5ae8c5334b169d3d56)]:
|
|
117
|
+
- @callstack/brownfield-cli@3.14.0
|
|
118
|
+
|
|
119
|
+
## 3.13.2
|
|
120
|
+
|
|
121
|
+
### Patch Changes
|
|
122
|
+
|
|
123
|
+
- [#401](https://github.com/callstack/react-native-brownfield/pull/401) [`c4410f6`](https://github.com/callstack/react-native-brownfield/commit/c4410f6af4c781cf3513ba55d03fa1b1055a443b) Thanks [@artus9033](https://github.com/artus9033)! - fix: brownfield Gradle Plugin not to depend on \*UpdatesResources task from expo-updates if it is absent
|
|
124
|
+
|
|
125
|
+
- [#398](https://github.com/callstack/react-native-brownfield/pull/398) [`8e90842`](https://github.com/callstack/react-native-brownfield/commit/8e90842291348dcb0542a6787f5cfbb1017532dd) Thanks [@artus9033](https://github.com/artus9033)! - feat: support brownfield unified config file in Expo
|
|
126
|
+
|
|
127
|
+
- [#402](https://github.com/callstack/react-native-brownfield/pull/402) [`3475c3d`](https://github.com/callstack/react-native-brownfield/commit/3475c3db375988ebd63ce01bfd93f4dbb1a55e8d) Thanks [@artus9033](https://github.com/artus9033)! - feat: support local BGP in Expo config plugin
|
|
128
|
+
|
|
129
|
+
- Updated dependencies [[`8e90842`](https://github.com/callstack/react-native-brownfield/commit/8e90842291348dcb0542a6787f5cfbb1017532dd), [`3475c3d`](https://github.com/callstack/react-native-brownfield/commit/3475c3db375988ebd63ce01bfd93f4dbb1a55e8d), [`4088c01`](https://github.com/callstack/react-native-brownfield/commit/4088c01a069306565dd3e279d9132f5dbe861d0b)]:
|
|
130
|
+
- @callstack/brownfield-cli@3.13.2
|
|
131
|
+
|
|
132
|
+
## 3.13.1
|
|
133
|
+
|
|
134
|
+
### Patch Changes
|
|
135
|
+
|
|
136
|
+
- Updated dependencies [[`89bc23c`](https://github.com/callstack/react-native-brownfield/commit/89bc23c00bb85c036fce6d4ea142fb3ba0846deb)]:
|
|
137
|
+
- @callstack/brownfield-cli@3.13.1
|
|
138
|
+
|
|
139
|
+
## 3.13.0
|
|
140
|
+
|
|
141
|
+
### Minor Changes
|
|
142
|
+
|
|
143
|
+
- [#359](https://github.com/callstack/react-native-brownfield/pull/359) [`533569b`](https://github.com/callstack/react-native-brownfield/commit/533569b59a4981669dfb738295b505343623bc32) Thanks [@MrMuzyk](https://github.com/MrMuzyk)! - Expose the Brownfield Android Gradle Plugin source from the npm package for opt-in local patching.
|
|
144
|
+
|
|
145
|
+
- [#339](https://github.com/callstack/react-native-brownfield/pull/339) [`ef835b5`](https://github.com/callstack/react-native-brownfield/commit/ef835b52a130e4cd8770a2db04402cbb066b9c27) Thanks [@Esemesek](https://github.com/Esemesek)! - Added configuration file support for react-native-brownfield packages.
|
|
146
|
+
|
|
147
|
+
### Patch Changes
|
|
148
|
+
|
|
149
|
+
- [#391](https://github.com/callstack/react-native-brownfield/pull/391) [`95dbb43`](https://github.com/callstack/react-native-brownfield/commit/95dbb434d4c526b8f75bfd4c54b1d023e349ccf4) Thanks [@adamTrz](https://github.com/adamTrz)! - Fix Expo iOS framework debug bundle packaging so Debug builds load from Metro when it is available and fall back to embedded bundles without dev-server-only runtime code.
|
|
150
|
+
|
|
151
|
+
- Updated dependencies [[`ef835b5`](https://github.com/callstack/react-native-brownfield/commit/ef835b52a130e4cd8770a2db04402cbb066b9c27)]:
|
|
152
|
+
- @callstack/brownfield-cli@3.13.0
|
|
153
|
+
|
|
154
|
+
## 3.12.0
|
|
155
|
+
|
|
156
|
+
### Minor Changes
|
|
157
|
+
|
|
158
|
+
- [#237](https://github.com/callstack/react-native-brownfield/pull/237) [`4186cc8`](https://github.com/callstack/react-native-brownfield/commit/4186cc8e2ed2fa7aa41e84cdba7a23f7035ee08d) Thanks [@hurali97](https://github.com/hurali97)! - Bump brownfield-gradle-plugin
|
|
159
|
+
|
|
160
|
+
### Patch Changes
|
|
161
|
+
|
|
162
|
+
- Updated dependencies []:
|
|
163
|
+
- @callstack/brownfield-cli@3.12.0
|
|
164
|
+
|
|
165
|
+
## 3.11.0
|
|
166
|
+
|
|
167
|
+
### Minor Changes
|
|
168
|
+
|
|
169
|
+
- [#317](https://github.com/callstack/react-native-brownfield/pull/317) [`c04301b`](https://github.com/callstack/react-native-brownfield/commit/c04301b79d288ab108aaa44d7c79dd876b8405e9) Thanks [@adamTrz](https://github.com/adamTrz)! - Add an opt-in iOS Debug mode for loading the embedded JavaScript bundle with `preferEmbeddedBundleInDebug`, fix `bundleURLOverride` fallback behavior when the override returns `nil`, and add native bundle-resolution tests.
|
|
170
|
+
|
|
171
|
+
### Patch Changes
|
|
172
|
+
|
|
173
|
+
- [#361](https://github.com/callstack/react-native-brownfield/pull/361) [`aa14eb2`](https://github.com/callstack/react-native-brownfield/commit/aa14eb26e26ea1e6075b91027237e4b41b932b57) Thanks [@hurali97](https://github.com/hurali97)! - make EXUpdates as a dependency only when installed
|
|
174
|
+
|
|
175
|
+
- [#347](https://github.com/callstack/react-native-brownfield/pull/347) [`c19a81b`](https://github.com/callstack/react-native-brownfield/commit/c19a81b7502cc458d742ab947186591bb69cb261) Thanks [@marcinszalski-callstack](https://github.com/marcinszalski-callstack)! - fix: fix method to deallocate reactNativeFactory instance for expo
|
|
176
|
+
|
|
177
|
+
- Updated dependencies [[`3715ac7`](https://github.com/callstack/react-native-brownfield/commit/3715ac7783000756ef1c66ecfe24a85c5e43abab), [`05c557d`](https://github.com/callstack/react-native-brownfield/commit/05c557da9e2b6fca02e6e1a0b0fe71a909bab15f)]:
|
|
178
|
+
- @callstack/brownfield-cli@3.11.0
|
|
179
|
+
|
|
180
|
+
## 3.10.0
|
|
181
|
+
|
|
182
|
+
### Patch Changes
|
|
183
|
+
|
|
184
|
+
- [#323](https://github.com/callstack/react-native-brownfield/pull/323) [`3456d3a`](https://github.com/callstack/react-native-brownfield/commit/3456d3aded18002475def4b79889979e76e1db5e) Thanks [@artus9033](https://github.com/artus9033)! - Force `BUILD_LIBRARY_FOR_DISTRIBUTION` / `SWIFT_EMIT_MODULE_INTERFACE` on the CocoaPods ReactBrownfield, Brownie and BrownfieldNavigation targets so Release builds emit `.swiftinterface` files and `xcodebuild -create-xcframework` (brownfield `package:ios`) can merge slices.
|
|
185
|
+
|
|
186
|
+
- Updated dependencies [[`3456d3a`](https://github.com/callstack/react-native-brownfield/commit/3456d3aded18002475def4b79889979e76e1db5e)]:
|
|
187
|
+
- @callstack/brownfield-cli@3.10.0
|
|
188
|
+
|
|
189
|
+
## 3.9.0
|
|
190
|
+
|
|
191
|
+
### Minor Changes
|
|
192
|
+
|
|
193
|
+
- [#326](https://github.com/callstack/react-native-brownfield/pull/326) [`80e6364`](https://github.com/callstack/react-native-brownfield/commit/80e6364d405d216b3e84a6297dfe346d2f01444b) Thanks [@artus9033](https://github.com/artus9033)! - feat: strip SO files by default, deprecate experimental option in favor of useStrippedSoFiles
|
|
194
|
+
|
|
195
|
+
### Patch Changes
|
|
196
|
+
|
|
197
|
+
- Updated dependencies [[`80e6364`](https://github.com/callstack/react-native-brownfield/commit/80e6364d405d216b3e84a6297dfe346d2f01444b)]:
|
|
198
|
+
- @callstack/brownfield-cli@3.9.0
|
|
199
|
+
|
|
200
|
+
## 3.8.1
|
|
201
|
+
|
|
202
|
+
### Patch Changes
|
|
203
|
+
|
|
204
|
+
- Updated dependencies [[`e78084d`](https://github.com/callstack/react-native-brownfield/commit/e78084d227a49d39d726b8c778bd56045634678d)]:
|
|
205
|
+
- @callstack/brownfield-cli@3.8.1
|
|
206
|
+
|
|
207
|
+
## 3.8.0
|
|
208
|
+
|
|
209
|
+
### Minor Changes
|
|
210
|
+
|
|
211
|
+
- [#295](https://github.com/callstack/react-native-brownfield/pull/295) [`d93dcd9`](https://github.com/callstack/react-native-brownfield/commit/d93dcd96e3b90517d718cd42b2cc773fb9795eac) Thanks [@hurali97](https://github.com/hurali97)! - add expo updates support
|
|
212
|
+
|
|
213
|
+
### Patch Changes
|
|
214
|
+
|
|
215
|
+
- Updated dependencies [[`d93dcd9`](https://github.com/callstack/react-native-brownfield/commit/d93dcd96e3b90517d718cd42b2cc773fb9795eac)]:
|
|
216
|
+
- @callstack/brownfield-cli@3.8.0
|
|
217
|
+
|
|
218
|
+
## 3.7.0
|
|
219
|
+
|
|
220
|
+
### Patch Changes
|
|
221
|
+
|
|
222
|
+
- [#315](https://github.com/callstack/react-native-brownfield/pull/315) [`874332b`](https://github.com/callstack/react-native-brownfield/commit/874332b8a4cc58e945adad64cbaebfbe4d6cae88) Thanks [@marcinszalski-callstack](https://github.com/marcinszalski-callstack)! - fix: make sure native libs are loaded for RN >= 0.80
|
|
223
|
+
|
|
224
|
+
- [#322](https://github.com/callstack/react-native-brownfield/pull/322) [`cbc99cf`](https://github.com/callstack/react-native-brownfield/commit/cbc99cf2bbbb8ba351a2bde3c839dd1b5dcf302b) Thanks [@marcinszalski-callstack](https://github.com/marcinszalski-callstack)! - fix: make sure android libs are loaded for expo apps
|
|
225
|
+
|
|
226
|
+
- Updated dependencies [[`c153378`](https://github.com/callstack/react-native-brownfield/commit/c1533783c0a93372b3c12f08c1428766c0405226)]:
|
|
227
|
+
- @callstack/brownfield-cli@3.7.0
|
|
228
|
+
|
|
229
|
+
## 3.6.1
|
|
230
|
+
|
|
231
|
+
### Patch Changes
|
|
232
|
+
|
|
233
|
+
- [#305](https://github.com/callstack/react-native-brownfield/pull/305) [`eab53d9`](https://github.com/callstack/react-native-brownfield/commit/eab53d9f7b93f38e13185020fcf8a7af23df0d05) Thanks [@hurali97](https://github.com/hurali97)! - fix securiy vulnerabilities
|
|
234
|
+
|
|
235
|
+
- Updated dependencies [[`eab53d9`](https://github.com/callstack/react-native-brownfield/commit/eab53d9f7b93f38e13185020fcf8a7af23df0d05)]:
|
|
236
|
+
- @callstack/brownfield-cli@3.6.1
|
|
237
|
+
|
|
238
|
+
## 3.6.0
|
|
239
|
+
|
|
240
|
+
### Minor Changes
|
|
241
|
+
|
|
242
|
+
- [#301](https://github.com/callstack/react-native-brownfield/pull/301) [`c8816e9`](https://github.com/callstack/react-native-brownfield/commit/c8816e9418a472e0e8a388db105121381243e496) Thanks [@marcinszalski-callstack](https://github.com/marcinszalski-callstack)! - feat: add method to deallocate reactNativeFactory instance
|
|
243
|
+
|
|
244
|
+
### Patch Changes
|
|
245
|
+
|
|
246
|
+
- Updated dependencies [[`5ac357b`](https://github.com/callstack/react-native-brownfield/commit/5ac357bb8802ecf3562d92be191f6681ae94a055)]:
|
|
247
|
+
- @callstack/brownfield-cli@3.6.0
|
|
248
|
+
|
|
249
|
+
## 3.5.1
|
|
250
|
+
|
|
251
|
+
### Patch Changes
|
|
252
|
+
|
|
253
|
+
- [#288](https://github.com/callstack/react-native-brownfield/pull/288) [`096cc3b`](https://github.com/callstack/react-native-brownfield/commit/096cc3bbf580d9bf22374fa8b67021d2f29e211c) Thanks [@marcinszalski-callstack](https://github.com/marcinszalski-callstack)! - fix: restore back-button propagation from native to RN
|
|
254
|
+
|
|
255
|
+
- Updated dependencies []:
|
|
256
|
+
- @callstack/brownfield-cli@3.5.1
|
|
257
|
+
|
|
258
|
+
## 3.5.0
|
|
259
|
+
|
|
260
|
+
### Minor Changes
|
|
261
|
+
|
|
262
|
+
- [#257](https://github.com/callstack/react-native-brownfield/pull/257) [`d0e6203`](https://github.com/callstack/react-native-brownfield/commit/d0e62039c8a080c648abbbeace047e72fadce28b) Thanks [@hurali97](https://github.com/hurali97)! - add brownie android
|
|
263
|
+
|
|
264
|
+
### Patch Changes
|
|
265
|
+
|
|
266
|
+
- Updated dependencies [[`d0e6203`](https://github.com/callstack/react-native-brownfield/commit/d0e62039c8a080c648abbbeace047e72fadce28b)]:
|
|
267
|
+
- @callstack/brownfield-cli@3.5.0
|
|
268
|
+
|
|
269
|
+
## 3.4.0
|
|
270
|
+
|
|
271
|
+
### Minor Changes
|
|
272
|
+
|
|
273
|
+
- [#268](https://github.com/callstack/react-native-brownfield/pull/268) [`e174e50`](https://github.com/callstack/react-native-brownfield/commit/e174e5018593f689f950b17241c528f53fb71500) Thanks [@artus9033](https://github.com/artus9033)! - feat: support linking in Expo and vanilla
|
|
274
|
+
|
|
275
|
+
### Patch Changes
|
|
276
|
+
|
|
277
|
+
- [#246](https://github.com/callstack/react-native-brownfield/pull/246) [`5484065`](https://github.com/callstack/react-native-brownfield/commit/5484065da9dc86a420af2be692fcdefa32fbb2af) Thanks [@artus9033](https://github.com/artus9033)! - chore: upgrade dependencies
|
|
278
|
+
|
|
279
|
+
- [#275](https://github.com/callstack/react-native-brownfield/pull/275) [`dd8b8a0`](https://github.com/callstack/react-native-brownfield/commit/dd8b8a0b532fe779c1f2ce018577ad748b887ee0) Thanks [@artus9033](https://github.com/artus9033)! - fix: support custom app project name in Gradle plugin via extension's appProjectName config field
|
|
280
|
+
|
|
281
|
+
- [#275](https://github.com/callstack/react-native-brownfield/pull/275) [`dd8b8a0`](https://github.com/callstack/react-native-brownfield/commit/dd8b8a0b532fe779c1f2ce018577ad748b887ee0) Thanks [@artus9033](https://github.com/artus9033)! - chore: bump up Gradle plugin version
|
|
282
|
+
|
|
283
|
+
- [#246](https://github.com/callstack/react-native-brownfield/pull/246) [`5484065`](https://github.com/callstack/react-native-brownfield/commit/5484065da9dc86a420af2be692fcdefa32fbb2af) Thanks [@artus9033](https://github.com/artus9033)! - chore: upgrade dependencies
|
|
284
|
+
|
|
285
|
+
- Updated dependencies [[`5484065`](https://github.com/callstack/react-native-brownfield/commit/5484065da9dc86a420af2be692fcdefa32fbb2af), [`dd8b8a0`](https://github.com/callstack/react-native-brownfield/commit/dd8b8a0b532fe779c1f2ce018577ad748b887ee0), [`54ab7ab`](https://github.com/callstack/react-native-brownfield/commit/54ab7ab01bd6f95439cc8b702d4124552e22ad55), [`5484065`](https://github.com/callstack/react-native-brownfield/commit/5484065da9dc86a420af2be692fcdefa32fbb2af)]:
|
|
286
|
+
- @callstack/brownfield-cli@3.4.0
|
|
287
|
+
|
|
288
|
+
## 3.3.0
|
|
289
|
+
|
|
290
|
+
### Minor Changes
|
|
291
|
+
|
|
292
|
+
- [#248](https://github.com/callstack/react-native-brownfield/pull/248) [`b0a6f41`](https://github.com/callstack/react-native-brownfield/commit/b0a6f4185aad4e8759b90ccaf9867be493a979ec) Thanks [@artus9033](https://github.com/artus9033)! - feat: support Expo 55
|
|
293
|
+
|
|
294
|
+
### Patch Changes
|
|
295
|
+
|
|
296
|
+
- Updated dependencies [[`b0a6f41`](https://github.com/callstack/react-native-brownfield/commit/b0a6f4185aad4e8759b90ccaf9867be493a979ec)]:
|
|
297
|
+
- @callstack/brownfield-cli@3.3.0
|
|
298
|
+
|
|
299
|
+
## 3.2.1
|
|
300
|
+
|
|
301
|
+
### Patch Changes
|
|
302
|
+
|
|
303
|
+
- [#265](https://github.com/callstack/react-native-brownfield/pull/265) [`7e114e6`](https://github.com/callstack/react-native-brownfield/commit/7e114e676fc290a54912b4d99bd22952b2f7380d) Thanks [@hurali97](https://github.com/hurali97)! - version bump
|
|
304
|
+
|
|
305
|
+
- Updated dependencies [[`7e114e6`](https://github.com/callstack/react-native-brownfield/commit/7e114e676fc290a54912b4d99bd22952b2f7380d)]:
|
|
306
|
+
- @callstack/brownfield-cli@3.2.1
|
|
307
|
+
|
|
308
|
+
## 3.2.0
|
|
309
|
+
|
|
310
|
+
### Minor Changes
|
|
311
|
+
|
|
312
|
+
- [#263](https://github.com/callstack/react-native-brownfield/pull/263) [`b7dfa7e`](https://github.com/callstack/react-native-brownfield/commit/b7dfa7e30e1a921bb7ac0952e23481ee081fb9ed) Thanks [@hurali97](https://github.com/hurali97)! - version bump for release
|
|
313
|
+
|
|
314
|
+
### Patch Changes
|
|
315
|
+
|
|
316
|
+
- Updated dependencies [[`b7dfa7e`](https://github.com/callstack/react-native-brownfield/commit/b7dfa7e30e1a921bb7ac0952e23481ee081fb9ed)]:
|
|
317
|
+
- @callstack/brownfield-cli@3.2.0
|
|
318
|
+
|
|
319
|
+
## 3.1.0
|
|
320
|
+
|
|
321
|
+
### Minor Changes
|
|
322
|
+
|
|
323
|
+
- [#252](https://github.com/callstack/react-native-brownfield/pull/252) [`d5c8609`](https://github.com/callstack/react-native-brownfield/commit/d5c8609485b072eb73be0158d49908fa399d8950) Thanks [@artus9033](https://github.com/artus9033)! - feat: added postMessage API
|
|
324
|
+
|
|
325
|
+
- [#236](https://github.com/callstack/react-native-brownfield/pull/236) [`3e33b89`](https://github.com/callstack/react-native-brownfield/commit/3e33b890e6f647f6bbebe32f8068a38b1ed85ea0) Thanks [@hurali97](https://github.com/hurali97)! - add brownfield navigation
|
|
326
|
+
|
|
327
|
+
### Patch Changes
|
|
328
|
+
|
|
329
|
+
- Updated dependencies [[`3e33b89`](https://github.com/callstack/react-native-brownfield/commit/3e33b890e6f647f6bbebe32f8068a38b1ed85ea0)]:
|
|
330
|
+
- @callstack/brownfield-cli@3.1.0
|
|
331
|
+
|
|
332
|
+
## 3.0.0
|
|
333
|
+
|
|
334
|
+
### Patch Changes
|
|
335
|
+
|
|
336
|
+
- [#255](https://github.com/callstack/react-native-brownfield/pull/255) [`48358b2`](https://github.com/callstack/react-native-brownfield/commit/48358b2dcce578aa5052e66cc3454524da8c7992) Thanks [@artus9033](https://github.com/artus9033)! - chore: release stable v3
|
|
337
|
+
|
|
338
|
+
- [#239](https://github.com/callstack/react-native-brownfield/pull/239) [`828bda3`](https://github.com/callstack/react-native-brownfield/commit/828bda32f39153085f5053becc7e9de16d284be5) Thanks [@hurali97](https://github.com/hurali97)! - fix: autodetect iOS app target name for Expo pre-55 patch script phase
|
|
339
|
+
|
|
340
|
+
- Updated dependencies [[`48358b2`](https://github.com/callstack/react-native-brownfield/commit/48358b2dcce578aa5052e66cc3454524da8c7992)]:
|
|
341
|
+
- @callstack/brownfield-cli@3.0.0
|
|
342
|
+
|
|
343
|
+
## 2.2.0
|
|
344
|
+
|
|
345
|
+
### Minor Changes
|
|
346
|
+
|
|
347
|
+
- [#212](https://github.com/callstack/react-native-brownfield/pull/212) [`4728945`](https://github.com/callstack/react-native-brownfield/commit/47289457b9bdbe50cf3c65a78c7f1d9d555dca9c) Thanks [@gronxb](https://github.com/gronxb)! - feat(ios): add bundleURL provider for dynamic bundle loading
|
|
348
|
+
|
|
349
|
+
### Patch Changes
|
|
350
|
+
|
|
351
|
+
- [#216](https://github.com/callstack/react-native-brownfield/pull/216) [`8ce3ea1`](https://github.com/callstack/react-native-brownfield/commit/8ce3ea10e0719adac7396dea8f171753e901b31d) Thanks [@thymikee](https://github.com/thymikee)! - chore: remove release-it
|
|
352
|
+
|
|
353
|
+
- Updated dependencies [[`8ce3ea1`](https://github.com/callstack/react-native-brownfield/commit/8ce3ea10e0719adac7396dea8f171753e901b31d)]:
|
|
354
|
+
- @callstack/brownfield-cli@1.0.4
|
|
355
|
+
|
|
356
|
+
## 2.1.1
|
|
357
|
+
|
|
358
|
+
### Patch Changes
|
|
359
|
+
|
|
360
|
+
- Updated dependencies [[`2347775`](https://github.com/callstack/react-native-brownfield/commit/23477753b16ee189b82c1aee3eac98a56c79f52a)]:
|
|
361
|
+
- @callstack/brownfield-cli@1.0.3
|
|
362
|
+
|
|
363
|
+
## 2.1.0
|
|
364
|
+
|
|
365
|
+
### Minor Changes
|
|
366
|
+
|
|
367
|
+
- [#207](https://github.com/callstack/react-native-brownfield/pull/207) [`feb7ed2`](https://github.com/callstack/react-native-brownfield/commit/feb7ed2e821112576ec89d6eb17e8ea411aeaa02) Thanks [@artus9033](https://github.com/artus9033)! - feat(android): allow bundle file path
|
|
368
|
+
|
|
369
|
+
### Patch Changes
|
|
370
|
+
|
|
371
|
+
- Updated dependencies [[`2a8563f`](https://github.com/callstack/react-native-brownfield/commit/2a8563f65ed152054ad1290caf963791a368ee9a)]:
|
|
372
|
+
- @callstack/brownfield-cli@1.0.2
|
|
373
|
+
|
|
374
|
+
## 2.0.2
|
|
375
|
+
|
|
376
|
+
### Patch Changes
|
|
377
|
+
|
|
378
|
+
- [#198](https://github.com/callstack/react-native-brownfield/pull/198) [`c8c903d`](https://github.com/callstack/react-native-brownfield/commit/c8c903d0d2b78a8c06a41213dfbe781a2daf3d25) Thanks [@artus9033](https://github.com/artus9033)! - docs: added README files to all packages
|
|
379
|
+
|
|
380
|
+
- Updated dependencies [[`c8c903d`](https://github.com/callstack/react-native-brownfield/commit/c8c903d0d2b78a8c06a41213dfbe781a2daf3d25)]:
|
|
381
|
+
- @callstack/brownfield-cli@1.0.1
|
|
@@ -65,6 +65,8 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
|
|
|
65
65
|
if (!initialized.getAndSet(true)) {
|
|
66
66
|
loadNativeLibs(application)
|
|
67
67
|
installAndPreload(reactHost, onJSBundleLoaded)
|
|
68
|
+
} else {
|
|
69
|
+
invokeWhenJSBundleLoaded(onJSBundleLoaded)
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
72
|
|
|
@@ -77,6 +79,8 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
|
|
|
77
79
|
if (!initialized.getAndSet(true)) {
|
|
78
80
|
loadNativeLibs(application)
|
|
79
81
|
installAndPreload(reactHostFactory(), onJSBundleLoaded)
|
|
82
|
+
} else {
|
|
83
|
+
invokeWhenJSBundleLoaded(onJSBundleLoaded)
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
86
|
|
|
@@ -102,6 +106,8 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
|
|
|
102
106
|
jsRuntimeFactory = null
|
|
103
107
|
)
|
|
104
108
|
installAndPreload(reactHost, onJSBundleLoaded)
|
|
109
|
+
} else {
|
|
110
|
+
invokeWhenJSBundleLoaded(onJSBundleLoaded)
|
|
105
111
|
}
|
|
106
112
|
}
|
|
107
113
|
|
|
@@ -134,6 +140,25 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
|
|
|
134
140
|
onJSBundleLoaded?.invoke(true)
|
|
135
141
|
}
|
|
136
142
|
}
|
|
143
|
+
|
|
144
|
+
private fun invokeWhenJSBundleLoaded(onJSBundleLoaded: OnJSBundleLoaded?) {
|
|
145
|
+
if (onJSBundleLoaded == null || !::instance.isInitialized) {
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
val reactHost = instance.reactHost
|
|
150
|
+
reactHost.currentReactContext?.let {
|
|
151
|
+
onJSBundleLoaded.invoke(true)
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
reactHost.addReactInstanceEventListener(object : ReactInstanceEventListener {
|
|
156
|
+
override fun onReactContextInitialized(context: ReactContext) {
|
|
157
|
+
onJSBundleLoaded.invoke(true)
|
|
158
|
+
reactHost.removeReactInstanceEventListener(this)
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
}
|
|
137
162
|
}
|
|
138
163
|
|
|
139
164
|
/**
|
|
@@ -69,6 +69,26 @@ class ReactNativeFragment : ReactFragment(), PermissionAwareActivity {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
override fun onPause() {
|
|
73
|
+
try {
|
|
74
|
+
super.onPause()
|
|
75
|
+
} catch (error: AssertionError) {
|
|
76
|
+
if (
|
|
77
|
+
error.message?.contains(
|
|
78
|
+
"Pausing an activity that is not the current activity"
|
|
79
|
+
) == true
|
|
80
|
+
) {
|
|
81
|
+
Log.w(
|
|
82
|
+
"ReactNativeFragment",
|
|
83
|
+
"Ignoring stale onHostPause for ${activity?.javaClass?.simpleName}",
|
|
84
|
+
error
|
|
85
|
+
)
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
throw error
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
72
92
|
override fun onRequestPermissionsResult(
|
|
73
93
|
requestCode: Int,
|
|
74
94
|
permissions: Array<String>,
|
|
File without changes
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
|
|
3
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates and starts the React Host, but does not create a view. React Native loads and evaluates
|
|
7
|
+
* the JavaScript bundle immediately, and not when it mounts the first React Native view.
|
|
8
|
+
* `viewWithModuleName:` makes the same call internally, thus a view that you create later uses the
|
|
9
|
+
* host that is ready.
|
|
10
|
+
*
|
|
11
|
+
* This class is in Objective-C, because Swift cannot make this call:
|
|
12
|
+
* `RCTReactNativeFactory.devMenuConfiguration` is nullable, but the related parameter is not
|
|
13
|
+
* nullable.
|
|
14
|
+
*/
|
|
15
|
+
@interface BrownfieldReactHostPreloader : NSObject
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Call this method on the main thread. If a host is already available, this method does nothing.
|
|
19
|
+
*
|
|
20
|
+
* @param reactNativeFactory An `RCTReactNativeFactory`, or a subclass, for example
|
|
21
|
+
* `ExpoReactNativeFactory`. The type is `id`, because this header must stay free of the React
|
|
22
|
+
* Native imports.
|
|
23
|
+
* @param launchOptions The launch options for the React Host.
|
|
24
|
+
*/
|
|
25
|
+
+ (void)preloadWithReactNativeFactory:(id)reactNativeFactory
|
|
26
|
+
launchOptions:(nullable NSDictionary *)launchOptions;
|
|
27
|
+
|
|
28
|
+
@end
|
|
29
|
+
|
|
30
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#import "BrownfieldReactHostPreloader.h"
|
|
2
|
+
|
|
3
|
+
// This file is plain Objective-C, and not Objective-C++. The umbrella header of
|
|
4
|
+
// React-RCTAppDelegate imports the Hermes and JSI headers if `__cplusplus` is set. This pod does
|
|
5
|
+
// not have the necessary search paths for those headers. Without C++, the compiler ignores those
|
|
6
|
+
// imports. The compiler then builds the module in the same way that Swift imports it.
|
|
7
|
+
//
|
|
8
|
+
// The name of the pod changes if the build makes it a framework. Thus you must try each possible
|
|
9
|
+
// name. Expo uses the same method in `RCTAppDelegateUmbrella.h`.
|
|
10
|
+
#if __has_include(<React_RCTAppDelegate/RCTRootViewFactory.h>)
|
|
11
|
+
#import <React_RCTAppDelegate/RCTReactNativeFactory.h>
|
|
12
|
+
#import <React_RCTAppDelegate/RCTRootViewFactory.h>
|
|
13
|
+
#elif __has_include(<React-RCTAppDelegate/RCTRootViewFactory.h>)
|
|
14
|
+
#import <React-RCTAppDelegate/RCTReactNativeFactory.h>
|
|
15
|
+
#import <React-RCTAppDelegate/RCTRootViewFactory.h>
|
|
16
|
+
#else
|
|
17
|
+
#import <React/RCTReactNativeFactory.h>
|
|
18
|
+
#import <React/RCTRootViewFactory.h>
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
22
|
+
|
|
23
|
+
// `RCTBundleConfiguration` first exists in React Native 0.84. React Native 0.83 does not declare
|
|
24
|
+
// the class. This forward declaration lets the file name the type with both versions.
|
|
25
|
+
@class RCTBundleConfiguration;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The two shapes of `initializeReactHostWithLaunchOptions:...`. React Native 0.83 has the shape
|
|
29
|
+
* without `bundleConfiguration:`. React Native 0.84 added that parameter and removed the earlier
|
|
30
|
+
* shape. No header tells the two versions apart at compile time, thus this file declares both
|
|
31
|
+
* shapes and `respondsToSelector:` selects one at run time. The declarations are equal to the
|
|
32
|
+
* React Native declarations. The compiler then accepts the file with both versions.
|
|
33
|
+
*/
|
|
34
|
+
@protocol BrownfieldReactHostInitializing <NSObject>
|
|
35
|
+
|
|
36
|
+
- (void)initializeReactHostWithLaunchOptions:(NSDictionary *__nullable)launchOptions
|
|
37
|
+
bundleConfiguration:(RCTBundleConfiguration *)bundleConfiguration
|
|
38
|
+
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration;
|
|
39
|
+
|
|
40
|
+
- (void)initializeReactHostWithLaunchOptions:(NSDictionary *__nullable)launchOptions
|
|
41
|
+
devMenuConfiguration:(RCTDevMenuConfiguration *)devMenuConfiguration;
|
|
42
|
+
|
|
43
|
+
@end
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* `RCTReactNativeFactory.bundleConfiguration` also first exists in React Native 0.84.
|
|
47
|
+
*/
|
|
48
|
+
@protocol BrownfieldBundleConfigurationProviding <NSObject>
|
|
49
|
+
|
|
50
|
+
@property (nonatomic, readonly) RCTBundleConfiguration *bundleConfiguration;
|
|
51
|
+
|
|
52
|
+
@end
|
|
53
|
+
|
|
54
|
+
NS_ASSUME_NONNULL_END
|
|
55
|
+
|
|
56
|
+
@implementation BrownfieldReactHostPreloader
|
|
57
|
+
|
|
58
|
+
+ (void)preloadWithReactNativeFactory:(id)reactNativeFactory
|
|
59
|
+
launchOptions:(NSDictionary *_Nullable)launchOptions
|
|
60
|
+
{
|
|
61
|
+
RCTReactNativeFactory *factory = (RCTReactNativeFactory *)reactNativeFactory;
|
|
62
|
+
RCTRootViewFactory *rootViewFactory = factory.rootViewFactory;
|
|
63
|
+
|
|
64
|
+
// `initializeReactHostWithLaunchOptions:...` returns early if a view, or an earlier preload,
|
|
65
|
+
// created a host. Thus this method makes no other check. React Native declares
|
|
66
|
+
// `rootViewFactory` as not nullable, and this guard is only a protection.
|
|
67
|
+
if (rootViewFactory == nil) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
id<BrownfieldReactHostInitializing> hostInitializer = (id)rootViewFactory;
|
|
72
|
+
SEL initializeWithBundleConfiguration =
|
|
73
|
+
@selector(initializeReactHostWithLaunchOptions:bundleConfiguration:devMenuConfiguration:);
|
|
74
|
+
SEL initializeWithDevMenuConfiguration =
|
|
75
|
+
@selector(initializeReactHostWithLaunchOptions:devMenuConfiguration:);
|
|
76
|
+
|
|
77
|
+
// Get the configurations from the factory. Do not make new configurations from the default
|
|
78
|
+
// values. The Expo runtime sends `RCTReactNativeFactory.devMenuConfiguration` from
|
|
79
|
+
// `ExpoReactNativeFactory.recreateRootView:`, thus the factory value keeps the two runtimes
|
|
80
|
+
// equal.
|
|
81
|
+
//
|
|
82
|
+
// The preloaded host is equal to a host that a view creates later, but the two paths send
|
|
83
|
+
// different objects. The bare runtime creates the view with
|
|
84
|
+
// `viewWithModuleName:initialProperties:launchOptions:`, and that method sends
|
|
85
|
+
// `[RCTBundleConfiguration defaultConfiguration]` and `[RCTDevMenuConfiguration
|
|
86
|
+
// defaultConfiguration]`. The values are equal:
|
|
87
|
+
// - `RCTReactNativeFactory.bundleConfiguration` gives `[RCTBundleConfiguration
|
|
88
|
+
// defaultConfiguration]` while nobody sets another value.
|
|
89
|
+
// - `RCTReactNativeFactory.devMenuConfiguration` is nil by default.
|
|
90
|
+
// `RCTDevMenuConfigurationDecorator` does nothing with nil, and `RCTDevMenu` and
|
|
91
|
+
// `RCTDevSettings` keep their own default values. Those values are equal to
|
|
92
|
+
// `[RCTDevMenuConfiguration defaultConfiguration]`, because the two sides read `RCT_DEV_MENU`.
|
|
93
|
+
if ([hostInitializer respondsToSelector:initializeWithBundleConfiguration]) {
|
|
94
|
+
id<BrownfieldBundleConfigurationProviding> configurationProvider = (id)factory;
|
|
95
|
+
|
|
96
|
+
[hostInitializer initializeReactHostWithLaunchOptions:launchOptions
|
|
97
|
+
bundleConfiguration:configurationProvider.bundleConfiguration
|
|
98
|
+
devMenuConfiguration:factory.devMenuConfiguration];
|
|
99
|
+
} else if ([hostInitializer respondsToSelector:initializeWithDevMenuConfiguration]) {
|
|
100
|
+
[hostInitializer initializeReactHostWithLaunchOptions:launchOptions
|
|
101
|
+
devMenuConfiguration:factory.devMenuConfiguration];
|
|
102
|
+
} else {
|
|
103
|
+
// A React Native version with a third shape of the method. Do not crash. The first React
|
|
104
|
+
// Native view creates the host, as without a preload.
|
|
105
|
+
NSLog(
|
|
106
|
+
@"%@",
|
|
107
|
+
@"ReactNativeBrownfield: startReactNative did not preload the JavaScript bundle, because "
|
|
108
|
+
@"this React Native version has no known initializeReactHostWithLaunchOptions: method. The "
|
|
109
|
+
@"first React Native view loads the bundle.");
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@end
|
|
@@ -11,7 +11,7 @@ internal import EXUpdates
|
|
|
11
11
|
final class ExpoHostRuntime {
|
|
12
12
|
static let shared = ExpoHostRuntime()
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
let preloadState = ReactHostPreloadState()
|
|
15
15
|
private var delegate = ExpoHostRuntimeDelegate()
|
|
16
16
|
private var reactNativeFactory: RCTReactNativeFactory?
|
|
17
17
|
private var expoDelegate: ExpoAppDelegate?
|
|
@@ -35,9 +35,15 @@ final class ExpoHostRuntime {
|
|
|
35
35
|
/**
|
|
36
36
|
* Starts React Native with optional callback when bundle is loaded.
|
|
37
37
|
*
|
|
38
|
-
* @param onBundleLoaded Optional callback invoked after JS bundle is fully loaded.
|
|
38
|
+
* @param onBundleLoaded Optional callback invoked on the main thread after JS bundle is fully loaded.
|
|
39
39
|
*/
|
|
40
40
|
public func startReactNative(onBundleLoaded: (() -> Void)?) {
|
|
41
|
+
// The callback registration is outside of the guard below. An earlier `startReactNative` call
|
|
42
|
+
// can already have made the factory, and the callback must still run.
|
|
43
|
+
if let onBundleLoaded {
|
|
44
|
+
preloadState.jsBundleLoadObserver.observe(onBundleLoaded: onBundleLoaded)
|
|
45
|
+
}
|
|
46
|
+
|
|
41
47
|
guard reactNativeFactory == nil else { return }
|
|
42
48
|
|
|
43
49
|
let appDelegate = ExpoAppDelegate()
|
|
@@ -50,10 +56,6 @@ final class ExpoHostRuntime {
|
|
|
50
56
|
appDelegate.bindReactNativeFactory(reactNativeFactory)
|
|
51
57
|
#endif
|
|
52
58
|
expoDelegate = appDelegate
|
|
53
|
-
|
|
54
|
-
if let onBundleLoaded {
|
|
55
|
-
jsBundleLoadObserver.observeOnce(onBundleLoaded: onBundleLoaded)
|
|
56
|
-
}
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
/**
|
|
@@ -70,6 +72,7 @@ final class ExpoHostRuntime {
|
|
|
70
72
|
}
|
|
71
73
|
reactNativeFactory = nil
|
|
72
74
|
expoDelegate = nil
|
|
75
|
+
preloadState.reset()
|
|
73
76
|
}
|
|
74
77
|
|
|
75
78
|
/**
|
|
@@ -169,6 +172,8 @@ final class ExpoHostRuntime {
|
|
|
169
172
|
let bundleURL = delegate.bundleURL()
|
|
170
173
|
configureDevLoadingView(with: bundleURL)
|
|
171
174
|
|
|
175
|
+
let resolvedLaunchOptions = preloadState.launchOptions(overriddenBy: launchOptions)
|
|
176
|
+
|
|
172
177
|
// below: https://github.com/expo/expo/commit/2013760c46cde1404872d181a691da72fbf207a4
|
|
173
178
|
// has moved the recreateRootView method to ExpoReactNativeFactory
|
|
174
179
|
#if EXPO_SDK_GTE_55 // this define comes from the Brownfield Expo config plugin
|
|
@@ -176,19 +181,51 @@ final class ExpoHostRuntime {
|
|
|
176
181
|
withBundleURL: bundleURL,
|
|
177
182
|
moduleName: moduleName,
|
|
178
183
|
initialProps: initialProps,
|
|
179
|
-
launchOptions:
|
|
184
|
+
launchOptions: resolvedLaunchOptions
|
|
180
185
|
)
|
|
181
186
|
#else
|
|
182
187
|
return expoDelegate?.recreateRootView(
|
|
183
188
|
withBundleURL: bundleURL,
|
|
184
189
|
moduleName: moduleName,
|
|
185
190
|
initialProps: initialProps,
|
|
186
|
-
launchOptions:
|
|
191
|
+
launchOptions: resolvedLaunchOptions
|
|
187
192
|
)
|
|
188
193
|
#endif
|
|
189
194
|
}
|
|
190
195
|
}
|
|
191
196
|
|
|
197
|
+
extension ExpoHostRuntime: ReactHostPreloading {
|
|
198
|
+
var reactNativeFactoryForPreload: AnyObject? {
|
|
199
|
+
return reactNativeFactory
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* expo-dev-launcher finds the Metro URL only after the user selects an app in the launcher. This
|
|
204
|
+
* is a Debug behavior. In Release the class is in the binary, but it does nothing. Thus this
|
|
205
|
+
* check is also only in Debug.
|
|
206
|
+
*
|
|
207
|
+
* The check reads the class name, because this pod has no dependency on expo-dev-launcher.
|
|
208
|
+
* `EXDevLauncherController` is the name in expo-dev-launcher 56 and 57. If a later version
|
|
209
|
+
* changes the name, this method gives `true`, and a preload can keep a bundle of the launcher
|
|
210
|
+
* screen. Examine the name again when you add a new Expo SDK.
|
|
211
|
+
*
|
|
212
|
+
* `ExpoHostRuntimeDelegate.isBundleURLStable` covers the other conditions.
|
|
213
|
+
*/
|
|
214
|
+
func canPreloadReactNative() -> Bool {
|
|
215
|
+
#if DEBUG
|
|
216
|
+
if NSClassFromString("EXDevLauncherController") != nil {
|
|
217
|
+
return false
|
|
218
|
+
}
|
|
219
|
+
#endif
|
|
220
|
+
|
|
221
|
+
return delegate.isBundleURLStable
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
func prepareDevLoadingView() {
|
|
225
|
+
configureDevLoadingView()
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
192
229
|
class ExpoHostRuntimeDelegate: ExpoReactNativeFactoryDelegate {
|
|
193
230
|
var entryFile = ".expo/.virtual-metro-entry"
|
|
194
231
|
var bundlePath = "main.jsbundle"
|
|
@@ -242,5 +279,30 @@ class ExpoHostRuntimeDelegate: ExpoReactNativeFactoryDelegate {
|
|
|
242
279
|
return nil
|
|
243
280
|
}
|
|
244
281
|
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* `true` if `bundleURL()` gives now the same result as a later resolution. This property follows
|
|
285
|
+
* the steps of `bundleURL()`, and it must change together with them.
|
|
286
|
+
*
|
|
287
|
+
* The override wins over every other step, thus an override makes the URL stable.
|
|
288
|
+
*
|
|
289
|
+
* expo-updates selects the launch asset while `AppController` starts. `ReactNativeViewController`
|
|
290
|
+
* starts `AppController`. Before this operation is complete, `launchAssetUrl()` is nil, and
|
|
291
|
+
* `bundleURL()` gives the embedded bundle. A host from that time keeps the embedded bundle, and
|
|
292
|
+
* Expo never applies the update. Thus the URL is stable only after `launchAssetUrl()` has a
|
|
293
|
+
* value. The class can be in the binary while the app does not use it, thus this check reads the
|
|
294
|
+
* state and not the class.
|
|
295
|
+
*/
|
|
296
|
+
var isBundleURLStable: Bool {
|
|
297
|
+
if bundleURLOverride?() != nil {
|
|
298
|
+
return true
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
#if canImport(EXUpdates) && !DEBUG
|
|
302
|
+
return AppController.isInitialized() && AppController.sharedInstance.launchAssetUrl() != nil
|
|
303
|
+
#else
|
|
304
|
+
return true
|
|
305
|
+
#endif
|
|
306
|
+
}
|
|
245
307
|
}
|
|
246
308
|
#endif
|
|
@@ -1,38 +1,85 @@
|
|
|
1
1
|
import Foundation
|
|
2
|
-
internal import React
|
|
3
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Watches the `RCTInstanceDidLoadBundle` notification, and calls the callback that waits for it.
|
|
5
|
+
*
|
|
6
|
+
* React Native sends the notification from the JavaScript thread. This class always calls the
|
|
7
|
+
* callback on the main thread, because the callback changes the user interface.
|
|
8
|
+
*
|
|
9
|
+
* The class starts to watch at the initialization, and not at the first callback. The class then
|
|
10
|
+
* knows that React Native loaded the bundle, also if nobody waited for the notification.
|
|
11
|
+
*/
|
|
4
12
|
final class JSBundleLoadObserver {
|
|
5
|
-
private var
|
|
13
|
+
private var pendingCallback: (() -> Void)?
|
|
14
|
+
private var didLoadBundle = false
|
|
6
15
|
private var observerToken: NSObjectProtocol?
|
|
7
16
|
|
|
8
|
-
|
|
9
|
-
removeObserverIfNeeded()
|
|
10
|
-
self.onBundleLoaded = onBundleLoaded
|
|
11
|
-
|
|
17
|
+
init() {
|
|
12
18
|
observerToken = NotificationCenter.default.addObserver(
|
|
13
19
|
forName: NSNotification.Name("RCTInstanceDidLoadBundle"),
|
|
14
20
|
object: nil,
|
|
15
|
-
queue:
|
|
21
|
+
queue: .main
|
|
16
22
|
) { [weak self] _ in
|
|
17
|
-
self?.
|
|
23
|
+
self?.bundleDidLoad()
|
|
18
24
|
}
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
deinit {
|
|
22
|
-
|
|
28
|
+
if let observerToken {
|
|
29
|
+
NotificationCenter.default.removeObserver(observerToken)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Keeps one callback, and calls it one time. A new callback replaces the callback that waits. If
|
|
35
|
+
* React Native already loaded the bundle, the class calls the callback in the next turn of the
|
|
36
|
+
* main run loop.
|
|
37
|
+
*
|
|
38
|
+
* @param onBundleLoaded The class always calls this callback on the main thread.
|
|
39
|
+
*/
|
|
40
|
+
func observe(onBundleLoaded: @escaping () -> Void) {
|
|
41
|
+
onMainThread { [weak self] in
|
|
42
|
+
self?.register(onBundleLoaded)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Removes the callback that waits, and forgets the bundle of the earlier session. Call this
|
|
48
|
+
* method when you stop React Native. A callback of the earlier session must not run in the next
|
|
49
|
+
* session.
|
|
50
|
+
*/
|
|
51
|
+
func reset() {
|
|
52
|
+
onMainThread { [weak self] in
|
|
53
|
+
self?.pendingCallback = nil
|
|
54
|
+
self?.didLoadBundle = false
|
|
55
|
+
}
|
|
23
56
|
}
|
|
24
57
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
58
|
+
// MARK: - Main thread only
|
|
59
|
+
|
|
60
|
+
private func register(_ onBundleLoaded: @escaping () -> Void) {
|
|
61
|
+
guard !didLoadBundle else {
|
|
62
|
+
DispatchQueue.main.async(execute: onBundleLoaded)
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
pendingCallback = onBundleLoaded
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private func bundleDidLoad() {
|
|
70
|
+
didLoadBundle = true
|
|
71
|
+
|
|
72
|
+
let callback = pendingCallback
|
|
73
|
+
pendingCallback = nil
|
|
74
|
+
|
|
29
75
|
callback?()
|
|
30
76
|
}
|
|
31
77
|
|
|
32
|
-
private func
|
|
33
|
-
if
|
|
34
|
-
|
|
35
|
-
|
|
78
|
+
private func onMainThread(_ work: @escaping () -> Void) {
|
|
79
|
+
if Thread.isMainThread {
|
|
80
|
+
work()
|
|
81
|
+
} else {
|
|
82
|
+
DispatchQueue.main.async(execute: work)
|
|
36
83
|
}
|
|
37
84
|
}
|
|
38
85
|
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The preload state that `startReactNative`, `view` and `stopReactNative` share.
|
|
5
|
+
*/
|
|
6
|
+
final class ReactHostPreloadState {
|
|
7
|
+
let jsBundleLoadObserver = JSBundleLoadObserver()
|
|
8
|
+
|
|
9
|
+
private let lock = NSLock()
|
|
10
|
+
private var storedLaunchOptions: [AnyHashable: Any]?
|
|
11
|
+
private var hasPreloadRequest = false
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Keeps the launch options of a `startReactNative` call.
|
|
15
|
+
*
|
|
16
|
+
* `startReactNative` can move its preload work to the main thread. A view on the main thread can
|
|
17
|
+
* create the React Host before that. Thus this method must run at the call, and not after the
|
|
18
|
+
* change of thread. The view then finds the options.
|
|
19
|
+
*/
|
|
20
|
+
func storeLaunchOptions(_ launchOptions: [AnyHashable: Any]?) {
|
|
21
|
+
guard let launchOptions else { return }
|
|
22
|
+
|
|
23
|
+
lock.lock()
|
|
24
|
+
defer { lock.unlock() }
|
|
25
|
+
|
|
26
|
+
storedLaunchOptions = launchOptions
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Records that a `startReactNative` call must preload the bundle. `consumePreloadRequest` reads
|
|
31
|
+
* the request one time, and `reset` cancels it.
|
|
32
|
+
*/
|
|
33
|
+
func requestPreload() {
|
|
34
|
+
lock.lock()
|
|
35
|
+
defer { lock.unlock() }
|
|
36
|
+
|
|
37
|
+
hasPreloadRequest = true
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* `true` if a preload request waits. The method also removes the request.
|
|
42
|
+
*
|
|
43
|
+
* `startReactNative` can move its preload work to the main thread. `stopReactNative` on the main
|
|
44
|
+
* thread can run before that work. The stop cancels the request, thus this method then gives
|
|
45
|
+
* `false`, and React Native stays stopped.
|
|
46
|
+
*/
|
|
47
|
+
func consumePreloadRequest() -> Bool {
|
|
48
|
+
lock.lock()
|
|
49
|
+
defer { lock.unlock() }
|
|
50
|
+
|
|
51
|
+
let hadRequest = hasPreloadRequest
|
|
52
|
+
hasPreloadRequest = false
|
|
53
|
+
|
|
54
|
+
return hadRequest
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The launch options for a call that can create the React Host. The options of the caller win
|
|
59
|
+
* over the options of an earlier `startReactNative` call.
|
|
60
|
+
*/
|
|
61
|
+
func launchOptions(
|
|
62
|
+
overriddenBy explicitLaunchOptions: [AnyHashable: Any]? = nil
|
|
63
|
+
) -> [AnyHashable: Any]? {
|
|
64
|
+
lock.lock()
|
|
65
|
+
defer { lock.unlock() }
|
|
66
|
+
|
|
67
|
+
return explicitLaunchOptions ?? storedLaunchOptions
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Removes the state of the session. Call this method when you stop React Native.
|
|
72
|
+
*/
|
|
73
|
+
func reset() {
|
|
74
|
+
jsBundleLoadObserver.reset()
|
|
75
|
+
|
|
76
|
+
lock.lock()
|
|
77
|
+
defer { lock.unlock() }
|
|
78
|
+
|
|
79
|
+
storedLaunchOptions = nil
|
|
80
|
+
hasPreloadRequest = false
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The preload sequence that the two host runtimes share. Only one runtime is in a build. The
|
|
86
|
+
* shared sequence keeps the behavior of the two runtimes equal.
|
|
87
|
+
*/
|
|
88
|
+
protocol ReactHostPreloading: AnyObject {
|
|
89
|
+
var preloadState: ReactHostPreloadState { get }
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The React Native factory, or nil while React Native did not start. The type is `AnyObject`,
|
|
93
|
+
* because `BrownfieldReactHostPreloader` also takes the factory as `id`. This file then needs no
|
|
94
|
+
* React Native import, and it builds with both runtimes.
|
|
95
|
+
*/
|
|
96
|
+
var reactNativeFactoryForPreload: AnyObject? { get }
|
|
97
|
+
|
|
98
|
+
func startReactNative()
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* `false` while the bundle URL can still change. The runtime must not create the host in this
|
|
102
|
+
* condition, because the host keeps the first bundle that it evaluates.
|
|
103
|
+
*/
|
|
104
|
+
func canPreloadReactNative() -> Bool
|
|
105
|
+
|
|
106
|
+
func prepareDevLoadingView()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
extension ReactHostPreloading {
|
|
110
|
+
/**
|
|
111
|
+
* The implementation of
|
|
112
|
+
* `ReactNativeBrownfield.startReactNative(launchOptions:preloadBundle:onBundleLoaded:)`, which
|
|
113
|
+
* holds the contract.
|
|
114
|
+
*/
|
|
115
|
+
func startReactNative(
|
|
116
|
+
launchOptions: [AnyHashable: Any]?,
|
|
117
|
+
preloadBundle: Bool,
|
|
118
|
+
onBundleLoaded: (() -> Void)?
|
|
119
|
+
) {
|
|
120
|
+
preloadState.storeLaunchOptions(launchOptions)
|
|
121
|
+
|
|
122
|
+
if let onBundleLoaded {
|
|
123
|
+
preloadState.jsBundleLoadObserver.observe(onBundleLoaded: onBundleLoaded)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
guard preloadBundle else {
|
|
127
|
+
startReactNative()
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
preloadState.requestPreload()
|
|
132
|
+
|
|
133
|
+
if Thread.isMainThread {
|
|
134
|
+
createReactHost()
|
|
135
|
+
} else {
|
|
136
|
+
DispatchQueue.main.async { [weak self] in
|
|
137
|
+
self?.createReactHost()
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private func createReactHost() {
|
|
143
|
+
// `stopReactNative` can run between the request and this method, because a caller that is not
|
|
144
|
+
// on the main thread moves the work to the main thread. The stop cancels the request, and
|
|
145
|
+
// React Native must then stay stopped.
|
|
146
|
+
guard preloadState.consumePreloadRequest() else { return }
|
|
147
|
+
|
|
148
|
+
startReactNative()
|
|
149
|
+
|
|
150
|
+
guard let factory = reactNativeFactoryForPreload else {
|
|
151
|
+
logSkippedPreload("React Native did not make the factory")
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
guard canPreloadReactNative() else {
|
|
156
|
+
logSkippedPreload("the bundle URL can still change")
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// You must configure the dev loading view before React Native loads the bundle. Usually the
|
|
161
|
+
// `view` method does this.
|
|
162
|
+
prepareDevLoadingView()
|
|
163
|
+
|
|
164
|
+
BrownfieldReactHostPreloader.preload(
|
|
165
|
+
withReactNativeFactory: factory,
|
|
166
|
+
launchOptions: preloadState.launchOptions()
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private func logSkippedPreload(_ reason: String) {
|
|
171
|
+
NSLog(
|
|
172
|
+
"%@",
|
|
173
|
+
"ReactNativeBrownfield: startReactNative did not preload the JavaScript bundle, because "
|
|
174
|
+
+ reason + ". The first React Native view loads the bundle."
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -192,7 +192,9 @@ internal import Expo
|
|
|
192
192
|
/**
|
|
193
193
|
* Starts React Native with optional callback when bundle is loaded.
|
|
194
194
|
*
|
|
195
|
-
* @param onBundleLoaded Optional callback invoked after JS bundle is
|
|
195
|
+
* @param onBundleLoaded Optional callback invoked on the main thread after the JS bundle is
|
|
196
|
+
* fully loaded. It runs in the next turn of the main run loop when the bundle is already
|
|
197
|
+
* loaded. A new callback replaces the callback that waits.
|
|
196
198
|
*/
|
|
197
199
|
@objc public func startReactNative(onBundleLoaded: (() -> Void)?) {
|
|
198
200
|
#if canImport(Expo)
|
|
@@ -202,6 +204,39 @@ internal import Expo
|
|
|
202
204
|
#endif
|
|
203
205
|
}
|
|
204
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Starts React Native, and optionally loads the JavaScript bundle immediately. Without a
|
|
209
|
+
* preload, React Native loads the bundle when it creates the first React Native view. On
|
|
210
|
+
* Android, `ReactNativeBrownfield.initialize` does the same operation.
|
|
211
|
+
*
|
|
212
|
+
* @param launchOptions The launch options for the React Host. Only the call that creates the
|
|
213
|
+
* host reads these options. This method keeps the options. A view that creates the host later
|
|
214
|
+
* uses them, also if this method cannot create the host. Options that you give to `view` win
|
|
215
|
+
* over these options.
|
|
216
|
+
* @param preloadBundle `true` loads and evaluates the JavaScript bundle now. A preload adds
|
|
217
|
+
* work to the section of the caller, but the first React Native screen appears faster.
|
|
218
|
+
* @param onBundleLoaded An optional callback, with the rules of `startReactNative`.
|
|
219
|
+
*/
|
|
220
|
+
@objc public func startReactNative(
|
|
221
|
+
launchOptions: [AnyHashable: Any]?,
|
|
222
|
+
preloadBundle: Bool,
|
|
223
|
+
onBundleLoaded: (() -> Void)?
|
|
224
|
+
) {
|
|
225
|
+
#if canImport(Expo)
|
|
226
|
+
ExpoHostRuntime.shared.startReactNative(
|
|
227
|
+
launchOptions: launchOptions,
|
|
228
|
+
preloadBundle: preloadBundle,
|
|
229
|
+
onBundleLoaded: onBundleLoaded
|
|
230
|
+
)
|
|
231
|
+
#else
|
|
232
|
+
ReactNativeHostRuntime.shared.startReactNative(
|
|
233
|
+
launchOptions: launchOptions,
|
|
234
|
+
preloadBundle: preloadBundle,
|
|
235
|
+
onBundleLoaded: onBundleLoaded
|
|
236
|
+
)
|
|
237
|
+
#endif
|
|
238
|
+
}
|
|
239
|
+
|
|
205
240
|
/**
|
|
206
241
|
* Send a serialized JSON message to the React Native JS application.
|
|
207
242
|
* The message is delivered as a `brownfieldMessage` DeviceEventEmitter event.
|
|
@@ -46,7 +46,7 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
|
|
|
46
46
|
|
|
47
47
|
final class ReactNativeHostRuntime {
|
|
48
48
|
public static let shared = ReactNativeHostRuntime()
|
|
49
|
-
|
|
49
|
+
let preloadState = ReactHostPreloadState()
|
|
50
50
|
private var delegate = ReactNativeBrownfieldDelegate()
|
|
51
51
|
|
|
52
52
|
private func configureDevLoadingView() {
|
|
@@ -133,6 +133,7 @@ final class ReactNativeHostRuntime {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
reactNativeFactory = nil
|
|
136
|
+
preloadState.reset()
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
public func view(
|
|
@@ -145,7 +146,7 @@ final class ReactNativeHostRuntime {
|
|
|
145
146
|
return reactNativeFactory?.rootViewFactory.view(
|
|
146
147
|
withModuleName: moduleName,
|
|
147
148
|
initialProperties: initialProps,
|
|
148
|
-
launchOptions: launchOptions
|
|
149
|
+
launchOptions: preloadState.launchOptions(overriddenBy: launchOptions)
|
|
149
150
|
)
|
|
150
151
|
}
|
|
151
152
|
|
|
@@ -188,17 +189,38 @@ final class ReactNativeHostRuntime {
|
|
|
188
189
|
/**
|
|
189
190
|
* Starts React Native with optional callback when bundle is loaded.
|
|
190
191
|
*
|
|
191
|
-
* @param onBundleLoaded Optional callback invoked after JS bundle is fully loaded.
|
|
192
|
+
* @param onBundleLoaded Optional callback invoked on the main thread after JS bundle is fully loaded.
|
|
192
193
|
*/
|
|
193
194
|
public func startReactNative(onBundleLoaded: (() -> Void)?) {
|
|
195
|
+
// The callback registration is outside of the guard below. An earlier `startReactNative` call
|
|
196
|
+
// can already have made the factory, and the callback must still run.
|
|
197
|
+
if let onBundleLoaded {
|
|
198
|
+
preloadState.jsBundleLoadObserver.observe(onBundleLoaded: onBundleLoaded)
|
|
199
|
+
}
|
|
200
|
+
|
|
194
201
|
guard reactNativeFactory == nil else { return }
|
|
195
202
|
|
|
196
203
|
delegate.dependencyProvider = RCTAppDependencyProvider()
|
|
197
204
|
reactNativeFactory = RCTReactNativeFactory(delegate: delegate)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
198
207
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
208
|
+
extension ReactNativeHostRuntime: ReactHostPreloading {
|
|
209
|
+
var reactNativeFactoryForPreload: AnyObject? {
|
|
210
|
+
return reactNativeFactory
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* The bare React Native delegate resolves the bundle URL from the override, from Metro, or from
|
|
215
|
+
* the embedded bundle. No step waits for an asynchronous operation. Thus a preload uses the same
|
|
216
|
+
* bundle as the first view.
|
|
217
|
+
*/
|
|
218
|
+
func canPreloadReactNative() -> Bool {
|
|
219
|
+
return true
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
func prepareDevLoadingView() {
|
|
223
|
+
configureDevLoadingView()
|
|
202
224
|
}
|
|
203
225
|
}
|
|
204
226
|
#endif
|
|
@@ -7,10 +7,15 @@ import com.callstack.reactnativebrownfield.ReactNativeBrownfield
|
|
|
7
7
|
import com.facebook.react.PackageList
|
|
8
8
|
import expo.modules.ApplicationLifecycleDispatcher
|
|
9
9
|
import expo.modules.ExpoReactHostFactory
|
|
10
|
+
import java.util.concurrent.atomic.AtomicBoolean
|
|
10
11
|
|
|
11
12
|
object ReactNativeHostManager {
|
|
13
|
+
private val applicationCreateDispatched = AtomicBoolean()
|
|
14
|
+
|
|
12
15
|
fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
|
|
13
|
-
|
|
16
|
+
if (applicationCreateDispatched.compareAndSet(false, true)) {
|
|
17
|
+
ApplicationLifecycleDispatcher.onApplicationCreate(application)
|
|
18
|
+
}
|
|
14
19
|
|
|
15
20
|
ReactNativeBrownfield.initialize(application, onJSBundleLoaded) {
|
|
16
21
|
ExpoReactHostFactory.getDefaultReactHost(
|
|
File without changes
|
|
@@ -7,10 +7,15 @@ import com.callstack.reactnativebrownfield.ReactNativeBrownfield
|
|
|
7
7
|
import com.facebook.react.PackageList
|
|
8
8
|
import expo.modules.ApplicationLifecycleDispatcher
|
|
9
9
|
import expo.modules.ExpoReactHostFactory
|
|
10
|
+
import java.util.concurrent.atomic.AtomicBoolean
|
|
10
11
|
|
|
11
12
|
object ReactNativeHostManager {
|
|
13
|
+
private val applicationCreateDispatched = AtomicBoolean()
|
|
14
|
+
|
|
12
15
|
fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
|
|
13
|
-
|
|
16
|
+
if (applicationCreateDispatched.compareAndSet(false, true)) {
|
|
17
|
+
ApplicationLifecycleDispatcher.onApplicationCreate(application)
|
|
18
|
+
}
|
|
14
19
|
|
|
15
20
|
ReactNativeBrownfield.initialize(application, onJSBundleLoaded) {
|
|
16
21
|
ExpoReactHostFactory.getDefaultReactHost(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@callstack/react-native-brownfield",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Michal Chudziak <mike.chudziak@callstack.com>",
|
|
6
6
|
"bin": {
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"@expo/config-plugins": ">=54 <100"
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"@callstack/brownfield-cli": "
|
|
92
|
+
"@callstack/brownfield-cli": "^5.1.0"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@babel/core": "^7.29.6",
|
|
@@ -121,4 +121,4 @@
|
|
|
121
121
|
"engines": {
|
|
122
122
|
"node": ">=20"
|
|
123
123
|
}
|
|
124
|
-
}
|
|
124
|
+
}
|
|
@@ -7,10 +7,15 @@ import com.callstack.reactnativebrownfield.ReactNativeBrownfield
|
|
|
7
7
|
import com.facebook.react.PackageList
|
|
8
8
|
import expo.modules.ApplicationLifecycleDispatcher
|
|
9
9
|
import expo.modules.ExpoReactHostFactory
|
|
10
|
+
import java.util.concurrent.atomic.AtomicBoolean
|
|
10
11
|
|
|
11
12
|
object ReactNativeHostManager {
|
|
13
|
+
private val applicationCreateDispatched = AtomicBoolean()
|
|
14
|
+
|
|
12
15
|
fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
|
|
13
|
-
|
|
16
|
+
if (applicationCreateDispatched.compareAndSet(false, true)) {
|
|
17
|
+
ApplicationLifecycleDispatcher.onApplicationCreate(application)
|
|
18
|
+
}
|
|
14
19
|
|
|
15
20
|
ReactNativeBrownfield.initialize(application, onJSBundleLoaded) {
|
|
16
21
|
ExpoReactHostFactory.getDefaultReactHost(
|