expo-dev-launcher 5.0.14 → 5.0.16

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 (20) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/android/build.gradle +11 -5
  3. package/android/src/debug/assets/expo_dev_launcher_android.bundle +1 -1
  4. package/android/src/debug/java/expo/modules/devlauncher/DevLauncherPackageDelegate.kt +1 -1
  5. package/android/src/debug/java/expo/modules/devlauncher/helpers/DevLauncherReactUtils.kt +2 -2
  6. package/android/src/{react-native-74/debug/expo/modules/devlauncher/rncompatibility → debug/java/expo/modules/devlauncher/react}/DevLauncherBridgeDevSupportManager.kt +1 -1
  7. package/android/src/{react-native-74/debug/expo/modules/devlauncher/rncompatibility → debug/java/expo/modules/devlauncher/react}/DevLauncherReactNativeHostHandler.kt +1 -1
  8. package/android/src/{react-native-74/debug/expo/modules/devlauncher/rncompatibility → rn74/debug/expo/modules/devlauncher/react}/DevLauncherBridgelessDevSupportManager.kt +1 -1
  9. package/android/src/{react-native-74/debug/expo/modules/devlauncher/rncompatibility → rn74/debug/expo/modules/devlauncher/react}/DevLauncherDevSupportManagerFactory.kt +1 -1
  10. package/android/src/{debug/java → rn74/debug}/expo/modules/devlauncher/react/DevLauncherDevSupportManagerSwapper.kt +2 -2
  11. package/android/src/rn77/debug/expo/modules/devlauncher/react/DevLauncherBridgelessDevSupportManager.kt +84 -0
  12. package/android/src/rn77/debug/expo/modules/devlauncher/react/DevLauncherDevSupportManagerFactory.kt +75 -0
  13. package/android/src/rn77/debug/expo/modules/devlauncher/react/DevLauncherDevSupportManagerSwapper.kt +179 -0
  14. package/android/src/rn77/main/com/facebook/react/devsupport/NonFinalBridgeDevSupportManager.java +202 -0
  15. package/android/src/rn77/main/com/facebook/react/devsupport/NonFinalBridgelessDevSupportManager.java +134 -0
  16. package/ios/main.jsbundle +1 -1
  17. package/package.json +3 -3
  18. /package/android/src/{react-native-74/main → main/java}/expo/modules/devlauncher/react/DevLauncherPackagerConnectionSettings.kt +0 -0
  19. /package/android/src/{main/java → rn74/main}/com/facebook/react/devsupport/NonFinalBridgeDevSupportManager.java +0 -0
  20. /package/android/src/{main/java → rn74/main}/com/facebook/react/runtime/NonFinalBridgelessDevSupportManager.java +0 -0
package/CHANGELOG.md CHANGED
@@ -10,6 +10,16 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 5.0.16 — 2024-11-22
14
+
15
+ ### 💡 Others
16
+
17
+ - Fixed compatibility for React Native 0.77. ([#33081](https://github.com/expo/expo/pull/33081) by [@kudo](https://github.com/kudo))
18
+
19
+ ## 5.0.15 — 2024-11-19
20
+
21
+ _This version does not introduce any user-facing changes._
22
+
13
23
  ## 5.0.14 — 2024-11-14
14
24
 
15
25
  _This version does not introduce any user-facing changes._
@@ -17,7 +17,7 @@ android {
17
17
  namespace "expo.modules.devlauncher"
18
18
  defaultConfig {
19
19
  versionCode 9
20
- versionName "5.0.14"
20
+ versionName "5.0.16"
21
21
  }
22
22
 
23
23
  buildTypes {
@@ -35,15 +35,21 @@ android {
35
35
  def rnVersion = getRNVersion()
36
36
  main {
37
37
  java {
38
- if (rnVersion >= versionToNumber(0, 74, 0)) {
39
- srcDirs += "src/react-native-74/main"
38
+ if (rnVersion >= versionToNumber(0, 77, 0)) {
39
+ srcDirs += "src/rn77/main"
40
+ } else if (rnVersion >= versionToNumber(0, 74, 0)) {
41
+ // TODO(kudo,20241112): Remove this when we drop react-native 0.76 support
42
+ srcDirs += "src/rn74/main"
40
43
  }
41
44
  }
42
45
  }
43
46
  debug {
44
47
  java {
45
- if (rnVersion >= versionToNumber(0, 74, 0)) {
46
- srcDirs += "src/react-native-74/debug"
48
+ if (rnVersion >= versionToNumber(0, 77, 0)) {
49
+ srcDirs += "src/rn77/debug"
50
+ } else if (rnVersion >= versionToNumber(0, 74, 0)) {
51
+ // TODO(kudo,20241112): Remove this when we drop react-native 0.76 support
52
+ srcDirs += "src/rn74/debug"
47
53
  }
48
54
  }
49
55
  }
@@ -745,7 +745,7 @@ __d((function(g,r,i,a,m,e,d){var t=r(d[0]);Object.defineProperty(e,"__esModule",
745
745
  __d((function(g,r,i,a,m,e,d){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,(0,r(d[0]).ensureNativeModulesAreInstalled)();e.default=globalThis.expo.NativeModule}),662,[659]);
746
746
  __d((function(g,r,i,a,m,e,d){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var t,n=r(d[0]),o=n.NativeModules.NativeUnimoduleProxy,l=null==(t=g.expo)||null==(t=t.modules)?void 0:t.NativeModulesProxy,u='exportedMethods',s={};if(o){var v=null!=l?l:o;Object.keys(v[u]).forEach((function(t){s[t]=v.modulesConstants[t]||{},v[u][t].forEach((function(n){s[t][n.name]=function(){for(var u=arguments.length,s=new Array(u),v=0;v<u;v++)s[v]=arguments[v];if(null!=l&&l.callMethod)return l.callMethod(t,n.name,s);var c=n.key,f=n.argumentsCount;return f!==s.length?Promise.reject(new Error(`Native method ${t}.${n.name} expects ${f} ${1===f?'argument':'arguments'} but received ${s.length}`)):o.callMethod(t,c,s)}})),n.NativeModules.EXReactNativeEventEmitter?(s[t].addListener=function(){for(var o,l=arguments.length,u=new Array(l),s=0;s<l;s++)u[s]=arguments[s];return(o=n.NativeModules.EXReactNativeEventEmitter).addProxiedListener.apply(o,[t].concat(u))},s[t].removeListeners=function(){for(var o,l=arguments.length,u=new Array(l),s=0;s<l;s++)u[s]=arguments[s];return(o=n.NativeModules.EXReactNativeEventEmitter).removeProxiedListeners.apply(o,[t].concat(u))}):(s[t].addListener=function(){},s[t].removeListeners=function(){})}))}else console.warn("The \"EXNativeModulesProxy\" native module is not exported through NativeModules; verify that expo-modules-core's native code is linked properly");e.default=s}),663,[1]);
747
747
  __d((function(g,r,i,a,m,e,d){}),664,[]);
748
- __d((function(g,_r,_i,_a,m,_e,d){var e=_r(d[0]);Object.defineProperty(_e,"__esModule",{value:!0}),_e.requireNativeViewManager=function(e){var r,a,l=i.NativeModules.NativeUnimoduleProxy.viewManagersMetadata,p=(null==l||l[e],null!=(r=null==(a=globalThis.expo)?void 0:a.__expo_app_identifier__)?r:''),v=w(`ViewManagerAdapter_${e}${p?`_${p}`:''}`),y=(function(e){function r(){var e;(0,t.default)(this,r);for(var n=arguments.length,a=new Array(n),o=0;o<n;o++)a[o]=arguments[o];return(e=s(this,r,[].concat(a))).nativeTag=null,e}return(0,o.default)(r,e),(0,n.default)(r,[{key:"componentDidMount",value:function(){this.nativeTag=(0,i.findNodeHandle)(this)}},{key:"render",value:function(){return(0,c.jsx)(v,Object.assign({},this.props))}}])})(u.default.PureComponent);y.displayName=e;try{var _=(0,f.requireNativeModule)(e).ViewPrototype;_&&Object.assign(y.prototype,_)}catch(e){}return y};var t=e(_r(d[1])),n=e(_r(d[2])),r=e(_r(d[3])),a=e(_r(d[4])),o=e(_r(d[5])),u=e(_r(d[6])),i=_r(d[7]),l=(function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=p(t);if(n&&n.has(e))return n.get(e);var r={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&{}.hasOwnProperty.call(e,o)){var u=a?Object.getOwnPropertyDescriptor(e,o):null;u&&(u.get||u.set)?Object.defineProperty(r,o,u):r[o]=e[o]}return r.default=e,n&&n.set(e,r),r})(_r(d[8])),f=_r(d[9]),c=_r(d[10]);function p(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(p=function(e){return e?n:t})(e)}function s(e,t,n){return t=(0,a.default)(t),(0,r.default)(e,v()?Reflect.construct(t,n||[],(0,a.default)(e).constructor):t.apply(e,n))}function v(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(v=function(){return!!e})()}var y=new Map;function _(e){return l.get(e,(function(){var t,n=e.replace('ViewManagerAdapter_',''),r=null==(t=globalThis.expo)?void 0:t.getViewConfig(n);return r||console.warn('Unable to get the view config for %s',n),Object.assign({uiViewClassName:e},r)}))}function w(e){var t=y.get(e);if(!t){var n=_(e);return y.set(e,n),n}return t}}),665,[21,13,14,25,27,30,109,1,64,666,248]);
748
+ __d((function(g,_r,_i,_a,m,_e,d){var e=_r(d[0]);Object.defineProperty(_e,"__esModule",{value:!0}),_e.requireNativeViewManager=function(e){var r,a,l=i.NativeModules.NativeUnimoduleProxy.viewManagersMetadata,p=(null==l||l[e],null!=(r=null==(a=globalThis.expo)?void 0:a.__expo_app_identifier__)?r:''),v=w(`ViewManagerAdapter_${e}${p?`_${p}`:''}`),y=(function(e){function r(){var e;(0,t.default)(this,r);for(var n=arguments.length,a=new Array(n),o=0;o<n;o++)a[o]=arguments[o];return(e=s(this,r,[].concat(a))).nativeRef=u.default.createRef(),e.nativeTag=null,e}return(0,o.default)(r,e),(0,n.default)(r,[{key:"componentDidMount",value:function(){this.nativeTag=(0,i.findNodeHandle)(this.nativeRef.current)}},{key:"render",value:function(){return(0,c.jsx)(v,Object.assign({},this.props,{ref:this.nativeRef}))}}])})(u.default.PureComponent);y.displayName=e;try{var _=(0,f.requireNativeModule)(e).ViewPrototype;_&&Object.assign(y.prototype,_)}catch(e){}return y};var t=e(_r(d[1])),n=e(_r(d[2])),r=e(_r(d[3])),a=e(_r(d[4])),o=e(_r(d[5])),u=e(_r(d[6])),i=_r(d[7]),l=(function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=p(t);if(n&&n.has(e))return n.get(e);var r={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&{}.hasOwnProperty.call(e,o)){var u=a?Object.getOwnPropertyDescriptor(e,o):null;u&&(u.get||u.set)?Object.defineProperty(r,o,u):r[o]=e[o]}return r.default=e,n&&n.set(e,r),r})(_r(d[8])),f=_r(d[9]),c=_r(d[10]);function p(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(p=function(e){return e?n:t})(e)}function s(e,t,n){return t=(0,a.default)(t),(0,r.default)(e,v()?Reflect.construct(t,n||[],(0,a.default)(e).constructor):t.apply(e,n))}function v(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(v=function(){return!!e})()}var y=new Map;function _(e){return l.get(e,(function(){var t,n=e.replace('ViewManagerAdapter_',''),r=null==(t=globalThis.expo)?void 0:t.getViewConfig(n);return r||console.warn('Unable to get the view config for %s',n),Object.assign({uiViewClassName:e},r)}))}function w(e){var t=y.get(e);if(!t){var n=_(e);return y.set(e,n),n}return t}}),665,[21,13,14,25,27,30,109,1,64,666,248]);
749
749
  __d((function(g,r,i,a,m,e,d){var l=r(d[0]);Object.defineProperty(e,"__esModule",{value:!0}),e.requireNativeModule=function(l){var n=o(l);if(!n)throw new Error(`Cannot find native module '${l}'`);return n},e.requireOptionalNativeModule=o;var n=l(r(d[1])),u=r(d[2]);function o(l){var o,t,v;return(0,u.ensureNativeModulesAreInstalled)(),null!=(o=null!=(t=null==(v=globalThis.expo)||null==(v=v.modules)?void 0:v[l])?t:n.default[l])?o:null}}),666,[21,663,659]);
750
750
  __d((function(g,r,i,a,m,e,d){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var n=r(d[0]),t=r(d[1]),s={OS:"android",select:'undefined'!=typeof window?n.Platform.select:function(n){return n.hasOwnProperty("android")?n.android:n.hasOwnProperty('native')?n.native:n.hasOwnProperty('default')?n.default:void 0},isDOMAvailable:t.isDOMAvailable,canUseEventListeners:t.canUseEventListeners,canUseViewport:t.canUseViewport,isAsyncDebugging:t.isAsyncDebugging};e.default=s}),667,[1,668]);
751
751
  __d((function(g,r,i,a,m,e,d){Object.defineProperty(e,"__esModule",{value:!0}),e.isDOMAvailable=e.isAsyncDebugging=e.canUseViewport=e.canUseEventListeners=void 0;e.isDOMAvailable=!1,e.canUseEventListeners=!1,e.canUseViewport=!1,e.isAsyncDebugging=!1}),668,[]);
@@ -17,7 +17,7 @@ import expo.modules.devlauncher.modules.DevLauncherModule
17
17
  import expo.modules.devlauncher.modules.DevLauncherAuth
18
18
  import expo.modules.core.interfaces.ReactNativeHostHandler
19
19
  import expo.modules.devlauncher.modules.DevLauncherDevMenuExtension
20
- import expo.modules.devlauncher.rncompatibility.DevLauncherReactNativeHostHandler
20
+ import expo.modules.devlauncher.react.DevLauncherReactNativeHostHandler
21
21
  import expo.modules.updatesinterface.UpdatesControllerRegistry
22
22
  import java.lang.ref.WeakReference
23
23
 
@@ -19,9 +19,9 @@ import com.facebook.react.runtime.ReactHostDelegate
19
19
  import com.facebook.react.runtime.ReactHostImpl
20
20
  import expo.interfaces.devmenu.ReactHostWrapper
21
21
  import expo.modules.devlauncher.launcher.DevLauncherControllerInterface
22
+ import expo.modules.devlauncher.react.DevLauncherBridgeDevSupportManager
23
+ import expo.modules.devlauncher.react.DevLauncherBridgelessDevSupportManager
22
24
  import expo.modules.devlauncher.react.DevLauncherDevSupportManagerSwapper
23
- import expo.modules.devlauncher.rncompatibility.DevLauncherBridgeDevSupportManager
24
- import expo.modules.devlauncher.rncompatibility.DevLauncherBridgelessDevSupportManager
25
25
  import expo.modules.devmenu.DevMenuManager
26
26
  import expo.modules.devmenu.helpers.setPrivateDeclaredFieldValue
27
27
  import okhttp3.HttpUrl
@@ -1,4 +1,4 @@
1
- package expo.modules.devlauncher.rncompatibility
1
+ package expo.modules.devlauncher.react
2
2
 
3
3
  import android.content.Context
4
4
  import android.util.Log
@@ -1,4 +1,4 @@
1
- package expo.modules.devlauncher.rncompatibility
1
+ package expo.modules.devlauncher.react
2
2
 
3
3
  import android.content.Context
4
4
  import com.facebook.hermes.reactexecutor.HermesExecutorFactory
@@ -1,4 +1,4 @@
1
- package expo.modules.devlauncher.rncompatibility
1
+ package expo.modules.devlauncher.react
2
2
 
3
3
  import android.content.Context
4
4
  import android.util.Log
@@ -1,4 +1,4 @@
1
- package expo.modules.devlauncher.rncompatibility
1
+ package expo.modules.devlauncher.react
2
2
 
3
3
  import android.content.Context
4
4
  import com.facebook.react.common.SurfaceDelegateFactory
@@ -16,8 +16,8 @@ import expo.modules.devlauncher.helpers.getProtectedFieldValue
16
16
  import expo.modules.devlauncher.helpers.setProtectedDeclaredField
17
17
  import expo.modules.devlauncher.koin.DevLauncherKoinComponent
18
18
  import expo.modules.devlauncher.launcher.DevLauncherControllerInterface
19
- import expo.modules.devlauncher.rncompatibility.DevLauncherBridgeDevSupportManager
20
- import expo.modules.devlauncher.rncompatibility.DevLauncherBridgelessDevSupportManager
19
+ import expo.modules.devlauncher.react.DevLauncherBridgeDevSupportManager
20
+ import expo.modules.devlauncher.react.DevLauncherBridgelessDevSupportManager
21
21
  import kotlinx.coroutines.delay
22
22
  import kotlinx.coroutines.launch
23
23
  import org.koin.core.component.inject
@@ -0,0 +1,84 @@
1
+ package expo.modules.devlauncher.react
2
+
3
+ import android.content.Context
4
+ import android.util.Log
5
+ import com.facebook.react.devsupport.NonFinalBridgelessDevSupportManager
6
+ import com.facebook.react.devsupport.ReactInstanceDevHelper
7
+ import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener
8
+ import com.facebook.react.devsupport.interfaces.RedBoxHandler
9
+ import com.facebook.react.packagerconnection.RequestHandler
10
+ import expo.modules.devlauncher.DevLauncherController
11
+ import expo.modules.devlauncher.helpers.injectDevServerHelper
12
+ import expo.modules.devlauncher.koin.DevLauncherKoinComponent
13
+ import expo.modules.devlauncher.koin.optInject
14
+ import expo.modules.devlauncher.launcher.DevLauncherControllerInterface
15
+ import expo.modules.devlauncher.launcher.errors.DevLauncherAppError
16
+ import expo.modules.devlauncher.launcher.errors.DevLauncherErrorActivity
17
+
18
+ class DevLauncherBridgelessDevSupportManager(
19
+ applicationContext: Context,
20
+ reactInstanceDevHelper: ReactInstanceDevHelper,
21
+ packagerPathForJSBundleName: String?,
22
+ enableOnCreate: Boolean,
23
+ redBoxHandler: RedBoxHandler?,
24
+ devBundleDownloadListener: DevBundleDownloadListener?,
25
+ minNumShakes: Int,
26
+ customPackagerCommandHandlers: MutableMap<String, RequestHandler>?
27
+ ) : NonFinalBridgelessDevSupportManager(
28
+ applicationContext,
29
+ reactInstanceDevHelper,
30
+ packagerPathForJSBundleName,
31
+ enableOnCreate,
32
+ redBoxHandler,
33
+ devBundleDownloadListener,
34
+ minNumShakes,
35
+ customPackagerCommandHandlers,
36
+ null,
37
+ null,
38
+ null
39
+ ), DevLauncherKoinComponent {
40
+ private val controller: DevLauncherControllerInterface? by optInject()
41
+
42
+ init {
43
+ injectDevServerHelper(applicationContext, this, controller)
44
+ }
45
+
46
+ @Suppress("INAPPLICABLE_JVM_NAME")
47
+ @get:JvmName("getjSBundleURLForRemoteDebugging")
48
+ override val jSBundleURLForRemoteDebugging: String? = super.getJSBundleURLForRemoteDebugging()
49
+
50
+ override fun showNewJavaError(message: String?, e: Throwable?) {
51
+ Log.e("DevLauncher", "$message", e)
52
+ if (!DevLauncherController.wasInitialized()) {
53
+ Log.e("DevLauncher", "DevLauncher wasn't initialized. Couldn't intercept native error handling.")
54
+ super.showNewJavaError(message, e)
55
+ return
56
+ }
57
+
58
+ val activity = reactInstanceDevHelper?.currentActivity
59
+ if (activity == null || activity.isFinishing || activity.isDestroyed) {
60
+ return
61
+ }
62
+
63
+ controller?.onAppLoadedWithError()
64
+ DevLauncherErrorActivity.showError(activity, DevLauncherAppError(message, e))
65
+ }
66
+
67
+ override fun getUniqueTag() = "DevLauncherApp-Bridgeless"
68
+
69
+ override fun startInspector() {
70
+ // no-op for the default `startInspector` which would be implicitly called
71
+ // right after `ReactInstanceManager` construction.
72
+ // For dev-launcher, we should inject the correct dev server address and
73
+ // call our customized `startInspectorWhenDevLauncherReady`.
74
+ // Check `DevLauncherReactUtils.injectReactInterceptor()` for details.
75
+ }
76
+
77
+ fun startInspectorWhenDevLauncherReady() {
78
+ super.startInspector()
79
+ }
80
+
81
+ companion object {
82
+ fun getDevHelperInternalFieldName() = "mReactInstanceDevHelper"
83
+ }
84
+ }
@@ -0,0 +1,75 @@
1
+ package expo.modules.devlauncher.react
2
+
3
+ import android.content.Context
4
+ import com.facebook.react.common.SurfaceDelegateFactory
5
+ import com.facebook.react.devsupport.DevSupportManagerFactory
6
+ import com.facebook.react.devsupport.ReleaseDevSupportManager
7
+ import com.facebook.react.devsupport.ReactInstanceDevHelper
8
+ import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener
9
+ import com.facebook.react.devsupport.interfaces.DevLoadingViewManager
10
+ import com.facebook.react.devsupport.interfaces.DevSupportManager
11
+ import com.facebook.react.devsupport.interfaces.PausedInDebuggerOverlayManager
12
+ import com.facebook.react.devsupport.interfaces.RedBoxHandler
13
+ import com.facebook.react.packagerconnection.RequestHandler
14
+
15
+ class DevLauncherDevSupportManagerFactory : DevSupportManagerFactory {
16
+
17
+ override fun create(
18
+ applicationContext: Context,
19
+ reactInstanceDevHelper: ReactInstanceDevHelper,
20
+ packagerPathForJSBundleName: String?,
21
+ enableOnCreate: Boolean,
22
+ redBoxHandler: RedBoxHandler?,
23
+ devBundleDownloadListener: DevBundleDownloadListener?,
24
+ minNumShakes: Int,
25
+ customPackagerCommandHandlers: Map<String, RequestHandler>?,
26
+ surfaceDelegateFactory: SurfaceDelegateFactory?,
27
+ devLoadingViewManager: DevLoadingViewManager?,
28
+ pausedInDebuggerOverlayManager: PausedInDebuggerOverlayManager?
29
+ ): DevSupportManager {
30
+ return if (!enableOnCreate) {
31
+ ReleaseDevSupportManager()
32
+ } else {
33
+ DevLauncherBridgeDevSupportManager(
34
+ applicationContext,
35
+ reactInstanceDevHelper,
36
+ packagerPathForJSBundleName,
37
+ enableOnCreate,
38
+ redBoxHandler,
39
+ devBundleDownloadListener,
40
+ minNumShakes,
41
+ customPackagerCommandHandlers?.toMutableMap()
42
+ )
43
+ }
44
+ }
45
+
46
+ override fun create(
47
+ applicationContext: Context,
48
+ reactInstanceDevHelper: ReactInstanceDevHelper,
49
+ packagerPathForJSBundleName: String?,
50
+ enableOnCreate: Boolean,
51
+ redBoxHandler: RedBoxHandler?,
52
+ devBundleDownloadListener: DevBundleDownloadListener?,
53
+ minNumShakes: Int,
54
+ customPackagerCommandHandlers: Map<String, RequestHandler>?,
55
+ surfaceDelegateFactory: SurfaceDelegateFactory?,
56
+ devLoadingViewManager: DevLoadingViewManager?,
57
+ pausedInDebuggerOverlayManager: PausedInDebuggerOverlayManager?,
58
+ useDevSupport: Boolean
59
+ ): DevSupportManager {
60
+ return if (!useDevSupport) {
61
+ ReleaseDevSupportManager()
62
+ } else {
63
+ DevLauncherBridgelessDevSupportManager(
64
+ applicationContext,
65
+ reactInstanceDevHelper,
66
+ packagerPathForJSBundleName,
67
+ enableOnCreate,
68
+ redBoxHandler,
69
+ devBundleDownloadListener,
70
+ minNumShakes,
71
+ customPackagerCommandHandlers?.toMutableMap()
72
+ )
73
+ }
74
+ }
75
+ }
@@ -0,0 +1,179 @@
1
+ package expo.modules.devlauncher.react
2
+
3
+ import android.util.Log
4
+ import com.facebook.react.ReactHost
5
+ import com.facebook.react.ReactInstanceManager
6
+ import com.facebook.react.ReactNativeHost
7
+ import com.facebook.react.common.ShakeDetector
8
+ import com.facebook.react.devsupport.DevServerHelper
9
+ import com.facebook.react.devsupport.DevSupportManagerBase
10
+ import com.facebook.react.devsupport.ReleaseDevSupportManager
11
+ import com.facebook.react.devsupport.interfaces.DevSupportManager
12
+ import com.facebook.react.packagerconnection.JSPackagerClient
13
+ import com.facebook.react.runtime.ReactHostImpl
14
+ import expo.interfaces.devmenu.ReactHostWrapper
15
+ import expo.modules.devlauncher.helpers.getProtectedFieldValue
16
+ import expo.modules.devlauncher.helpers.setProtectedDeclaredField
17
+ import expo.modules.devlauncher.koin.DevLauncherKoinComponent
18
+ import expo.modules.devlauncher.launcher.DevLauncherControllerInterface
19
+ import expo.modules.devlauncher.react.DevLauncherBridgeDevSupportManager
20
+ import expo.modules.devlauncher.react.DevLauncherBridgelessDevSupportManager
21
+ import kotlinx.coroutines.delay
22
+ import kotlinx.coroutines.launch
23
+ import org.koin.core.component.inject
24
+
25
+ internal class DevLauncherDevSupportManagerSwapper : DevLauncherKoinComponent {
26
+ private val controller: DevLauncherControllerInterface by inject()
27
+
28
+ fun swapDevSupportManagerImpl(reactHost: ReactHostWrapper) {
29
+ if (reactHost.isBridgelessMode) {
30
+ swapDevSupportManagerImpl(reactHost.reactHost)
31
+ } else {
32
+ swapDevSupportManagerImpl(reactHost.reactNativeHost)
33
+ }
34
+ }
35
+
36
+ private fun swapDevSupportManagerImpl(reactNativeHost: ReactNativeHost) {
37
+ val reactInstanceManager = reactNativeHost.reactInstanceManager
38
+ val currentDevSupportManager = reactInstanceManager.devSupportManager
39
+ if (currentDevSupportManager is DevLauncherBridgeDevSupportManager) {
40
+ // DevSupportManager was swapped by the DevLauncherReactNativeHostHandler
41
+ return
42
+ }
43
+ if (currentDevSupportManager is ReleaseDevSupportManager) {
44
+ Log.i("DevLauncher", "DevSupportManager is disabled. So we don't want to override it.")
45
+ return
46
+ }
47
+
48
+ try {
49
+ val devManagerClass = DevSupportManagerBase::class.java
50
+ val newDevSupportManager = createDevLauncherBridgeDevSupportManager(devManagerClass, currentDevSupportManager)
51
+
52
+ ReactInstanceManager::class.java.setProtectedDeclaredField(reactInstanceManager, "mDevSupportManager", newDevSupportManager)
53
+
54
+ closeExistingConnection(devManagerClass, currentDevSupportManager)
55
+ } catch (e: Exception) {
56
+ Log.i("DevLauncher", "Couldn't inject `DevLauncherDevSupportManager`.", e)
57
+ }
58
+ }
59
+
60
+ private fun swapDevSupportManagerImpl(reactHost: ReactHost) {
61
+ val currentDevSupportManager = requireNotNull(reactHost.devSupportManager)
62
+ if (currentDevSupportManager is DevLauncherBridgelessDevSupportManager) {
63
+ // DevSupportManager was swapped by the DevLauncherReactNativeHostHandler
64
+ return
65
+ }
66
+ if (currentDevSupportManager is ReleaseDevSupportManager) {
67
+ Log.i("DevLauncher", "DevSupportManager is disabled. So we don't want to override it.")
68
+ return
69
+ }
70
+
71
+ try {
72
+ val devManagerClass = DevSupportManagerBase::class.java
73
+ val newDevSupportManager = createDevLauncherBridgelessDevSupportManager(
74
+ devManagerClass,
75
+ currentDevSupportManager
76
+ )
77
+
78
+ ReactHostImpl::class.java.setProtectedDeclaredField(reactHost, "mDevSupportManager", newDevSupportManager)
79
+
80
+ closeExistingConnection(devManagerClass, currentDevSupportManager)
81
+ } catch (e: Exception) {
82
+ Log.i("DevLauncher", "Couldn't inject `DevLauncherDevSupportManager`.", e)
83
+ }
84
+ }
85
+
86
+ private fun createDevLauncherBridgeDevSupportManager(
87
+ devManagerClass: Class<*>,
88
+ currentDevSupportManager: DevSupportManager
89
+ ): DevLauncherBridgeDevSupportManager {
90
+ return DevLauncherBridgeDevSupportManager(
91
+ applicationContext = devManagerClass.getProtectedFieldValue(currentDevSupportManager, "mApplicationContext"),
92
+ reactInstanceDevHelper = devManagerClass.getProtectedFieldValue(currentDevSupportManager, DevLauncherBridgeDevSupportManager.getDevHelperInternalFieldName()),
93
+ packagerPathForJSBundleName = devManagerClass.getProtectedFieldValue(currentDevSupportManager, "mJSAppBundleName"),
94
+ enableOnCreate = true,
95
+ redBoxHandler = devManagerClass.getProtectedFieldValue(currentDevSupportManager, "mRedBoxHandler"),
96
+ devBundleDownloadListener = devManagerClass.getProtectedFieldValue(currentDevSupportManager, "mBundleDownloadListener"),
97
+ minNumShakes = 1,
98
+ customPackagerCommandHandlers = devManagerClass.getProtectedFieldValue(currentDevSupportManager, "mCustomPackagerCommandHandlers")
99
+ )
100
+ }
101
+
102
+ private fun createDevLauncherBridgelessDevSupportManager(
103
+ devManagerClass: Class<*>,
104
+ currentDevSupportManager: DevSupportManager
105
+ ): DevLauncherBridgelessDevSupportManager {
106
+ return DevLauncherBridgelessDevSupportManager(
107
+ applicationContext = devManagerClass.getProtectedFieldValue(currentDevSupportManager, "mApplicationContext"),
108
+ reactInstanceDevHelper = devManagerClass.getProtectedFieldValue(currentDevSupportManager, DevLauncherBridgeDevSupportManager.getDevHelperInternalFieldName()),
109
+ packagerPathForJSBundleName = devManagerClass.getProtectedFieldValue(currentDevSupportManager, "mJSAppBundleName"),
110
+ enableOnCreate = true,
111
+ redBoxHandler = devManagerClass.getProtectedFieldValue(currentDevSupportManager, "mRedBoxHandler"),
112
+ devBundleDownloadListener = devManagerClass.getProtectedFieldValue(currentDevSupportManager, "mBundleDownloadListener"),
113
+ minNumShakes = 1,
114
+ customPackagerCommandHandlers = devManagerClass.getProtectedFieldValue(currentDevSupportManager, "mCustomPackagerCommandHandlers")
115
+ )
116
+ }
117
+
118
+ /**
119
+ * We need to invalidate the old packager connection.
120
+ * However, this connection is established in the background
121
+ * and we don't know when it will be available (see [DevServerHelper.openPackagerConnection]).
122
+ * So we just wait for connection and then we kill it.
123
+ */
124
+ private fun closeExistingConnection(devManagerClass: Class<*>, devSupportManager: DevSupportManager) {
125
+ controller.coroutineScope.launch {
126
+ try {
127
+ while (true) {
128
+ // Invalidate shake detector - not doing that leads to memory leaks
129
+ tryToStopShakeDetector(devSupportManager)
130
+
131
+ val devServerHelper: DevServerHelper = devManagerClass.getProtectedFieldValue(
132
+ devSupportManager,
133
+ "mDevServerHelper"
134
+ )
135
+
136
+ try {
137
+ val packagerConnectionLock: Boolean = DevServerHelper::class.java.getProtectedFieldValue(
138
+ devServerHelper,
139
+ "mPackagerConnectionLock"
140
+ )
141
+
142
+ if (!packagerConnectionLock) {
143
+ devServerHelper.closePackagerConnection()
144
+ return@launch
145
+ }
146
+ } catch (_: NoSuchFieldException) {
147
+ // mPackagerConnectionLock was removed from the React Native in v0.63.4
148
+ val packagerClient: JSPackagerClient? = DevServerHelper::class.java.getProtectedFieldValue(
149
+ devServerHelper,
150
+ "mPackagerClient"
151
+ )
152
+
153
+ if (packagerClient != null) {
154
+ devServerHelper.closePackagerConnection()
155
+ return@launch
156
+ }
157
+ }
158
+
159
+ delay(50)
160
+ }
161
+ } catch (e: Exception) {
162
+ Log.w("DevLauncher", "Couldn't close the packager connection: ${e.message}", e)
163
+ }
164
+ }
165
+ }
166
+
167
+ private fun tryToStopShakeDetector(currentDevSupportManager: DevSupportManager) {
168
+ try {
169
+ val shakeDetector: ShakeDetector =
170
+ DevSupportManagerBase::class.java.getProtectedFieldValue(
171
+ currentDevSupportManager,
172
+ "mShakeDetector"
173
+ )
174
+ shakeDetector.stop()
175
+ } catch (e: Exception) {
176
+ Log.w("DevLauncher", "Couldn't stop shake detector.", e)
177
+ }
178
+ }
179
+ }
@@ -0,0 +1,202 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.devsupport;
9
+
10
+ import android.content.Context;
11
+ import androidx.annotation.Nullable;
12
+ import com.facebook.common.logging.FLog;
13
+ import com.facebook.debug.holder.PrinterHolder;
14
+ import com.facebook.debug.tags.ReactDebugOverlayTags;
15
+ import com.facebook.infer.annotation.Assertions;
16
+ import com.facebook.react.bridge.CatalystInstance;
17
+ import com.facebook.react.bridge.JSBundleLoader;
18
+ import com.facebook.react.bridge.JavaJSExecutor;
19
+ import com.facebook.react.bridge.ReactMarker;
20
+ import com.facebook.react.bridge.ReactMarkerConstants;
21
+ import com.facebook.react.bridge.UiThreadUtil;
22
+ import com.facebook.react.common.ReactConstants;
23
+ import com.facebook.react.common.SurfaceDelegateFactory;
24
+ import com.facebook.react.common.futures.SimpleSettableFuture;
25
+ import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
26
+ import com.facebook.react.devsupport.interfaces.DevLoadingViewManager;
27
+ import com.facebook.react.devsupport.interfaces.DevSplitBundleCallback;
28
+ import com.facebook.react.devsupport.interfaces.PausedInDebuggerOverlayManager;
29
+ import com.facebook.react.devsupport.interfaces.RedBoxHandler;
30
+ import com.facebook.react.packagerconnection.RequestHandler;
31
+ import java.io.IOException;
32
+ import java.util.Map;
33
+ import java.util.concurrent.ExecutionException;
34
+ import java.util.concurrent.TimeUnit;
35
+ import java.util.concurrent.TimeoutException;
36
+
37
+ //
38
+ // Expo: This is a copy of react-native's {@link com.facebook.react.devsupport.BridgeDevSupportManager}
39
+ // just removing the "final" modifier that we can inherit and reuse.
40
+ // From time to time for react-native upgrade, just follow the steps to update the code
41
+ // 1. Copy the contents from BridgeDevSupportManager to this file.
42
+ // 2. Rename the class to NonFinalBridgeDevSupportManager.
43
+ // 3. Remove the "final" modifier.
44
+ // 4. Revert the comment
45
+ //
46
+
47
+ /**
48
+ * Interface for accessing and interacting with development features. Following features
49
+ * are supported through this manager class:
50
+ * 1) Displaying JS errors (aka RedBox)
51
+ * 2) Displaying developers menu (Reload JS, Debug JS)
52
+ * 3) Communication with developer server in order to download updated JS bundle
53
+ * 4) Starting/stopping broadcast receiver for js reload signals
54
+ * 5) Starting/stopping motion sensor listener that recognize shake gestures which in turn may
55
+ * trigger developers menu.
56
+ * 6) Launching developers settings view
57
+ *
58
+ * This class automatically monitors the state of registered views and activities to which they are
59
+ * bound to make sure that we don't display overlay or that we we don't listen for sensor events
60
+ * when app is backgrounded.
61
+ *
62
+ * {@link com.facebook.react.ReactInstanceManager} implementation is responsible for instantiating
63
+ * this class as well as for populating with a reference to {@link CatalystInstance} whenever
64
+ * instance manager recreates it (through {@link #onNewReactContextCreated). Also, instance manager
65
+ * is responsible for enabling/disabling dev support in case when app is backgrounded or when all
66
+ * the views has been detached from the instance (through {@link #setDevSupportEnabled} method).
67
+ */
68
+ public class NonFinalBridgeDevSupportManager extends DevSupportManagerBase {
69
+ private boolean mIsSamplingProfilerEnabled = false;
70
+
71
+ public NonFinalBridgeDevSupportManager(
72
+ Context applicationContext,
73
+ ReactInstanceDevHelper reactInstanceManagerHelper,
74
+ @Nullable String packagerPathForJSBundleName,
75
+ boolean enableOnCreate,
76
+ @Nullable RedBoxHandler redBoxHandler,
77
+ @Nullable DevBundleDownloadListener devBundleDownloadListener,
78
+ int minNumShakes,
79
+ @Nullable Map<String, RequestHandler> customPackagerCommandHandlers,
80
+ @Nullable SurfaceDelegateFactory surfaceDelegateFactory,
81
+ @Nullable DevLoadingViewManager devLoadingViewManager,
82
+ @Nullable PausedInDebuggerOverlayManager pausedInDebuggerOverlayManager) {
83
+ super(
84
+ applicationContext,
85
+ reactInstanceManagerHelper,
86
+ packagerPathForJSBundleName,
87
+ enableOnCreate,
88
+ redBoxHandler,
89
+ devBundleDownloadListener,
90
+ minNumShakes,
91
+ customPackagerCommandHandlers,
92
+ surfaceDelegateFactory,
93
+ devLoadingViewManager,
94
+ pausedInDebuggerOverlayManager);
95
+ }
96
+
97
+ @Override
98
+ protected String getUniqueTag() {
99
+ return "Bridge";
100
+ }
101
+
102
+ @Override
103
+ public void loadSplitBundleFromServer(
104
+ final String bundlePath, final DevSplitBundleCallback callback) {
105
+ fetchSplitBundleAndCreateBundleLoader(
106
+ bundlePath,
107
+ new CallbackWithBundleLoader() {
108
+ @Override
109
+ public void onSuccess(JSBundleLoader bundleLoader) {
110
+ bundleLoader.loadScript(getCurrentReactContext().getCatalystInstance());
111
+ getCurrentReactContext()
112
+ .getJSModule(HMRClient.class)
113
+ .registerBundle(getDevServerHelper().getDevServerSplitBundleURL(bundlePath));
114
+ callback.onSuccess();
115
+ }
116
+
117
+ @Override
118
+ public void onError(String url, Throwable cause) {
119
+ callback.onError(url, cause);
120
+ }
121
+ });
122
+ }
123
+
124
+ private WebsocketJavaScriptExecutor.JSExecutorConnectCallback getExecutorConnectCallback(
125
+ final SimpleSettableFuture<Boolean> future) {
126
+ return new WebsocketJavaScriptExecutor.JSExecutorConnectCallback() {
127
+ @Override
128
+ public void onSuccess() {
129
+ future.set(true);
130
+ hideDevLoadingView();
131
+ }
132
+
133
+ @Override
134
+ public void onFailure(final Throwable cause) {
135
+ hideDevLoadingView();
136
+ FLog.e(ReactConstants.TAG, "Failed to connect to debugger!", cause);
137
+ future.setException(
138
+ new IOException(
139
+ getApplicationContext().getString(com.facebook.react.R.string.catalyst_debug_error),
140
+ cause));
141
+ }
142
+ };
143
+ }
144
+
145
+ private void reloadJSInProxyMode() {
146
+ // When using js proxy, there is no need to fetch JS bundle as proxy executor will do that
147
+ // anyway
148
+ getDevServerHelper().launchJSDevtools();
149
+
150
+ JavaJSExecutor.Factory factory =
151
+ new JavaJSExecutor.Factory() {
152
+ @Override
153
+ public JavaJSExecutor create() throws Exception {
154
+ WebsocketJavaScriptExecutor executor = new WebsocketJavaScriptExecutor();
155
+ SimpleSettableFuture<Boolean> future = new SimpleSettableFuture<>();
156
+ executor.connect(
157
+ getDevServerHelper().getWebsocketProxyURL(), getExecutorConnectCallback(future));
158
+ // TODO(t9349129) Don't use timeout
159
+ try {
160
+ future.get(90, TimeUnit.SECONDS);
161
+ return executor;
162
+ } catch (ExecutionException e) {
163
+ throw (Exception) e.getCause();
164
+ } catch (InterruptedException | TimeoutException e) {
165
+ throw new RuntimeException(e);
166
+ }
167
+ }
168
+ };
169
+ getReactInstanceDevHelper().onReloadWithJSDebugger(factory);
170
+ }
171
+
172
+ @Override
173
+ public void handleReloadJS() {
174
+
175
+ UiThreadUtil.assertOnUiThread();
176
+
177
+ ReactMarker.logMarker(
178
+ ReactMarkerConstants.RELOAD,
179
+ getDevSettings().getPackagerConnectionSettings().getDebugServerHost());
180
+
181
+ // dismiss redbox if exists
182
+ hideRedboxDialog();
183
+
184
+ if (getDevSettings().isRemoteJSDebugEnabled()) {
185
+ PrinterHolder.getPrinter()
186
+ .logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: load from Proxy");
187
+ showDevLoadingViewForRemoteJSEnabled();
188
+ reloadJSInProxyMode();
189
+ } else {
190
+ PrinterHolder.getPrinter()
191
+ .logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: load from Server");
192
+ String bundleURL =
193
+ getDevServerHelper()
194
+ .getDevServerBundleURL(Assertions.assertNotNull(getJSAppBundleName()));
195
+ reloadJSFromServer(
196
+ bundleURL,
197
+ () ->
198
+ UiThreadUtil.runOnUiThread(
199
+ () -> getReactInstanceDevHelper().onJSBundleLoadedFromServer()));
200
+ }
201
+ }
202
+ }
@@ -0,0 +1,134 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.devsupport;
9
+
10
+ import android.content.Context;
11
+ import androidx.annotation.Nullable;
12
+ import com.facebook.infer.annotation.Nullsafe;
13
+ import com.facebook.react.bridge.JSBundleLoader;
14
+ import com.facebook.react.bridge.ReactContext;
15
+ import com.facebook.react.bridge.UiThreadUtil;
16
+ import com.facebook.react.common.SurfaceDelegateFactory;
17
+ import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
18
+ import com.facebook.react.devsupport.interfaces.DevLoadingViewManager;
19
+ import com.facebook.react.devsupport.interfaces.DevSplitBundleCallback;
20
+ import com.facebook.react.devsupport.interfaces.PausedInDebuggerOverlayManager;
21
+ import com.facebook.react.devsupport.interfaces.RedBoxHandler;
22
+ import com.facebook.react.packagerconnection.RequestHandler;
23
+ import java.util.Map;
24
+
25
+ //
26
+ // Expo: This is a copy of react-native's {@link com.facebook.react.devsupport.BridgelessDevSupportManager}
27
+ // just removing the "final" modifier that we can inherit and reuse.
28
+ // From time to time for react-native upgrade, just follow the steps to update the code
29
+ // 1. Copy the contents from BridgelessDevSupportManager to this file.
30
+ // 2. Rename the class to NonFinalBridgelessDevSupportManager.
31
+ // 3. Add "public" modifier
32
+ // 4. Revert the comment
33
+ //
34
+
35
+ /**
36
+ * An implementation of {@link com.facebook.react.devsupport.interfaces.DevSupportManager} that
37
+ * extends the functionality in {@link DevSupportManagerBase} with some additional, more flexible
38
+ * APIs for asynchronously loading the JS bundle.
39
+ */
40
+ @Nullsafe(Nullsafe.Mode.LOCAL)
41
+ public class NonFinalBridgelessDevSupportManager extends DevSupportManagerBase {
42
+
43
+ public NonFinalBridgelessDevSupportManager(
44
+ Context context,
45
+ ReactInstanceDevHelper reactInstanceManagerHelper,
46
+ @Nullable String packagerPathForJSBundleName) {
47
+ this(
48
+ context.getApplicationContext(),
49
+ reactInstanceManagerHelper,
50
+ packagerPathForJSBundleName,
51
+ true /* enableOnCreate */,
52
+ null /* redBoxHandler */,
53
+ null /* devBundleDownloadListener */,
54
+ 2 /* minNumShakes */,
55
+ null /* customPackagerCommandHandlers */,
56
+ null /* surfaceDelegateFactory */,
57
+ null /* devLoadingViewManager */,
58
+ null /* pausedInDebuggerOverlayManager */);
59
+ }
60
+
61
+ /**
62
+ * This constructor mirrors the same constructor we have for {@link BridgeDevSupportManager} and
63
+ * is kept for backward compatibility.
64
+ */
65
+ public NonFinalBridgelessDevSupportManager(
66
+ Context applicationContext,
67
+ ReactInstanceDevHelper reactInstanceManagerHelper,
68
+ @Nullable String packagerPathForJSBundleName,
69
+ boolean enableOnCreate,
70
+ @Nullable RedBoxHandler redBoxHandler,
71
+ @Nullable DevBundleDownloadListener devBundleDownloadListener,
72
+ int minNumShakes,
73
+ @Nullable Map<String, RequestHandler> customPackagerCommandHandlers,
74
+ @Nullable SurfaceDelegateFactory surfaceDelegateFactory,
75
+ @Nullable DevLoadingViewManager devLoadingViewManager,
76
+ @Nullable PausedInDebuggerOverlayManager pausedInDebuggerOverlayManager) {
77
+ super(
78
+ applicationContext,
79
+ reactInstanceManagerHelper,
80
+ packagerPathForJSBundleName,
81
+ enableOnCreate,
82
+ redBoxHandler,
83
+ devBundleDownloadListener,
84
+ minNumShakes,
85
+ customPackagerCommandHandlers,
86
+ surfaceDelegateFactory,
87
+ devLoadingViewManager,
88
+ pausedInDebuggerOverlayManager);
89
+ }
90
+
91
+ @Override
92
+ protected String getUniqueTag() {
93
+ return "Bridgeless";
94
+ }
95
+
96
+ @Override
97
+ public void loadSplitBundleFromServer(
98
+ final String bundlePath, final DevSplitBundleCallback callback) {
99
+ fetchSplitBundleAndCreateBundleLoader(
100
+ bundlePath,
101
+ new CallbackWithBundleLoader() {
102
+ @Override
103
+ public void onSuccess(final JSBundleLoader bundleLoader) {
104
+ try {
105
+ mReactInstanceDevHelper.loadBundle(bundleLoader).waitForCompletion();
106
+ String bundleURL = getDevServerHelper().getDevServerSplitBundleURL(bundlePath);
107
+ ReactContext reactContext = mReactInstanceDevHelper.getCurrentReactContext();
108
+ if (reactContext != null) {
109
+ reactContext.getJSModule(HMRClient.class).registerBundle(bundleURL);
110
+ }
111
+ callback.onSuccess();
112
+ } catch (InterruptedException e) {
113
+ Thread.currentThread().interrupt();
114
+ throw new RuntimeException(
115
+ "[BridgelessDevSupportManager]: Got interrupted while loading bundle", e);
116
+ }
117
+ }
118
+
119
+ @Override
120
+ public void onError(String url, Throwable cause) {
121
+ callback.onError(url, cause);
122
+ }
123
+ });
124
+ }
125
+
126
+ @Override
127
+ public void handleReloadJS() {
128
+ UiThreadUtil.assertOnUiThread();
129
+
130
+ // dismiss redbox if exists
131
+ hideRedboxDialog();
132
+ mReactInstanceDevHelper.reload("BridgelessDevSupportManager.handleReloadJS()");
133
+ }
134
+ }
package/ios/main.jsbundle CHANGED
@@ -742,7 +742,7 @@ __d((function(g,r,i,a,m,e,d){var t=r(d[0]);Object.defineProperty(e,"__esModule",
742
742
  __d((function(g,r,i,a,m,e,d){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,(0,r(d[0]).ensureNativeModulesAreInstalled)();e.default=globalThis.expo.NativeModule}),659,[656]);
743
743
  __d((function(g,r,i,a,m,e,d){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var t,n=r(d[0]),o=n.NativeModules.NativeUnimoduleProxy,l=null==(t=g.expo)||null==(t=t.modules)?void 0:t.NativeModulesProxy,u='exportedMethods',s={};if(o){var v=null!=l?l:o;Object.keys(v[u]).forEach((function(t){s[t]=v.modulesConstants[t]||{},v[u][t].forEach((function(n){s[t][n.name]=function(){for(var u=arguments.length,s=new Array(u),v=0;v<u;v++)s[v]=arguments[v];if(null!=l&&l.callMethod)return l.callMethod(t,n.name,s);var c=n.key,f=n.argumentsCount;return f!==s.length?Promise.reject(new Error(`Native method ${t}.${n.name} expects ${f} ${1===f?'argument':'arguments'} but received ${s.length}`)):o.callMethod(t,c,s)}})),n.NativeModules.EXReactNativeEventEmitter?(s[t].addListener=function(){for(var o,l=arguments.length,u=new Array(l),s=0;s<l;s++)u[s]=arguments[s];return(o=n.NativeModules.EXReactNativeEventEmitter).addProxiedListener.apply(o,[t].concat(u))},s[t].removeListeners=function(){for(var o,l=arguments.length,u=new Array(l),s=0;s<l;s++)u[s]=arguments[s];return(o=n.NativeModules.EXReactNativeEventEmitter).removeProxiedListeners.apply(o,[t].concat(u))}):(s[t].addListener=function(){},s[t].removeListeners=function(){})}))}else console.warn("The \"EXNativeModulesProxy\" native module is not exported through NativeModules; verify that expo-modules-core's native code is linked properly");e.default=s}),660,[1]);
744
744
  __d((function(g,r,i,a,m,e,d){}),661,[]);
745
- __d((function(g,_r,_i,_a,m,_e,d){var e=_r(d[0]);Object.defineProperty(_e,"__esModule",{value:!0}),_e.requireNativeViewManager=function(e){var r,a,l=i.NativeModules.NativeUnimoduleProxy.viewManagersMetadata,p=(null==l||l[e],null!=(r=null==(a=globalThis.expo)?void 0:a.__expo_app_identifier__)?r:''),v=w(`ViewManagerAdapter_${e}${p?`_${p}`:''}`),y=(function(e){function r(){var e;(0,t.default)(this,r);for(var n=arguments.length,a=new Array(n),o=0;o<n;o++)a[o]=arguments[o];return(e=s(this,r,[].concat(a))).nativeTag=null,e}return(0,o.default)(r,e),(0,n.default)(r,[{key:"componentDidMount",value:function(){this.nativeTag=(0,i.findNodeHandle)(this)}},{key:"render",value:function(){return(0,c.jsx)(v,Object.assign({},this.props))}}])})(u.default.PureComponent);y.displayName=e;try{var _=(0,f.requireNativeModule)(e).ViewPrototype;_&&Object.assign(y.prototype,_)}catch(e){}return y};var t=e(_r(d[1])),n=e(_r(d[2])),r=e(_r(d[3])),a=e(_r(d[4])),o=e(_r(d[5])),u=e(_r(d[6])),i=_r(d[7]),l=(function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=p(t);if(n&&n.has(e))return n.get(e);var r={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&{}.hasOwnProperty.call(e,o)){var u=a?Object.getOwnPropertyDescriptor(e,o):null;u&&(u.get||u.set)?Object.defineProperty(r,o,u):r[o]=e[o]}return r.default=e,n&&n.set(e,r),r})(_r(d[8])),f=_r(d[9]),c=_r(d[10]);function p(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(p=function(e){return e?n:t})(e)}function s(e,t,n){return t=(0,a.default)(t),(0,r.default)(e,v()?Reflect.construct(t,n||[],(0,a.default)(e).constructor):t.apply(e,n))}function v(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(v=function(){return!!e})()}var y=new Map;function _(e){return l.get(e,(function(){var t,n=e.replace('ViewManagerAdapter_',''),r=null==(t=globalThis.expo)?void 0:t.getViewConfig(n);return r||console.warn('Unable to get the view config for %s',n),Object.assign({uiViewClassName:e},r)}))}function w(e){var t=y.get(e);if(!t){var n=_(e);return y.set(e,n),n}return t}}),662,[21,13,14,25,27,30,109,1,64,663,250]);
745
+ __d((function(g,_r,_i,_a,m,_e,d){var e=_r(d[0]);Object.defineProperty(_e,"__esModule",{value:!0}),_e.requireNativeViewManager=function(e){var r,a,l=i.NativeModules.NativeUnimoduleProxy.viewManagersMetadata,p=(null==l||l[e],null!=(r=null==(a=globalThis.expo)?void 0:a.__expo_app_identifier__)?r:''),v=w(`ViewManagerAdapter_${e}${p?`_${p}`:''}`),y=(function(e){function r(){var e;(0,t.default)(this,r);for(var n=arguments.length,a=new Array(n),o=0;o<n;o++)a[o]=arguments[o];return(e=s(this,r,[].concat(a))).nativeRef=u.default.createRef(),e.nativeTag=null,e}return(0,o.default)(r,e),(0,n.default)(r,[{key:"componentDidMount",value:function(){this.nativeTag=(0,i.findNodeHandle)(this.nativeRef.current)}},{key:"render",value:function(){return(0,c.jsx)(v,Object.assign({},this.props,{ref:this.nativeRef}))}}])})(u.default.PureComponent);y.displayName=e;try{var _=(0,f.requireNativeModule)(e).ViewPrototype;_&&Object.assign(y.prototype,_)}catch(e){}return y};var t=e(_r(d[1])),n=e(_r(d[2])),r=e(_r(d[3])),a=e(_r(d[4])),o=e(_r(d[5])),u=e(_r(d[6])),i=_r(d[7]),l=(function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=p(t);if(n&&n.has(e))return n.get(e);var r={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&{}.hasOwnProperty.call(e,o)){var u=a?Object.getOwnPropertyDescriptor(e,o):null;u&&(u.get||u.set)?Object.defineProperty(r,o,u):r[o]=e[o]}return r.default=e,n&&n.set(e,r),r})(_r(d[8])),f=_r(d[9]),c=_r(d[10]);function p(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(p=function(e){return e?n:t})(e)}function s(e,t,n){return t=(0,a.default)(t),(0,r.default)(e,v()?Reflect.construct(t,n||[],(0,a.default)(e).constructor):t.apply(e,n))}function v(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(v=function(){return!!e})()}var y=new Map;function _(e){return l.get(e,(function(){var t,n=e.replace('ViewManagerAdapter_',''),r=null==(t=globalThis.expo)?void 0:t.getViewConfig(n);return r||console.warn('Unable to get the view config for %s',n),Object.assign({uiViewClassName:e},r)}))}function w(e){var t=y.get(e);if(!t){var n=_(e);return y.set(e,n),n}return t}}),662,[21,13,14,25,27,30,109,1,64,663,250]);
746
746
  __d((function(g,r,i,a,m,e,d){var l=r(d[0]);Object.defineProperty(e,"__esModule",{value:!0}),e.requireNativeModule=function(l){var n=o(l);if(!n)throw new Error(`Cannot find native module '${l}'`);return n},e.requireOptionalNativeModule=o;var n=l(r(d[1])),u=r(d[2]);function o(l){var o,t,v;return(0,u.ensureNativeModulesAreInstalled)(),null!=(o=null!=(t=null==(v=globalThis.expo)||null==(v=v.modules)?void 0:v[l])?t:n.default[l])?o:null}}),663,[21,660,656]);
747
747
  __d((function(g,r,i,a,m,e,d){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var n=r(d[0]),t=r(d[1]),s={OS:"ios",select:'undefined'!=typeof window?n.Platform.select:function(n){return n.hasOwnProperty("ios")?n.ios:n.hasOwnProperty('native')?n.native:n.hasOwnProperty('default')?n.default:void 0},isDOMAvailable:t.isDOMAvailable,canUseEventListeners:t.canUseEventListeners,canUseViewport:t.canUseViewport,isAsyncDebugging:t.isAsyncDebugging};e.default=s}),664,[1,665]);
748
748
  __d((function(g,r,i,a,m,e,d){Object.defineProperty(e,"__esModule",{value:!0}),e.isDOMAvailable=e.isAsyncDebugging=e.canUseViewport=e.canUseEventListeners=void 0;e.isDOMAvailable=!1,e.canUseEventListeners=!1,e.canUseViewport=!1,e.isAsyncDebugging=!1}),665,[]);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-dev-launcher",
3
3
  "title": "Expo Development Launcher",
4
- "version": "5.0.14",
4
+ "version": "5.0.16",
5
5
  "description": "Pre-release version of the Expo development launcher package for testing.",
6
6
  "main": "build/DevLauncher.js",
7
7
  "types": "build/DevLauncher.d.ts",
@@ -31,7 +31,7 @@
31
31
  "homepage": "https://docs.expo.dev",
32
32
  "dependencies": {
33
33
  "ajv": "8.11.0",
34
- "expo-dev-menu": "6.0.9",
34
+ "expo-dev-menu": "6.0.11",
35
35
  "expo-manifests": "~0.15.0",
36
36
  "resolve-from": "^5.0.0"
37
37
  },
@@ -66,5 +66,5 @@
66
66
  ],
67
67
  "testTimeout": 15000
68
68
  },
69
- "gitHead": "9ff989048e66f85facda048e4be78329d8665e7c"
69
+ "gitHead": "6cbc7c671f769d36e4294f25a9445281912e45fd"
70
70
  }