@hot-updater/react-native 0.35.5 → 0.35.7
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/android/proguard-rules.pro +8 -1
- package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +11 -9
- package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +61 -1
- package/lib/commonjs/sdkVersion.js +1 -1
- package/lib/module/sdkVersion.js +1 -1
- package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
- package/lib/typescript/module/sdkVersion.d.ts +1 -1
- package/package.json +6 -6
- package/src/sdkVersion.ts +1 -1
|
@@ -14,4 +14,11 @@
|
|
|
14
14
|
|
|
15
15
|
-keepclassmembers class * implements com.facebook.react.runtime.ReactHostDelegate {
|
|
16
16
|
** jsBundleLoader;
|
|
17
|
-
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
# Preserve the Brotli decoder and its embedded static dictionary
|
|
20
|
+
# (DictionaryData). R8 otherwise strips the dictionary's static init, causing OTA
|
|
21
|
+
# .tar.br extraction to fail at runtime with:
|
|
22
|
+
# java.io.IOException: Brotli stream decoding failed
|
|
23
|
+
# Caused by: brotli dictionary is not set
|
|
24
|
+
-keep class com.hotupdater.vendor.brotli.** { *; }
|
|
@@ -1211,15 +1211,17 @@ class BundleFileStorageService(
|
|
|
1211
1211
|
|
|
1212
1212
|
if (hasManifestDrivenArtifacts && canUseManifestDrivenInstall()) {
|
|
1213
1213
|
try {
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1214
|
+
withContext(Dispatchers.IO) {
|
|
1215
|
+
updateBundleFromManifest(
|
|
1216
|
+
bundleId = bundleId,
|
|
1217
|
+
manifestUrl = manifestUrl!!,
|
|
1218
|
+
manifestFileHash = manifestFileHash!!,
|
|
1219
|
+
changedAssets = changedAssets!!,
|
|
1220
|
+
bundleStoreDir = bundleStoreDir,
|
|
1221
|
+
finalBundleDir = finalBundleDir,
|
|
1222
|
+
progressCallback = progressCallback,
|
|
1223
|
+
)
|
|
1224
|
+
}
|
|
1223
1225
|
return
|
|
1224
1226
|
} catch (e: Exception) {
|
|
1225
1227
|
if (fileUrl.isNullOrEmpty()) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package com.hotupdater
|
|
2
2
|
|
|
3
3
|
import android.content.ContextWrapper
|
|
4
|
+
import kotlinx.coroutines.asCoroutineDispatcher
|
|
5
|
+
import kotlinx.coroutines.runBlocking
|
|
4
6
|
import org.json.JSONObject
|
|
5
7
|
import org.junit.Assert.assertEquals
|
|
6
8
|
import org.junit.Assert.assertFalse
|
|
@@ -12,6 +14,8 @@ import org.junit.Test
|
|
|
12
14
|
import org.junit.rules.TemporaryFolder
|
|
13
15
|
import java.io.File
|
|
14
16
|
import java.net.URL
|
|
17
|
+
import java.util.concurrent.CopyOnWriteArrayList
|
|
18
|
+
import java.util.concurrent.Executors
|
|
15
19
|
import java.util.zip.ZipEntry
|
|
16
20
|
import java.util.zip.ZipOutputStream
|
|
17
21
|
|
|
@@ -269,6 +273,47 @@ class BundleFileStorageServiceTest {
|
|
|
269
273
|
assertFalse(invokeCanUseManifestDrivenInstall(service))
|
|
270
274
|
}
|
|
271
275
|
|
|
276
|
+
@Test
|
|
277
|
+
fun `manifest driven install moves blocking work off caller dispatcher`() {
|
|
278
|
+
val rootDir = temporaryFolder.newFolder("manifest-install-dispatcher")
|
|
279
|
+
val preferences = InMemoryPreferencesService()
|
|
280
|
+
val downloadService = RecordingFailedDownloadService()
|
|
281
|
+
val service = createService(rootDir, preferences, downloadService)
|
|
282
|
+
val activeDir = createBundleDir(rootDir, "active-bundle")
|
|
283
|
+
val activeBundleFile = writeFile(activeDir, "index.android.bundle")
|
|
284
|
+
writeManifest(activeDir, listOf("index.android.bundle"))
|
|
285
|
+
|
|
286
|
+
preferences.setItem("HotUpdaterBundleURL", activeBundleFile.absolutePath)
|
|
287
|
+
|
|
288
|
+
Executors
|
|
289
|
+
.newSingleThreadExecutor { runnable -> Thread(runnable, "manifest-caller") }
|
|
290
|
+
.asCoroutineDispatcher()
|
|
291
|
+
.use { callerDispatcher ->
|
|
292
|
+
runBlocking(callerDispatcher) {
|
|
293
|
+
val result =
|
|
294
|
+
runCatching {
|
|
295
|
+
service.updateBundle(
|
|
296
|
+
bundleId = "target-bundle",
|
|
297
|
+
fileUrl = "https://example.com/bundle.zip",
|
|
298
|
+
fileHash = null,
|
|
299
|
+
manifestUrl = "https://example.com/manifest.json",
|
|
300
|
+
manifestFileHash = "manifest-hash",
|
|
301
|
+
changedAssets = emptyMap(),
|
|
302
|
+
progressCallback = {},
|
|
303
|
+
)
|
|
304
|
+
}
|
|
305
|
+
assertTrue(result.exceptionOrNull() is HotUpdaterException)
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
val manifestCall = downloadService.calls.first()
|
|
310
|
+
assertEquals("https://example.com/manifest.json", manifestCall.first)
|
|
311
|
+
assertFalse(
|
|
312
|
+
"Manifest install ran on the caller dispatcher: ${manifestCall.second}",
|
|
313
|
+
manifestCall.second.contains("manifest-caller"),
|
|
314
|
+
)
|
|
315
|
+
}
|
|
316
|
+
|
|
272
317
|
@Test
|
|
273
318
|
fun `zip decompression does not write sibling prefix traversal entries`() {
|
|
274
319
|
val rootDir = temporaryFolder.newFolder("zip-sibling-prefix")
|
|
@@ -293,11 +338,12 @@ class BundleFileStorageServiceTest {
|
|
|
293
338
|
private fun createService(
|
|
294
339
|
rootDir: File,
|
|
295
340
|
preferences: InMemoryPreferencesService = InMemoryPreferencesService(),
|
|
341
|
+
downloadService: DownloadService = UnusedDownloadService,
|
|
296
342
|
): BundleFileStorageService =
|
|
297
343
|
BundleFileStorageService(
|
|
298
344
|
ContextWrapper(null),
|
|
299
345
|
TestFileSystemService(rootDir),
|
|
300
|
-
|
|
346
|
+
downloadService,
|
|
301
347
|
DecompressService(),
|
|
302
348
|
preferences,
|
|
303
349
|
TEST_ISOLATION_KEY,
|
|
@@ -447,6 +493,20 @@ class BundleFileStorageServiceTest {
|
|
|
447
493
|
): DownloadResult = error("downloadFile should not be called in these tests")
|
|
448
494
|
}
|
|
449
495
|
|
|
496
|
+
private class RecordingFailedDownloadService : DownloadService {
|
|
497
|
+
val calls = CopyOnWriteArrayList<Pair<String, String>>()
|
|
498
|
+
|
|
499
|
+
override suspend fun downloadFile(
|
|
500
|
+
fileUrl: URL,
|
|
501
|
+
destination: File,
|
|
502
|
+
fileSizeCallback: ((Long) -> Unit)?,
|
|
503
|
+
progressCallback: (DownloadProgress) -> Unit,
|
|
504
|
+
): DownloadResult {
|
|
505
|
+
calls += fileUrl.toString() to Thread.currentThread().name
|
|
506
|
+
return DownloadResult.Error(IllegalStateException("expected download failure"))
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
450
510
|
companion object {
|
|
451
511
|
private const val TEST_ISOLATION_KEY = "test-isolation-key"
|
|
452
512
|
}
|
|
@@ -4,5 +4,5 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.HOT_UPDATER_SDK_VERSION = void 0;
|
|
7
|
-
const HOT_UPDATER_SDK_VERSION = exports.HOT_UPDATER_SDK_VERSION = "0.35.
|
|
7
|
+
const HOT_UPDATER_SDK_VERSION = exports.HOT_UPDATER_SDK_VERSION = "0.35.7";
|
|
8
8
|
//# sourceMappingURL=sdkVersion.js.map
|
package/lib/module/sdkVersion.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const HOT_UPDATER_SDK_VERSION = "0.35.
|
|
1
|
+
export declare const HOT_UPDATER_SDK_VERSION = "0.35.7";
|
|
2
2
|
//# sourceMappingURL=sdkVersion.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const HOT_UPDATER_SDK_VERSION = "0.35.
|
|
1
|
+
export declare const HOT_UPDATER_SDK_VERSION = "0.35.7";
|
|
2
2
|
//# sourceMappingURL=sdkVersion.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/react-native",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.7",
|
|
4
4
|
"description": "React Native OTA solution for self-hosted",
|
|
5
5
|
"source": "./src/index.ts",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
|
@@ -130,14 +130,14 @@
|
|
|
130
130
|
"react-native": "0.79.1",
|
|
131
131
|
"react-native-builder-bob": "0.41.0",
|
|
132
132
|
"typescript": "^6.0.2",
|
|
133
|
-
"hot-updater": "0.35.
|
|
133
|
+
"hot-updater": "0.35.7"
|
|
134
134
|
},
|
|
135
135
|
"dependencies": {
|
|
136
136
|
"use-sync-external-store": "1.5.0",
|
|
137
|
-
"@hot-updater/
|
|
138
|
-
"@hot-updater/
|
|
139
|
-
"@hot-updater/
|
|
140
|
-
"@hot-updater/
|
|
137
|
+
"@hot-updater/cli-tools": "0.35.7",
|
|
138
|
+
"@hot-updater/core": "0.35.7",
|
|
139
|
+
"@hot-updater/js": "0.35.7",
|
|
140
|
+
"@hot-updater/plugin-core": "0.35.7"
|
|
141
141
|
},
|
|
142
142
|
"scripts": {
|
|
143
143
|
"build": "node ./scripts/sync-sdk-version.mjs run -- bob build && tsc -p plugin/tsconfig.build.json",
|
package/src/sdkVersion.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const HOT_UPDATER_SDK_VERSION = "0.35.
|
|
1
|
+
export const HOT_UPDATER_SDK_VERSION = "0.35.7";
|