@callstack/react-native-brownfield 3.6.1 → 3.7.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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # @callstack/react-native-brownfield
2
2
 
3
+ ## 3.7.0
4
+
5
+ ### Patch Changes
6
+
7
+ - [#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
8
+
9
+ - [#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
10
+
11
+ - Updated dependencies [[`c153378`](https://github.com/callstack/react-native-brownfield/commit/c1533783c0a93372b3c12f08c1428766c0405226)]:
12
+ - @callstack/brownfield-cli@3.7.0
13
+
3
14
  ## 3.6.1
4
15
 
5
16
  ### Patch Changes
@@ -7,7 +7,6 @@ import androidx.activity.OnBackPressedCallback
7
7
  import androidx.fragment.app.FragmentActivity
8
8
  import androidx.lifecycle.DefaultLifecycleObserver
9
9
  import androidx.lifecycle.LifecycleOwner
10
- import com.callstack.reactnativebrownfield.utils.VersionUtils
11
10
  import com.facebook.react.ReactHost
12
11
  import com.facebook.react.ReactInstanceEventListener
13
12
  import com.facebook.react.ReactPackage
@@ -28,33 +27,34 @@ fun interface OnMessageListener {
28
27
  fun onMessage(message: String)
29
28
  }
30
29
 
31
- /**
32
- * The threshold RN version based on which we decide whether to
33
- * load JNI libs or not. We only load JNI libs on version less
34
- * than this.
35
- */
36
- private const val RN_THRESHOLD_VERSION = "0.80.0"
37
-
38
30
  class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
39
31
  private val messageListeners = CopyOnWriteArrayList<OnMessageListener>()
40
32
 
41
33
  companion object {
42
34
  private lateinit var instance: ReactNativeBrownfield
43
35
  private val initialized = AtomicBoolean()
44
- private const val LOG_TAG = "ReactNativeBrownfield"
36
+ private val nativeLibsLoaded = AtomicBoolean()
45
37
 
46
38
  @JvmStatic
47
39
  val shared: ReactNativeBrownfield get() = instance
48
40
 
49
41
  private fun loadNativeLibs(application: Application) {
50
- val rnVersion = BuildConfig.RN_VERSION
51
-
52
- if (VersionUtils.isVersionLessThan(rnVersion, RN_THRESHOLD_VERSION)) {
53
- SoLoader.init(application.applicationContext, OpenSourceMergedSoMapping)
54
- load()
42
+ if (!nativeLibsLoaded.getAndSet(true)) {
43
+ loadNativeLibsInternal(application)
55
44
  }
56
45
  }
57
46
 
47
+ private fun loadNativeLibsInternal(application: Application) {
48
+ SoLoader.init(application.applicationContext, OpenSourceMergedSoMapping)
49
+ load()
50
+ }
51
+
52
+ @Deprecated(
53
+ message = "Unsafe when reactHost construction triggers SoLoader (e.g. ExpoReactHostFactory): " +
54
+ "the parameter is evaluated by the caller before loadNativeLibs() runs. " +
55
+ "Use initialize(application, onJSBundleLoaded) { reactHostFactory } instead.",
56
+ replaceWith = ReplaceWith("initialize(application, onJSBundleLoaded) { reactHost }")
57
+ )
58
58
  @JvmStatic
59
59
  @JvmOverloads
60
60
  fun initialize(
@@ -64,14 +64,22 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
64
64
  ) {
65
65
  if (!initialized.getAndSet(true)) {
66
66
  loadNativeLibs(application)
67
- instance = ReactNativeBrownfield(reactHost)
68
-
69
- preloadReactNative {
70
- onJSBundleLoaded?.invoke(true)
71
- }
67
+ installAndPreload(reactHost, onJSBundleLoaded)
72
68
  }
73
69
  }
74
70
 
71
+ @JvmStatic
72
+ fun initialize(
73
+ application: Application,
74
+ onJSBundleLoaded: OnJSBundleLoaded? = null,
75
+ reactHostFactory: () -> ReactHost
76
+ ) {
77
+ if (!initialized.getAndSet(true)) {
78
+ loadNativeLibs(application)
79
+ installAndPreload(reactHostFactory(), onJSBundleLoaded)
80
+ }
81
+ }
82
+
75
83
  @JvmStatic
76
84
  @JvmOverloads
77
85
  fun initialize(
@@ -79,8 +87,9 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
79
87
  options: HashMap<String, Any>,
80
88
  onJSBundleLoaded: OnJSBundleLoaded? = null
81
89
  ) {
82
- val reactHost: ReactHost by lazy {
83
- getDefaultReactHost(
90
+ if (!initialized.getAndSet(true)) {
91
+ loadNativeLibs(application)
92
+ val reactHost = getDefaultReactHost(
84
93
  context = application,
85
94
  packageList = (options["packages"] as? List<*> ?: emptyList<ReactPackage>())
86
95
  .filterIsInstance<ReactPackage>(),
@@ -92,9 +101,8 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
92
101
  ?: ReactBuildConfig.DEBUG,
93
102
  jsRuntimeFactory = null
94
103
  )
104
+ installAndPreload(reactHost, onJSBundleLoaded)
95
105
  }
96
-
97
- initialize(application, reactHost, onJSBundleLoaded)
98
106
  }
99
107
 
100
108
  @JvmStatic
@@ -119,6 +127,13 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
119
127
  })
120
128
  shared.reactHost.start()
121
129
  }
130
+
131
+ private fun installAndPreload(reactHost: ReactHost, onJSBundleLoaded: OnJSBundleLoaded?) {
132
+ instance = ReactNativeBrownfield(reactHost)
133
+ preloadReactNative {
134
+ onJSBundleLoaded?.invoke(true)
135
+ }
136
+ }
122
137
  }
123
138
 
124
139
  /**
@@ -5,25 +5,19 @@ import android.content.res.Configuration
5
5
  import com.callstack.reactnativebrownfield.OnJSBundleLoaded
6
6
  import com.callstack.reactnativebrownfield.ReactNativeBrownfield
7
7
  import com.facebook.react.PackageList
8
- import com.facebook.react.ReactHost
9
- import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
10
8
  import expo.modules.ApplicationLifecycleDispatcher
11
9
  import expo.modules.ExpoReactHostFactory
12
10
 
13
11
  object ReactNativeHostManager {
14
12
  fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
15
- loadReactNative(application)
16
-
17
13
  ApplicationLifecycleDispatcher.onApplicationCreate(application)
18
14
 
19
- val reactHost: ReactHost by lazy {
15
+ ReactNativeBrownfield.initialize(application, onJSBundleLoaded) {
20
16
  ExpoReactHostFactory.getDefaultReactHost(
21
17
  context = application.applicationContext,
22
18
  packageList = PackageList(application).packages,
23
19
  )
24
20
  }
25
-
26
- ReactNativeBrownfield.initialize(application, reactHost, onJSBundleLoaded)
27
21
  }
28
22
 
29
23
  fun onConfigurationChanged(application: Application, newConfig: Configuration) {
@@ -5,8 +5,6 @@ import android.content.res.Configuration
5
5
  import com.callstack.reactnativebrownfield.OnJSBundleLoaded
6
6
  import com.callstack.reactnativebrownfield.ReactNativeBrownfield
7
7
  import com.facebook.react.PackageList
8
- import com.facebook.react.ReactHost
9
- import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
10
8
  import com.facebook.react.ReactPackage
11
9
  import com.facebook.react.defaults.DefaultReactNativeHost
12
10
  import expo.modules.ApplicationLifecycleDispatcher
@@ -15,8 +13,6 @@ import expo.modules.ReactNativeHostWrapper
15
13
 
16
14
  object ReactNativeHostManager {
17
15
  fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
18
- loadReactNative(application)
19
-
20
16
  ApplicationLifecycleDispatcher.onApplicationCreate(application)
21
17
 
22
18
  val reactNativeHost = ReactNativeHostWrapper(
@@ -37,15 +33,12 @@ object ReactNativeHostManager {
37
33
  override fun getBundleAssetName(): String = "index.android.bundle"
38
34
  })
39
35
 
40
-
41
- val reactHost: ReactHost by lazy {
36
+ ReactNativeBrownfield.initialize(application, onJSBundleLoaded) {
42
37
  ExpoReactHostFactory.createFromReactNativeHost(
43
38
  context = application.applicationContext,
44
39
  reactNativeHost = reactNativeHost
45
40
  )
46
41
  }
47
-
48
- ReactNativeBrownfield.initialize(application, reactHost, onJSBundleLoaded)
49
42
  }
50
43
 
51
44
  fun onConfigurationChanged(application: Application, newConfig: Configuration) {
@@ -5,25 +5,19 @@ import android.content.res.Configuration
5
5
  import com.callstack.reactnativebrownfield.OnJSBundleLoaded
6
6
  import com.callstack.reactnativebrownfield.ReactNativeBrownfield
7
7
  import com.facebook.react.PackageList
8
- import com.facebook.react.ReactHost
9
- import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
10
8
  import expo.modules.ApplicationLifecycleDispatcher
11
9
  import expo.modules.ExpoReactHostFactory
12
10
 
13
11
  object ReactNativeHostManager {
14
12
  fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
15
- loadReactNative(application)
16
-
17
13
  ApplicationLifecycleDispatcher.onApplicationCreate(application)
18
14
 
19
- val reactHost: ReactHost by lazy {
15
+ ReactNativeBrownfield.initialize(application, onJSBundleLoaded) {
20
16
  ExpoReactHostFactory.getDefaultReactHost(
21
17
  context = application.applicationContext,
22
18
  packageList = PackageList(application).packages,
23
19
  )
24
20
  }
25
-
26
- ReactNativeBrownfield.initialize(application, reactHost, onJSBundleLoaded)
27
21
  }
28
22
 
29
23
  fun onConfigurationChanged(application: Application, newConfig: Configuration) {
@@ -5,8 +5,6 @@ import android.content.res.Configuration
5
5
  import com.callstack.reactnativebrownfield.OnJSBundleLoaded
6
6
  import com.callstack.reactnativebrownfield.ReactNativeBrownfield
7
7
  import com.facebook.react.PackageList
8
- import com.facebook.react.ReactHost
9
- import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
10
8
  import com.facebook.react.ReactPackage
11
9
  import com.facebook.react.defaults.DefaultReactNativeHost
12
10
  import expo.modules.ApplicationLifecycleDispatcher
@@ -15,8 +13,6 @@ import expo.modules.ReactNativeHostWrapper
15
13
 
16
14
  object ReactNativeHostManager {
17
15
  fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
18
- loadReactNative(application)
19
-
20
16
  ApplicationLifecycleDispatcher.onApplicationCreate(application)
21
17
 
22
18
  val reactNativeHost = ReactNativeHostWrapper(
@@ -37,15 +33,12 @@ object ReactNativeHostManager {
37
33
  override fun getBundleAssetName(): String = "index.android.bundle"
38
34
  })
39
35
 
40
-
41
- val reactHost: ReactHost by lazy {
36
+ ReactNativeBrownfield.initialize(application, onJSBundleLoaded) {
42
37
  ExpoReactHostFactory.createFromReactNativeHost(
43
38
  context = application.applicationContext,
44
39
  reactNativeHost = reactNativeHost
45
40
  )
46
41
  }
47
-
48
- ReactNativeBrownfield.initialize(application, reactHost, onJSBundleLoaded)
49
42
  }
50
43
 
51
44
  fun onConfigurationChanged(application: Application, newConfig: Configuration) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@callstack/react-native-brownfield",
3
- "version": "3.6.1",
3
+ "version": "3.7.0",
4
4
  "license": "MIT",
5
5
  "author": "Michal Chudziak <mike.chudziak@callstack.com>",
6
6
  "bin": {
@@ -86,14 +86,14 @@
86
86
  "@expo/config-plugins": "^54.0.4"
87
87
  },
88
88
  "dependencies": {
89
- "@callstack/brownfield-cli": "^3.6.1"
89
+ "@callstack/brownfield-cli": "^3.7.0"
90
90
  },
91
91
  "devDependencies": {
92
92
  "@babel/core": "^7.25.2",
93
93
  "@babel/preset-env": "^7.25.3",
94
94
  "@babel/runtime": "^7.25.0",
95
95
  "@expo/config-plugins": "^54.0.4",
96
- "@react-native/babel-preset": "0.82.1",
96
+ "@react-native/babel-preset": "0.83.2",
97
97
  "@types/jest": "^30.0.0",
98
98
  "@types/react": "^19.1.1",
99
99
  "@vitest/coverage-v8": "^4.1.0",
@@ -102,7 +102,7 @@
102
102
  "import": "^0.0.6",
103
103
  "nodemon": "^3.1.14",
104
104
  "react": "19.1.1",
105
- "react-native": "0.82.1",
105
+ "react-native": "0.83.2",
106
106
  "react-native-builder-bob": "^0.41.0",
107
107
  "typescript": "5.9.3",
108
108
  "vitest": "^4.1.4"
@@ -5,25 +5,19 @@ import android.content.res.Configuration
5
5
  import com.callstack.reactnativebrownfield.OnJSBundleLoaded
6
6
  import com.callstack.reactnativebrownfield.ReactNativeBrownfield
7
7
  import com.facebook.react.PackageList
8
- import com.facebook.react.ReactHost
9
- import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
10
8
  import expo.modules.ApplicationLifecycleDispatcher
11
9
  import expo.modules.ExpoReactHostFactory
12
10
 
13
11
  object ReactNativeHostManager {
14
12
  fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
15
- loadReactNative(application)
16
-
17
13
  ApplicationLifecycleDispatcher.onApplicationCreate(application)
18
14
 
19
- val reactHost: ReactHost by lazy {
15
+ ReactNativeBrownfield.initialize(application, onJSBundleLoaded) {
20
16
  ExpoReactHostFactory.getDefaultReactHost(
21
17
  context = application.applicationContext,
22
18
  packageList = PackageList(application).packages,
23
19
  )
24
20
  }
25
-
26
- ReactNativeBrownfield.initialize(application, reactHost, onJSBundleLoaded)
27
21
  }
28
22
 
29
23
  fun onConfigurationChanged(application: Application, newConfig: Configuration) {
@@ -5,8 +5,6 @@ import android.content.res.Configuration
5
5
  import com.callstack.reactnativebrownfield.OnJSBundleLoaded
6
6
  import com.callstack.reactnativebrownfield.ReactNativeBrownfield
7
7
  import com.facebook.react.PackageList
8
- import com.facebook.react.ReactHost
9
- import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
10
8
  import com.facebook.react.ReactPackage
11
9
  import com.facebook.react.defaults.DefaultReactNativeHost
12
10
  import expo.modules.ApplicationLifecycleDispatcher
@@ -15,8 +13,6 @@ import expo.modules.ReactNativeHostWrapper
15
13
 
16
14
  object ReactNativeHostManager {
17
15
  fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
18
- loadReactNative(application)
19
-
20
16
  ApplicationLifecycleDispatcher.onApplicationCreate(application)
21
17
 
22
18
  val reactNativeHost = ReactNativeHostWrapper(
@@ -37,15 +33,12 @@ object ReactNativeHostManager {
37
33
  override fun getBundleAssetName(): String = "index.android.bundle"
38
34
  })
39
35
 
40
-
41
- val reactHost: ReactHost by lazy {
36
+ ReactNativeBrownfield.initialize(application, onJSBundleLoaded) {
42
37
  ExpoReactHostFactory.createFromReactNativeHost(
43
38
  context = application.applicationContext,
44
39
  reactNativeHost = reactNativeHost
45
40
  )
46
41
  }
47
-
48
- ReactNativeBrownfield.initialize(application, reactHost, onJSBundleLoaded)
49
42
  }
50
43
 
51
44
  fun onConfigurationChanged(application: Application, newConfig: Configuration) {