@hot-updater/react-native 0.1.3 → 0.1.5

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 (42) hide show
  1. package/HotUpdater.podspec +1 -2
  2. package/android/build.gradle +16 -3
  3. package/android/generated/java/com/hotupdater/NativeHotUpdaterSpec.java +54 -0
  4. package/android/generated/jni/CMakeLists.txt +36 -0
  5. package/android/generated/jni/HotUpdaterSpec-generated.cpp +56 -0
  6. package/android/generated/jni/HotUpdaterSpec.h +31 -0
  7. package/android/generated/jni/react/renderer/components/HotUpdaterSpec/HotUpdaterSpecJSI-generated.cpp +57 -0
  8. package/android/generated/jni/react/renderer/components/HotUpdaterSpec/HotUpdaterSpecJSI.h +103 -0
  9. package/android/react-native-helpers.gradle +42 -0
  10. package/android/src/main/java/com/hotupdater/HotUpdater.kt +151 -240
  11. package/android/src/main/java/com/hotupdater/HotUpdaterModule.kt +52 -40
  12. package/android/src/main/java/com/hotupdater/HotUpdaterPackage.kt +25 -24
  13. package/android/src/main/java/com/hotupdater/ReactIntegrationManagerBase.kt +34 -0
  14. package/android/src/newarch/HotUpdaterSpec.kt +3 -2
  15. package/android/src/newarch/ReactIntegrationManager.kt +46 -0
  16. package/android/src/oldarch/HotUpdaterSpec.kt +12 -8
  17. package/android/src/oldarch/ReactIntegrationManager.kt +41 -0
  18. package/dist/index.d.mts +71 -0
  19. package/dist/index.d.ts +43 -52
  20. package/dist/index.js +2366 -139
  21. package/dist/index.mjs +2411 -0
  22. package/ios/HotUpdater/HotUpdater.h +8 -4
  23. package/ios/HotUpdater/HotUpdater.mm +167 -116
  24. package/ios/generated/HotUpdaterSpec/HotUpdaterSpec-generated.mm +67 -0
  25. package/ios/generated/HotUpdaterSpec/HotUpdaterSpec.h +67 -0
  26. package/ios/generated/HotUpdaterSpecJSI-generated.cpp +57 -0
  27. package/ios/generated/HotUpdaterSpecJSI.h +103 -0
  28. package/package.json +26 -10
  29. package/react-native.config.js +12 -0
  30. package/src/const.ts +1 -0
  31. package/src/ensureBundles.ts +21 -0
  32. package/src/global.d.ts +3 -0
  33. package/src/index.ts +27 -5
  34. package/src/init.tsx +25 -7
  35. package/src/native.ts +50 -42
  36. package/src/specs/{NativeHotUpdaterModule.ts → NativeHotUpdater.ts} +6 -7
  37. package/src/store.ts +48 -0
  38. package/dist/index.cjs +0 -220
  39. package/dist/index.d.cts +0 -80
  40. package/src/checkForUpdate.test.ts +0 -517
  41. package/src/checkForUpdate.ts +0 -111
  42. package/src/utils.ts +0 -2
@@ -5,286 +5,197 @@ import android.content.Context
5
5
  import android.os.Handler
6
6
  import android.os.Looper
7
7
  import android.util.Log
8
- import com.facebook.react.ReactInstanceManager
9
- import com.facebook.react.ReactNativeHost
10
- import com.facebook.react.bridge.JSBundleLoader
11
- import com.facebook.react.bridge.LifecycleEventListener
8
+ import android.view.View
9
+ import com.facebook.react.ReactApplication
10
+ import com.facebook.react.ReactPackage
11
+ import com.facebook.react.bridge.NativeModule
12
+ import com.facebook.react.bridge.ReactApplicationContext
13
+ import com.facebook.react.uimanager.ReactShadowNode
14
+ import com.facebook.react.uimanager.ViewManager
12
15
  import java.io.File
13
- import java.lang.reflect.Field
16
+ import java.net.HttpURLConnection
14
17
  import java.net.URL
15
18
  import java.util.zip.ZipFile
16
19
 
17
- class HotUpdater internal constructor(context: Context, reactNativeHost: ReactNativeHost) {
18
- private val mContext: Context = context
19
- private val mReactNativeHost: ReactNativeHost = reactNativeHost
20
+ class HotUpdater : ReactPackage {
21
+ override fun createViewManagers(context: ReactApplicationContext): MutableList<ViewManager<View, ReactShadowNode<*>>> = mutableListOf()
20
22
 
21
- companion object {
22
- private var mCurrentInstance: HotUpdater? = null
23
-
24
- fun init(context: Context, reactNativeHost: ReactNativeHost): HotUpdater {
25
- Log.d("HotUpdater", "Initializing HotUpdater")
26
-
27
- return mCurrentInstance
28
- ?: synchronized(this) {
29
- mCurrentInstance
30
- ?: HotUpdater(context, reactNativeHost).also {
31
- mCurrentInstance = it
32
- }
33
- }
34
- }
35
-
36
- fun getAppVersion(): String? {
37
- return mCurrentInstance?.getAppVersion()
38
- }
39
-
40
- fun initializeOnAppUpdate() {
41
- mCurrentInstance?.initializeOnAppUpdate()
42
- }
43
-
44
- fun reload() {
45
- mCurrentInstance?.reload()
46
- }
47
-
48
- fun getJSBundleFile(): String? {
49
- Log.d("HotUpdater", "Getting JS bundle file ${mCurrentInstance?.getBundleURL()}")
50
- return mCurrentInstance?.getBundleURL()
51
- }
52
-
53
- fun getBundleVersion(): Double? {
54
- return mCurrentInstance?.getBundleVersion()
55
- }
56
-
57
- fun updateBundle(prefix: String, url: String?): Boolean? {
58
- return mCurrentInstance?.updateBundle(prefix, url)
59
- }
60
- }
61
-
62
- private val documentsDir: String
63
- get() = mContext.getExternalFilesDir(null)?.absolutePath ?: mContext.filesDir.absolutePath
64
-
65
- private fun convertFileSystemPathFromBasePath(basePath: String): String {
66
- val separator = if (basePath.startsWith("/")) "" else "/"
67
- return "$documentsDir$separator$basePath"
68
- }
23
+ override fun createNativeModules(context: ReactApplicationContext): MutableList<NativeModule> =
24
+ listOf(HotUpdaterModule(context)).toMutableList()
69
25
 
70
- private fun stripPrefixFromPath(prefix: String, path: String): String {
71
- return if (path.startsWith("/$prefix/")) {
72
- path.replaceFirst("/$prefix/", "")
73
- } else {
74
- path
75
- }
76
- }
26
+ companion object {
27
+ private fun convertFileSystemPathFromBasePath(
28
+ context: Context,
29
+ basePath: String,
30
+ ): String {
31
+ val documentsDir = context.getExternalFilesDir(null)?.absolutePath ?: context.filesDir.absolutePath
32
+ val separator = if (basePath.startsWith("/")) "" else "/"
33
+
34
+ return "$documentsDir$separator$basePath"
35
+ }
36
+
37
+ private fun stripPrefixFromPath(
38
+ prefix: String,
39
+ path: String,
40
+ ): String =
41
+ if (path.startsWith("/$prefix/")) {
42
+ path.replaceFirst("/$prefix/", "")
43
+ } else {
44
+ path
45
+ }
77
46
 
78
- private fun loadBundleLegacy() {
79
- val currentActivity: Activity? =
80
- mReactNativeHost.reactInstanceManager.currentReactContext?.currentActivity
81
- if (currentActivity == null) {
82
- return
47
+ fun getAppVersion(context: Context): String? {
48
+ val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
49
+ return packageInfo.versionName
83
50
  }
84
51
 
85
- currentActivity.runOnUiThread { currentActivity.recreate() }
86
- }
87
- private var mLifecycleEventListener: LifecycleEventListener? = null
88
-
89
- private fun clearLifecycleEventListener() {
90
- if (mLifecycleEventListener != null) {
91
- mReactNativeHost.reactInstanceManager.currentReactContext?.removeLifecycleEventListener(
92
- mLifecycleEventListener
93
- )
94
- mLifecycleEventListener = null
52
+ private fun setBundleURL(
53
+ context: Context,
54
+ bundleURL: String?,
55
+ ) {
56
+ val sharedPreferences =
57
+ context.getSharedPreferences("HotUpdaterPrefs", Context.MODE_PRIVATE)
58
+ with(sharedPreferences.edit()) {
59
+ putString("HotUpdaterBundleURL", bundleURL)
60
+ apply()
61
+ }
95
62
  }
96
- }
97
-
98
- private fun setJSBundle(instanceManager: ReactInstanceManager, latestJSBundleFile: String?) {
99
-
100
- try {
101
- var latestJSBundleLoader: JSBundleLoader? = null
102
63
 
103
- if (latestJSBundleFile != null && latestJSBundleFile.lowercase().startsWith("assets://")
104
- ) {
105
- latestJSBundleLoader =
106
- JSBundleLoader.createAssetLoader(
107
- instanceManager.currentReactContext,
108
- latestJSBundleFile,
109
- false
110
- )
111
- } else if (latestJSBundleFile != null) {
112
- latestJSBundleLoader = JSBundleLoader.createFileLoader(latestJSBundleFile)
64
+ private fun extractZipFileAtPath(
65
+ filePath: String,
66
+ destinationPath: String,
67
+ ): Boolean =
68
+ try {
69
+ ZipFile(filePath).use { zip ->
70
+ zip.entries().asSequence().forEach { entry ->
71
+ val file = File(destinationPath, entry.name)
72
+ if (entry.isDirectory) {
73
+ file.mkdirs()
74
+ } else {
75
+ file.parentFile?.mkdirs()
76
+ zip.getInputStream(entry).use { input ->
77
+ file.outputStream().use { output -> input.copyTo(output) }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ true
83
+ } catch (e: Exception) {
84
+ Log.d("HotUpdater", "Failed to unzip file: ${e.message}")
85
+ false
113
86
  }
114
- val bundleLoaderField: Field =
115
- instanceManager::class.java.getDeclaredField("mBundleLoader")
116
- bundleLoaderField.isAccessible = true
117
87
 
118
- if (latestJSBundleLoader != null) {
119
- bundleLoaderField.set(instanceManager, latestJSBundleLoader)
88
+ private fun getCurrentActivity(context: Context): Activity? =
89
+ if (context is ReactApplicationContext) {
90
+ context.currentActivity
120
91
  } else {
121
- bundleLoaderField.set(instanceManager, null)
92
+ null
122
93
  }
123
- } catch (e: Exception) {
124
- throw IllegalAccessException("Could not setJSBundle")
125
- }
126
- }
127
-
128
- fun initializeOnAppUpdate() {
129
- val sharedPreferences =
130
- mContext.getSharedPreferences("HotUpdaterPrefs", Context.MODE_PRIVATE)
131
94
 
132
- val currentVersion = getAppVersion()
133
- val savedVersion = sharedPreferences.getString("HotUpdaterAppVersion", null)
95
+ fun reload(context: Context) {
96
+ val activity: Activity? = getCurrentActivity(context)
97
+ val reactIntegrationManager = ReactIntegrationManager(context)
134
98
 
135
- if (currentVersion != savedVersion) {
136
- val editor = sharedPreferences.edit()
137
- editor.remove("HotUpdaterBundleURL")
138
- editor.remove("HotUpdaterBundleVersion")
139
- editor.putString("HotUpdaterAppVersion", currentVersion)
140
- editor.apply()
141
- }
142
- }
99
+ val reactApplication: ReactApplication = reactIntegrationManager.getReactApplication(activity?.application)
100
+ val bundleURL = getJSBundleFile(context)
143
101
 
144
- fun reload() {
145
- Log.d("HotUpdater", "HotUpdater requested a reload ${getBundleURL()}")
102
+ reactIntegrationManager.setJSBundle(reactApplication, bundleURL)
146
103
 
147
- setJSBundle(mReactNativeHost.reactInstanceManager, getBundleURL())
148
-
149
- clearLifecycleEventListener()
150
- try {
151
104
  Handler(Looper.getMainLooper()).post {
152
- try {
153
- mReactNativeHost.reactInstanceManager.recreateReactContextInBackground()
154
- } catch (t: Throwable) {
155
- loadBundleLegacy()
156
- }
105
+ reactIntegrationManager.reload(reactApplication)
157
106
  }
158
- } catch (t: Throwable) {
159
- loadBundleLegacy()
160
107
  }
161
- }
162
108
 
163
- fun getAppVersion(): String {
164
- val packageInfo = mContext.packageManager.getPackageInfo(mContext.packageName, 0)
165
- return packageInfo.versionName
166
- }
167
-
168
- fun getBundleURL(): String {
169
- val sharedPreferences =
170
- mContext.getSharedPreferences("HotUpdaterPrefs", Context.MODE_PRIVATE)
171
- val urlString = sharedPreferences.getString("HotUpdaterBundleURL", null)
172
- if (urlString.isNullOrEmpty()) {
173
- return "assets://index.android.bundle"
174
- }
109
+ public fun getJSBundleFile(context: Context): String {
110
+ val sharedPreferences =
111
+ context.getSharedPreferences("HotUpdaterPrefs", Context.MODE_PRIVATE)
112
+ val urlString = sharedPreferences.getString("HotUpdaterBundleURL", null)
113
+ if (urlString.isNullOrEmpty()) {
114
+ return "assets://index.android.bundle"
115
+ }
175
116
 
176
- return urlString
177
- }
117
+ val file = File(urlString)
118
+ if (!file.exists()) {
119
+ setBundleURL(context, null)
120
+ return "assets://index.android.bundle"
121
+ }
178
122
 
179
- private fun setBundleURL(bundleURL: String?) {
180
- val sharedPreferences =
181
- mContext.getSharedPreferences("HotUpdaterPrefs", Context.MODE_PRIVATE)
182
- with(sharedPreferences.edit()) {
183
- putString("HotUpdaterBundleURL", bundleURL)
184
- apply()
185
- }
186
- }
187
- private fun setBundleVersion(bundleVersion: String?) {
188
- val sharedPreferences =
189
- mContext.getSharedPreferences("HotUpdaterPrefs", Context.MODE_PRIVATE)
190
- with(sharedPreferences.edit()) {
191
- putString("HotUpdaterBundleVersion", bundleVersion)
192
- apply()
123
+ return urlString
193
124
  }
194
- }
195
125
 
196
- fun getBundleVersion(): Double? {
197
- val sharedPreferences =
198
- mContext.getSharedPreferences("HotUpdaterPrefs", Context.MODE_PRIVATE)
199
- val bundleVersion = sharedPreferences.getString("HotUpdaterBundleVersion", null)
200
- Log.d("HotUpdater", "Bundle version: $bundleVersion")
201
- return if (bundleVersion != null && bundleVersion.isNotEmpty()) {
202
- try {
203
- bundleVersion.toDouble()
204
- } catch (e: Exception) {
205
- -1.0
126
+ fun updateBundle(
127
+ context: Context,
128
+ bundleId: String,
129
+ zipUrl: String,
130
+ progressCallback: ((Double) -> Unit),
131
+ ): Boolean {
132
+ Log.d("HotUpdater", "updateBundle bundleId $bundleId zipUrl $zipUrl")
133
+ if (zipUrl.isEmpty()) {
134
+ setBundleURL(context, null)
135
+ return true
206
136
  }
207
- } else {
208
- -1.0
209
- }
210
- }
211
137
 
212
- private fun extractZipFileAtPath(filePath: String, destinationPath: String): Boolean {
213
- return try {
214
- ZipFile(filePath).use { zip ->
215
- zip.entries().asSequence().forEach { entry ->
216
- val file = File(destinationPath, entry.name)
217
- if (entry.isDirectory) {
218
- file.mkdirs()
219
- } else {
220
- file.parentFile?.mkdirs()
221
- zip.getInputStream(entry).use { input ->
222
- file.outputStream().use { output -> input.copyTo(output) }
223
- }
224
- }
225
- }
226
- }
227
- true
228
- } catch (e: Exception) {
229
- Log.d("HotUpdater", "Failed to unzip file: ${e.message}")
230
- false
231
- }
232
- }
138
+ val downloadUrl = URL(zipUrl)
233
139
 
234
- fun updateBundle(prefix: String, url: String?): Boolean {
235
- if (url == null) {
236
- setBundleURL(null)
237
- setBundleVersion(null)
238
- return true
239
- }
140
+ val basePath = stripPrefixFromPath(bundleId, downloadUrl.path)
141
+ val path = convertFileSystemPathFromBasePath(context, basePath)
240
142
 
241
- val downloadUrl = URL(url)
242
-
243
- val basePath = stripPrefixFromPath(prefix, downloadUrl.path)
244
- val path = convertFileSystemPathFromBasePath(basePath)
143
+ var connection: HttpURLConnection? = null
144
+ try {
145
+ connection = downloadUrl.openConnection() as HttpURLConnection
146
+ connection.connect()
245
147
 
246
- val data =
247
- try {
248
- downloadUrl.readBytes()
249
- } catch (e: Exception) {
250
- Log.d("HotUpdater", "Failed to download data from URL: $url")
148
+ val totalSize = connection.contentLength
149
+ if (totalSize <= 0) {
150
+ Log.d("HotUpdater", "Invalid content length: $totalSize")
251
151
  return false
252
152
  }
253
153
 
254
- val file = File(path)
255
- try {
256
- file.parentFile?.mkdirs()
257
- file.writeBytes(data)
258
- } catch (e: Exception) {
259
- Log.d("HotUpdater", "Failed to save data: ${e.message}")
260
- return false
261
- }
154
+ val file = File(path)
155
+ file.parentFile?.mkdirs()
262
156
 
263
- val extractedPath = file.parentFile?.path
264
- if (extractedPath == null) {
265
- return false
266
- }
157
+ connection.inputStream.use { input ->
158
+ file.outputStream().use { output ->
159
+ val buffer = ByteArray(8 * 1024)
160
+ var bytesRead: Int
161
+ var totalRead = 0L
267
162
 
268
- if (!extractZipFileAtPath(path, extractedPath)) {
269
- Log.d("HotUpdater", "Failed to extract zip file.")
270
- return false
271
- }
163
+ while (input.read(buffer).also { bytesRead = it } != -1) {
164
+ output.write(buffer, 0, bytesRead)
165
+ totalRead += bytesRead
166
+ val progress = (totalRead.toDouble() / totalSize)
167
+ progressCallback.invoke(progress)
168
+ }
169
+ }
170
+ }
171
+ } catch (e: Exception) {
172
+ Log.d("HotUpdater", "Failed to download data from URL: $zipUrl, Error: ${e.message}")
173
+ return false
174
+ } finally {
175
+ connection?.disconnect()
176
+ }
272
177
 
273
- val extractedDirectory = File(extractedPath)
274
- val indexFile = extractedDirectory.walk().find { it.name == "index.android.bundle.js" }
178
+ val extractedPath = File(path).parentFile?.path ?: return false
275
179
 
276
- if (indexFile != null) {
277
- val bundlePath = indexFile.path
278
- Log.d("HotUpdater", "Setting bundle URL: $bundlePath")
279
- setBundleURL(bundlePath)
280
- } else {
281
- Log.d("HotUpdater", "index.android.bundle.js not found.")
282
- return false
283
- }
180
+ if (!extractZipFileAtPath(path, extractedPath)) {
181
+ Log.d("HotUpdater", "Failed to extract zip file.")
182
+ return false
183
+ }
284
184
 
285
- setBundleVersion(prefix)
286
- Log.d("HotUpdater", "Downloaded and extracted file successfully.")
185
+ val extractedDirectory = File(extractedPath)
186
+ val indexFile = extractedDirectory.walk().find { it.name == "index.android.bundle" }
287
187
 
288
- return true
188
+ if (indexFile != null) {
189
+ val bundlePath = indexFile.path
190
+ Log.d("HotUpdater", "Setting bundle URL: $bundlePath")
191
+ setBundleURL(context, bundlePath)
192
+ } else {
193
+ Log.d("HotUpdater", "index.android.bundle not found.")
194
+ return false
195
+ }
196
+
197
+ Log.d("HotUpdater", "Downloaded and extracted file successfully.")
198
+ return true
199
+ }
289
200
  }
290
201
  }
@@ -1,45 +1,57 @@
1
1
  package com.hotupdater
2
2
 
3
- import com.facebook.react.bridge.Callback
3
+ import com.facebook.react.bridge.Promise
4
4
  import com.facebook.react.bridge.ReactApplicationContext
5
5
  import com.facebook.react.bridge.ReactMethod
6
-
7
- class HotUpdaterModule internal constructor(context: ReactApplicationContext) :
8
- HotUpdaterSpec(context) {
9
-
10
- private val mReactApplicationContext: ReactApplicationContext = context
11
-
12
- override fun getName(): String {
13
- return NAME
14
- }
15
-
16
- @ReactMethod
17
- override fun initializeOnAppUpdate() {
18
- HotUpdater.initializeOnAppUpdate()
19
- }
20
-
21
- @ReactMethod
22
- override fun reload() {
23
- HotUpdater.reload()
24
- }
25
-
26
- @ReactMethod
27
- override fun getAppVersion(callback: Callback) {
28
- callback.invoke(HotUpdater.getAppVersion())
29
- }
30
-
31
- @ReactMethod
32
- override fun getBundleVersion(callback: Callback) {
33
- callback.invoke(HotUpdater.getBundleVersion())
34
- }
35
-
36
- @ReactMethod
37
- override fun updateBundle(prefix: String, url: String?, callback: Callback) {
38
- val result = HotUpdater.updateBundle(prefix, url)
39
- callback.invoke(result)
40
- }
41
-
42
- companion object {
43
- const val NAME = "HotUpdater"
44
- }
6
+ import com.facebook.react.bridge.WritableNativeMap
7
+ import com.facebook.react.modules.core.DeviceEventManagerModule
8
+
9
+ class HotUpdaterModule internal constructor(
10
+ context: ReactApplicationContext,
11
+ ) : HotUpdaterSpec(context) {
12
+ private val mReactApplicationContext: ReactApplicationContext = context
13
+
14
+ override fun getName(): String = NAME
15
+
16
+ @ReactMethod
17
+ override fun reload() {
18
+ HotUpdater.reload(mReactApplicationContext)
19
+ }
20
+
21
+ @ReactMethod
22
+ override fun getAppVersion(promise: Promise) {
23
+ promise.resolve(HotUpdater.getAppVersion(mReactApplicationContext))
24
+ }
25
+
26
+ @ReactMethod
27
+ override fun updateBundle(
28
+ bundleId: String,
29
+ zipUrl: String,
30
+ promise: Promise,
31
+ ) {
32
+ val isSuccess =
33
+ HotUpdater.updateBundle(mReactApplicationContext, bundleId, zipUrl) { progress ->
34
+ val params =
35
+ WritableNativeMap().apply {
36
+ putDouble("progress", progress)
37
+ }
38
+
39
+ this.mReactApplicationContext
40
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
41
+ .emit("onProgress", params)
42
+ }
43
+ promise.resolve(isSuccess)
44
+ }
45
+
46
+ override fun addListener(eventName: String?) {
47
+ // No-op
48
+ }
49
+
50
+ override fun removeListeners(count: Double) {
51
+ // No-op
52
+ }
53
+
54
+ companion object {
55
+ const val NAME = "HotUpdater"
56
+ }
45
57
  }
@@ -8,29 +8,30 @@ import com.facebook.react.module.model.ReactModuleInfoProvider
8
8
  import java.util.HashMap
9
9
 
10
10
  class HotUpdaterPackage : TurboReactPackage() {
11
- override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
12
- return if (name == HotUpdaterModule.NAME) {
13
- HotUpdaterModule(reactContext)
14
- } else {
15
- null
16
- }
17
- }
11
+ override fun getModule(
12
+ name: String,
13
+ reactContext: ReactApplicationContext,
14
+ ): NativeModule? =
15
+ if (name == HotUpdaterModule.NAME) {
16
+ HotUpdaterModule(reactContext)
17
+ } else {
18
+ null
19
+ }
18
20
 
19
- override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
20
- return ReactModuleInfoProvider {
21
- val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
22
- val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
23
- moduleInfos[HotUpdaterModule.NAME] =
24
- ReactModuleInfo(
25
- HotUpdaterModule.NAME,
26
- HotUpdaterModule.NAME,
27
- false, // canOverrideExistingModule
28
- false, // needsEagerInit
29
- true, // hasConstants
30
- false, // isCxxModule
31
- isTurboModule // isTurboModule
32
- )
33
- moduleInfos
34
- }
35
- }
21
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider =
22
+ ReactModuleInfoProvider {
23
+ val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
24
+ val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
25
+ moduleInfos[HotUpdaterModule.NAME] =
26
+ ReactModuleInfo(
27
+ HotUpdaterModule.NAME,
28
+ HotUpdaterModule.NAME,
29
+ false, // canOverrideExistingModule
30
+ false, // needsEagerInit
31
+ true, // hasConstants
32
+ false, // isCxxModule
33
+ isTurboModule, // isTurboModule
34
+ )
35
+ moduleInfos
36
+ }
36
37
  }
@@ -0,0 +1,34 @@
1
+ package com.hotupdater
2
+
3
+ import android.app.Application
4
+ import android.content.Context
5
+ import com.facebook.react.ReactApplication
6
+ import com.facebook.react.bridge.JSBundleLoader
7
+
8
+ open class ReactIntegrationManagerBase(
9
+ private val context: Context,
10
+ ) {
11
+ fun getJSBundlerLoader(bundleFileUrl: String): JSBundleLoader? {
12
+ val bundleLoader: JSBundleLoader?
13
+
14
+ if (bundleFileUrl.lowercase().startsWith("assets://")) {
15
+ bundleLoader =
16
+ JSBundleLoader.createAssetLoader(
17
+ context,
18
+ bundleFileUrl,
19
+ true,
20
+ )
21
+ } else {
22
+ bundleLoader = JSBundleLoader.createFileLoader(bundleFileUrl)
23
+ }
24
+ return bundleLoader
25
+ }
26
+
27
+ public fun getReactApplication(application: Application?): ReactApplication {
28
+ if (application is ReactApplication) {
29
+ return application
30
+ } else {
31
+ throw IllegalArgumentException("Application does not implement ReactApplication")
32
+ }
33
+ }
34
+ }
@@ -2,5 +2,6 @@ package com.hotupdater
2
2
 
3
3
  import com.facebook.react.bridge.ReactApplicationContext
4
4
 
5
- abstract class HotUpdaterSpec internal constructor(context: ReactApplicationContext) :
6
- NativeHotUpdaterSpec(context) {}
5
+ abstract class HotUpdaterSpec internal constructor(
6
+ context: ReactApplicationContext,
7
+ ) : NativeHotUpdaterSpec(context)