react-native-ota-hot-update 2.4.0-rc.2 → 2.4.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/README.md
CHANGED
|
@@ -8,6 +8,7 @@ This React Native module allows you to manage hot updates (in-app update) with m
|
|
|
8
8
|
- Host the bundle on your own server or in a Git repository.
|
|
9
9
|
- Rollback function
|
|
10
10
|
- Crash Handling: Handles crash exceptions when an incorrect bundle is updated and will automatically roll back to the previous bundle version.
|
|
11
|
+
- bundle management features
|
|
11
12
|
|
|
12
13
|
1. **Demo via server**
|
|
13
14
|
|
|
@@ -21,13 +22,35 @@ iOS GIF | Android GIF
|
|
|
21
22
|
:-------------------------:|:-------------------------:
|
|
22
23
|
<img src="./iosgit.gif" title="iOS GIF" width="250"> | <img src="./androidgithotupdate.gif" title="Android GIF" width="250">
|
|
23
24
|
|
|
25
|
+
3. **Demo bundle management**
|
|
26
|
+
|
|
27
|
+
[<img src="https://raw.githubusercontent.com/vantuan88291/react-native-ota-hot-update/e4d4bd928dc096bbb4fc329ce89e80d288e44ff1/ioshotupdate-new.gif" title="iOS Bundle Management Demo" width="300">](https://raw.githubusercontent.com/vantuan88291/react-native-ota-hot-update/e4d4bd928dc096bbb4fc329ce89e80d288e44ff1/ioshotupdate-new.gif)
|
|
28
|
+
|
|
24
29
|
[](https://img.shields.io/npm/dw/react-native-ota-hot-update)
|
|
25
30
|
[](https://img.shields.io/npm/v/react-native-ota-hot-update?color=red)
|
|
26
31
|
|
|
32
|
+
|
|
27
33
|
## New architecture supported
|
|
28
34
|
|
|
29
35
|
New architecture backward compatibility supported from version 2, it also supported old architecture, for source code of version 1.x.x please refer to branch `oldArch`, you might need install version 1.x.x if you are using react native < 0.70
|
|
30
36
|
|
|
37
|
+
### 🚀 Preview Release: Enhanced Bundle Management (v2.4.0-rc.1)
|
|
38
|
+
|
|
39
|
+
We're excited to introduce a preview release with enhanced bundle management features! Version **2.4.0-rc.1** includes:
|
|
40
|
+
|
|
41
|
+
- **Configurable bundle history**: Manage multiple bundle versions (configurable via `maxBundleVersions`)
|
|
42
|
+
- **New APIs**: `getBundleList()`, `deleteBundleById()`, `clearAllBundles()`
|
|
43
|
+
- **Bundle identification**: Descriptive folder names with version and timestamp
|
|
44
|
+
- **Automatic cleanup**: Older bundles are automatically removed when exceeding the limit
|
|
45
|
+
|
|
46
|
+
This is an experimental release for testing. Please try it out and share your feedback! All discussions and issues related to this feature can be found in [PR #132](https://github.com/vantuan88291/react-native-ota-hot-update/pull/132).
|
|
47
|
+
- Branch: `task/manage_bundle`
|
|
48
|
+
|
|
49
|
+
To install the preview version:
|
|
50
|
+
```bash
|
|
51
|
+
yarn add react-native-ota-hot-update@2.4.0-rc.1
|
|
52
|
+
```
|
|
53
|
+
|
|
31
54
|
## Installation
|
|
32
55
|
|
|
33
56
|
if you don't want to manage the download progress, need to install blob util together:
|
|
@@ -50,7 +50,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
|
|
|
50
50
|
private fun loadBundleHistory(): List<BundleVersion> {
|
|
51
51
|
val sharedPrefs = SharedPrefs(reactApplicationContext)
|
|
52
52
|
val historyJson = sharedPrefs.getString(BUNDLE_HISTORY)
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
// If history exists, load it
|
|
55
55
|
if (!historyJson.isNullOrEmpty()) {
|
|
56
56
|
return try {
|
|
@@ -68,20 +68,20 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
|
|
|
68
68
|
emptyList()
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
// Migration: If history is empty but PATH exists, migrate from old system
|
|
73
73
|
val currentPath = sharedPrefs.getString(PATH)
|
|
74
74
|
val currentVersion = sharedPrefs.getString(VERSION)
|
|
75
75
|
val previousPath = sharedPrefs.getString(PREVIOUS_PATH)
|
|
76
76
|
val previousVersion = sharedPrefs.getString(PREVIOUS_VERSION)
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
if (currentPath.isNullOrEmpty()) {
|
|
79
79
|
return emptyList()
|
|
80
80
|
}
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
// Migrate current bundle
|
|
83
83
|
val migratedHistory = mutableListOf<BundleVersion>()
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
// Add current bundle if has version
|
|
86
86
|
if (!currentVersion.isNullOrEmpty()) {
|
|
87
87
|
try {
|
|
@@ -101,7 +101,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
|
|
|
101
101
|
// Version is not a number, skip
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
// Add previous bundle if exists
|
|
106
106
|
if (!previousPath.isNullOrEmpty() && !previousVersion.isNullOrEmpty()) {
|
|
107
107
|
try {
|
|
@@ -121,12 +121,12 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
|
|
|
121
121
|
// Version is not a number, skip
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
// Save migrated history if any
|
|
126
126
|
if (migratedHistory.isNotEmpty()) {
|
|
127
127
|
saveBundleHistory(migratedHistory.sortedByDescending { it.version })
|
|
128
128
|
}
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
return migratedHistory.sortedByDescending { it.version }
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -204,7 +204,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
|
|
|
204
204
|
utils.deleteOldBundleIfneeded(null)
|
|
205
205
|
val sharedPrefs = SharedPrefs(reactApplicationContext)
|
|
206
206
|
val oldPath = sharedPrefs.getString(PATH)
|
|
207
|
-
|
|
207
|
+
|
|
208
208
|
// If version is provided, save to history system
|
|
209
209
|
if (version != null) {
|
|
210
210
|
val maxVersionsToKeep = maxVersions ?: Common.DEFAULT_MAX_BUNDLE_VERSIONS
|
|
@@ -213,7 +213,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
|
|
|
213
213
|
// No version (e.g., Git update) - just set path, no history
|
|
214
214
|
sharedPrefs.putString(PATH, fileUnzip)
|
|
215
215
|
}
|
|
216
|
-
|
|
216
|
+
|
|
217
217
|
sharedPrefs.putString(
|
|
218
218
|
CURRENT_VERSION_CODE,
|
|
219
219
|
reactApplicationContext.getVersionCode()
|
|
@@ -254,21 +254,21 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
|
|
|
254
254
|
try {
|
|
255
255
|
val sharedPrefs = SharedPrefs(reactApplicationContext)
|
|
256
256
|
val currentPath = sharedPrefs.getString(PATH)
|
|
257
|
-
|
|
257
|
+
|
|
258
258
|
// Delete current bundle from file system
|
|
259
259
|
val isDeleted = utils.deleteOldBundleIfneeded(PATH)
|
|
260
|
-
|
|
260
|
+
|
|
261
261
|
// Remove current bundle from history if exists
|
|
262
262
|
if (currentPath != null && currentPath.isNotEmpty()) {
|
|
263
263
|
val history = loadBundleHistory()
|
|
264
264
|
val updatedHistory = history.filter { it.path != currentPath }
|
|
265
265
|
saveBundleHistory(updatedHistory)
|
|
266
266
|
}
|
|
267
|
-
|
|
267
|
+
|
|
268
268
|
// Clear paths and version (no longer clear PREVIOUS_PATH, use history instead)
|
|
269
269
|
sharedPrefs.putString(PATH, "")
|
|
270
270
|
sharedPrefs.putString(VERSION, "0")
|
|
271
|
-
|
|
271
|
+
|
|
272
272
|
withContext(Dispatchers.Main) {
|
|
273
273
|
promise.resolve(isDeleted)
|
|
274
274
|
}
|
|
@@ -282,7 +282,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
|
|
|
282
282
|
|
|
283
283
|
@ReactMethod
|
|
284
284
|
override fun restart() {
|
|
285
|
-
val context: Context? = currentActivity
|
|
285
|
+
val context: Context? = reactApplicationContext.currentActivity
|
|
286
286
|
ProcessPhoenix.triggerRebirth(context)
|
|
287
287
|
}
|
|
288
288
|
|
|
@@ -364,7 +364,7 @@ class OtaHotUpdateModule internal constructor(context: ReactApplicationContext)
|
|
|
364
364
|
if (isDeleted) {
|
|
365
365
|
sharedPrefs.putString(PATH, previousBundle.path)
|
|
366
366
|
sharedPrefs.putString(VERSION, previousBundle.version.toString())
|
|
367
|
-
|
|
367
|
+
|
|
368
368
|
withContext(Dispatchers.Main) {
|
|
369
369
|
promise.resolve(true)
|
|
370
370
|
}
|