pulse-updates 1.0.20 → 1.0.21

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.
@@ -199,33 +199,43 @@ class PulseUpdatesModule(private val reactContext: ReactApplicationContext) :
199
199
  return@runOnUiThread
200
200
  }
201
201
 
202
- // Try new architecture first (ReactHost) - like expo-updates does
202
+ // New architecture (ReactHost) first.
203
+ //
204
+ // Reached through the TYPED interface, not `javaClass.getMethod("getReactHost")`:
205
+ // reflection by name looks the method up on the app's own class, and in a
206
+ // minified release R8 has renamed it. The lookup then throws, the code falls
207
+ // through to the bridge path below, and that path is gone on bridgeless — the
208
+ // user taps "Reload" and gets `ReactInstanceManager.createReactContext is
209
+ // unsupported` with the update sitting there, applied only at the next cold
210
+ // start. `ReactApplication.getReactHost()` is part of the RN interface, so it
211
+ // survives minification; older RN without it throws a LINKAGE error, which is
212
+ // caught separately so those runtimes still reach the fallback.
203
213
  try {
204
- val reactHost = reactApplication.javaClass.getMethod("getReactHost").invoke(reactApplication)
214
+ val reactHost = reactApplication.reactHost
205
215
  if (reactHost != null) {
206
216
  pulseLog(TAG, "reloadAsync: using ReactHost.reload()")
207
217
 
208
- // Check lifecycle state and resume if needed (like expo does)
218
+ // Resume first when the host is not RESUMED: reload on a paused host
219
+ // is a no-op (same reason expo-updates does this).
209
220
  val currentActivity = reactContext.currentActivity
210
221
  try {
211
- val lifecycleState = reactHost.javaClass.getMethod("getLifecycleState").invoke(reactHost)
212
- val resumedState = Class.forName("com.facebook.react.common.LifecycleState")
213
- .getField("RESUMED").get(null)
214
- if (lifecycleState != resumedState && currentActivity != null) {
215
- reactHost.javaClass.getMethod("onHostResume", android.app.Activity::class.java)
216
- .invoke(reactHost, currentActivity)
222
+ if (reactHost.lifecycleState != com.facebook.react.common.LifecycleState.RESUMED && currentActivity != null) {
223
+ reactHost.onHostResume(currentActivity)
217
224
  }
218
225
  } catch (e: Exception) {
219
226
  pulseLogWarn(TAG, "reloadAsync: could not check/resume lifecycle: ${e.message}")
220
227
  }
221
228
 
222
- reactHost.javaClass.getMethod("reload", String::class.java)
223
- .invoke(reactHost, "PulseUpdates reload")
229
+ reactHost.reload("PulseUpdates reload")
224
230
  promise.resolve(null)
225
231
  return@runOnUiThread
226
232
  }
227
- } catch (e: Exception) {
233
+ pulseLog(TAG, "reloadAsync: ReactHost is null — falling back to the bridge path")
234
+ } catch (e: LinkageError) {
235
+ // RN too old to expose ReactHost at all.
228
236
  pulseLog(TAG, "reloadAsync: ReactHost not available: ${e.message}")
237
+ } catch (e: Exception) {
238
+ pulseLogWarn(TAG, "reloadAsync: ReactHost.reload failed: ${e.message}")
229
239
  }
230
240
 
231
241
  // Fall back to old architecture (ReactNativeHost)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pulse-updates",
3
- "version": "1.0.20",
3
+ "version": "1.0.21",
4
4
  "description": "OTA updates for React Native - lightweight alternative to expo-updates",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",