expo-updates 29.1.0-canary-20251013-623c5a6 → 29.1.0-canary-20251023-4c86f95
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/DEVELOPMENT.md +10 -0
- package/android/CMakeLists.txt +53 -0
- package/android/build.gradle +24 -2
- package/android/src/main/cpp/BSPatch.h +23 -0
- package/android/src/main/cpp/BSPatchModule.cpp +36 -0
- package/android/src/main/cpp/ExpoUpdatesMain.cpp +11 -0
- package/android/src/main/cpp/third-party/bzip2/LICENSE +42 -0
- package/android/src/main/cpp/third-party/bzip2/blocksort.c +1094 -0
- package/android/src/main/cpp/third-party/bzip2/bzlib.c +1572 -0
- package/android/src/main/cpp/third-party/bzip2/bzlib.h +282 -0
- package/android/src/main/cpp/third-party/bzip2/bzlib_private.h +509 -0
- package/android/src/main/cpp/third-party/bzip2/compress.c +672 -0
- package/android/src/main/cpp/third-party/bzip2/crctable.c +104 -0
- package/android/src/main/cpp/third-party/bzip2/decompress.c +652 -0
- package/android/src/main/cpp/third-party/bzip2/huffman.c +205 -0
- package/android/src/main/cpp/third-party/bzip2/randtable.c +84 -0
- package/android/src/main/java/expo/modules/updates/BSPatch.kt +14 -0
- package/android/src/main/java/expo/modules/updates/EnabledUpdatesController.kt +7 -1
- package/android/src/main/java/expo/modules/updates/UpdatesConfiguration.kt +5 -0
- package/android/src/main/java/expo/modules/updates/UpdatesDevLauncherController.kt +7 -1
- package/android/src/main/java/expo/modules/updates/UpdatesUtils.kt +16 -4
- package/android/src/main/java/expo/modules/updates/launcher/DatabaseLauncher.kt +5 -3
- package/android/src/main/java/expo/modules/updates/loader/EmbeddedLoader.kt +1 -1
- package/android/src/main/java/expo/modules/updates/loader/FileDownloader.kt +360 -66
- package/android/src/main/java/expo/modules/updates/loader/Loader.kt +1 -1
- package/android/src/main/java/expo/modules/updates/loader/RemoteLoader.kt +3 -3
- package/ios/EXUpdates/AppLauncher/AppLauncherWithDatabase.swift +10 -2
- package/ios/EXUpdates/AppLoader/AppLoader.swift +13 -2
- package/ios/EXUpdates/AppLoader/FileDownloader.swift +348 -6
- package/ios/EXUpdates/AppLoader/RemoteAppLoader.swift +18 -2
- package/ios/EXUpdates/BSPatch.swift +30 -0
- package/ios/EXUpdates/EXUpdatesBSPatch.h +9 -0
- package/ios/EXUpdates/EXUpdatesBSPatch.m +18 -0
- package/ios/EXUpdates/EnabledAppController.swift +2 -1
- package/ios/EXUpdates/Procedures/CheckForUpdateProcedure.swift +7 -2
- package/ios/EXUpdates/UpdatesConfig.swift +6 -0
- package/ios/EXUpdates.podspec +14 -2
- package/ios/Tests/FileDownloaderManifestParsingSpec.swift +27 -16
- package/ios/Tests/FileDownloaderSpec.swift +320 -13
- package/ios/Tests/HermesDiffSpec.swift +68 -0
- package/ios/Tests/Support/fixtures/new.hbc +0 -0
- package/ios/Tests/Support/fixtures/old.hbc +0 -0
- package/ios/Tests/Support/fixtures/test.patch +0 -0
- package/ios/Tests/UpdatesConfigSpec.swift +3 -0
- package/package.json +8 -8
- package/vendor/bspatch/LICENSE +25 -0
- package/vendor/bspatch/bspatch.c +420 -0
package/DEVELOPMENT.md
CHANGED
|
@@ -9,6 +9,7 @@ While it's possible to develop expo-updates in the context of Expo Go, it's usua
|
|
|
9
9
|
There are a few ways to hook up your local copy of expo-updates to your test app. If you're not importing anything from expo-updates in your JS, you may be able to use `yarn link`, which is the most straightforward solution.
|
|
10
10
|
|
|
11
11
|
Unfortunately, Metro doesn't support symlinks (at the time of this writing) so if you do need to use the Updates JS module methods in your app, `yarn link` will not suffice. A couple of suggestions are:
|
|
12
|
+
|
|
12
13
|
- in package.json, replace the expo-updates dependency with: `"expo-updates": "file:/path/to/expo/expo/packages/expo-updates"`. You'll need to run `yarn --force` each time you make changes to your expo-updates source to make yarn copy them into node_modules.
|
|
13
14
|
- if you don't want to wait for yarn to run each time, you can just manually copy expo-updates into node_modules each time you make a change.
|
|
14
15
|
|
|
@@ -63,9 +64,18 @@ sed -i '' 's/SKIP_BUNDLING/FORCE_BUNDLING/g;' ios/<project name>.xcodeproj/proje
|
|
|
63
64
|
|
|
64
65
|
Now you can make a debug build of your app which behaves as if it were a release build (but without an embedded update).
|
|
65
66
|
|
|
67
|
+
# BSPatch and BZip2
|
|
68
|
+
|
|
69
|
+
expo-updates includes support for applying binary patches to assets.
|
|
70
|
+
We use a modified version of the FreeBSD version of [BSPatch](https://github.com/freebsd/freebsd-src/blob/main/usr.bin/bsdiff/bspatch/bspatch.c)
|
|
71
|
+
https://github.com/freebsd/freebsd-src/blob/b202176dc76d862f886778439b96dd1243d8b999/usr.bin/bsdiff/bspatch/bspatch.c. We make these modifications to make it safe to use in the mobile environment without crashing the user app.
|
|
72
|
+
|
|
73
|
+
BSPatch relies on [BZip2](https://www.sourceware.org/bzip2/downloads.html). On iOS, we link against the system BZip2 library. On Android, we include a copy of the BZip2 source code in our repo and build it as part of the native code build. We only include the parts of BZip2 that handle decompression. When updating, download the bzip2 source code and replace the necessary files in `packages/expo-updates/android/src/main/cpp/third-party/bzip2`.
|
|
74
|
+
|
|
66
75
|
## Troubleshooting
|
|
67
76
|
|
|
68
77
|
If expo-updates is not loading an update you expect it to, check that:
|
|
78
|
+
|
|
69
79
|
- the creation time of the update you're trying to load is newer than the embedded bundle, or you've configured expo-updates to [ignore the embedded bundle](#ignore-embedded-update).
|
|
70
80
|
- the SDK or runtime version configured in Expo.plist or AndroidManifest.xml matches the one in the manifest you're trying to load.
|
|
71
81
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.4.1)
|
|
2
|
+
|
|
3
|
+
project(expo-updates)
|
|
4
|
+
|
|
5
|
+
set(CMAKE_VERBOSE_MAKEFILE ON)
|
|
6
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
7
|
+
set(PACKAGE_NAME "expo-updates")
|
|
8
|
+
set(BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
|
|
9
|
+
|
|
10
|
+
set(SRC_DIR "${CMAKE_SOURCE_DIR}/src/main/cpp")
|
|
11
|
+
set(BSDIFF_SRC_DIR "${CMAKE_SOURCE_DIR}/../vendor/bspatch")
|
|
12
|
+
set(BZIP2_SRC_DIR "${SRC_DIR}/third-party/bzip2")
|
|
13
|
+
|
|
14
|
+
file(GLOB SOURCES "${SRC_DIR}/*.cpp")
|
|
15
|
+
file(GLOB BSDIFF_SOURCES "${BSDIFF_SRC_DIR}/*.c")
|
|
16
|
+
file(GLOB BZIP2_SOURCES "${BZIP2_SRC_DIR}/*.c")
|
|
17
|
+
|
|
18
|
+
add_library(
|
|
19
|
+
${PACKAGE_NAME}
|
|
20
|
+
SHARED
|
|
21
|
+
${SOURCES}
|
|
22
|
+
${BSDIFF_SOURCES}
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
add_library(
|
|
26
|
+
bzip2
|
|
27
|
+
STATIC
|
|
28
|
+
${BZIP2_SOURCES}
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
target_include_directories(
|
|
32
|
+
bzip2
|
|
33
|
+
PUBLIC
|
|
34
|
+
"${BZIP2_SRC_DIR}"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
target_include_directories(
|
|
38
|
+
${PACKAGE_NAME}
|
|
39
|
+
PRIVATE
|
|
40
|
+
${SRC_DIR}
|
|
41
|
+
"${BSDIFF_SRC_DIR}"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
find_library(LOG_LIB log)
|
|
45
|
+
find_package(fbjni REQUIRED CONFIG)
|
|
46
|
+
|
|
47
|
+
target_link_libraries(
|
|
48
|
+
${PACKAGE_NAME}
|
|
49
|
+
${LOG_LIB}
|
|
50
|
+
bzip2
|
|
51
|
+
fbjni::fbjni
|
|
52
|
+
android
|
|
53
|
+
)
|
package/android/build.gradle
CHANGED
|
@@ -42,7 +42,7 @@ expoModule {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
group = 'host.exp.exponent'
|
|
45
|
-
version = '29.1.0-canary-
|
|
45
|
+
version = '29.1.0-canary-20251023-4c86f95'
|
|
46
46
|
|
|
47
47
|
// Utility method to derive boolean values from the environment or from Java properties,
|
|
48
48
|
// and return them as strings to be used in BuildConfig fields
|
|
@@ -83,12 +83,13 @@ def useDevClient = findProject(":expo-dev-client") != null
|
|
|
83
83
|
android {
|
|
84
84
|
buildFeatures {
|
|
85
85
|
buildConfig true
|
|
86
|
+
prefab true
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
namespace "expo.modules.updates"
|
|
89
90
|
defaultConfig {
|
|
90
91
|
versionCode 31
|
|
91
|
-
versionName '29.1.0-canary-
|
|
92
|
+
versionName '29.1.0-canary-20251023-4c86f95'
|
|
92
93
|
consumerProguardFiles("proguard-rules.pro")
|
|
93
94
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
94
95
|
|
|
@@ -97,6 +98,18 @@ android {
|
|
|
97
98
|
buildConfigField("boolean", "EX_UPDATES_ANDROID_DELAY_LOAD_APP", exUpdatesAndroidDelayLoadApp)
|
|
98
99
|
buildConfigField("boolean", "EX_UPDATES_COPY_EMBEDDED_ASSETS", exUpdatesCopyEmbeddedAssets)
|
|
99
100
|
buildConfigField("boolean", "USE_DEV_CLIENT", useDevClient.toString())
|
|
101
|
+
|
|
102
|
+
externalNativeBuild {
|
|
103
|
+
cmake {
|
|
104
|
+
arguments "-DANDROID_STL=c++_shared",
|
|
105
|
+
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
externalNativeBuild {
|
|
110
|
+
cmake {
|
|
111
|
+
path "CMakeLists.txt"
|
|
112
|
+
}
|
|
100
113
|
}
|
|
101
114
|
testOptions {
|
|
102
115
|
unitTests.includeAndroidResources = true
|
|
@@ -109,6 +122,12 @@ android {
|
|
|
109
122
|
resources.excludes.add("META-INF/LICENSE-notice.md")
|
|
110
123
|
}
|
|
111
124
|
}
|
|
125
|
+
packagingOptions {
|
|
126
|
+
excludes += [
|
|
127
|
+
"**/libc++_shared.so",
|
|
128
|
+
"**/libfbjni.so",
|
|
129
|
+
]
|
|
130
|
+
}
|
|
112
131
|
sourceSets {
|
|
113
132
|
main.assets.srcDirs += files("$projectDir/src/main/certificates".toString())
|
|
114
133
|
androidTest.assets.srcDirs += files("$projectDir/src/androidTest/schemas".toString())
|
|
@@ -142,12 +161,15 @@ dependencies {
|
|
|
142
161
|
implementation("com.squareup.okhttp3:okhttp-brotli:4.9.2")
|
|
143
162
|
implementation("org.bouncycastle:bcutil-jdk15to18:1.81")
|
|
144
163
|
|
|
164
|
+
compileOnly 'com.facebook.fbjni:fbjni:0.3.0'
|
|
165
|
+
|
|
145
166
|
testImplementation 'junit:junit:4.13.2'
|
|
146
167
|
testImplementation 'androidx.test:core:1.7.0'
|
|
147
168
|
testImplementation 'com.google.truth:truth:1.4.5'
|
|
148
169
|
testImplementation "io.mockk:mockk:$mockk_version"
|
|
149
170
|
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:${kotlinVersion}"
|
|
150
171
|
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.2'
|
|
172
|
+
testImplementation "com.squareup.okhttp3:mockwebserver:4.9.2"
|
|
151
173
|
testImplementation 'org.robolectric:robolectric:4.16'
|
|
152
174
|
|
|
153
175
|
androidTestImplementation 'com.squareup.okio:okio:2.9.0'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <fbjni/fbjni.h>
|
|
6
|
+
|
|
7
|
+
namespace jni = facebook::jni;
|
|
8
|
+
|
|
9
|
+
namespace expo {
|
|
10
|
+
|
|
11
|
+
class BSPatch : public jni::JavaClass<BSPatch> {
|
|
12
|
+
public:
|
|
13
|
+
static constexpr auto kJavaDescriptor = "Lexpo/modules/updates/BSPatch;";
|
|
14
|
+
|
|
15
|
+
static void registerNatives();
|
|
16
|
+
|
|
17
|
+
static jint applyPatch(jni::alias_ref<jni::JClass>,
|
|
18
|
+
jni::alias_ref<jni::JString> oldFilePath,
|
|
19
|
+
jni::alias_ref<jni::JString> newFilePath,
|
|
20
|
+
jni::alias_ref<jni::JString> patchFilePath);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#include "BSPatch.h"
|
|
4
|
+
#include <array>
|
|
5
|
+
|
|
6
|
+
namespace jni = facebook::jni;
|
|
7
|
+
|
|
8
|
+
extern "C" int bspatch_main(int argc, char *argv[]);
|
|
9
|
+
|
|
10
|
+
namespace expo {
|
|
11
|
+
|
|
12
|
+
void BSPatch::registerNatives() {
|
|
13
|
+
javaClassStatic()->registerNatives({
|
|
14
|
+
makeNativeMethod("applyPatch", BSPatch::applyPatch),
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
jint BSPatch::applyPatch(jni::alias_ref<jni::JClass>,
|
|
19
|
+
jni::alias_ref<jni::JString> oldFilePath,
|
|
20
|
+
jni::alias_ref<jni::JString> newFilePath,
|
|
21
|
+
jni::alias_ref<jni::JString> patchFilePath) {
|
|
22
|
+
std::string oldFile = oldFilePath->toStdString();
|
|
23
|
+
std::string newFile = newFilePath->toStdString();
|
|
24
|
+
std::string patchFile = patchFilePath->toStdString();
|
|
25
|
+
|
|
26
|
+
std::array<char *, 4> argv = {
|
|
27
|
+
const_cast<char *>("bspatch"),
|
|
28
|
+
const_cast<char *>(oldFile.c_str()),
|
|
29
|
+
const_cast<char *>(newFile.c_str()),
|
|
30
|
+
const_cast<char *>(patchFile.c_str()),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return bspatch_main(static_cast<int>(argv.size()), argv.data());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
#include <fbjni/fbjni.h>
|
|
4
|
+
|
|
5
|
+
#include "BSPatch.h"
|
|
6
|
+
|
|
7
|
+
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
|
8
|
+
return facebook::jni::initialize(vm, [] {
|
|
9
|
+
expo::BSPatch::registerNatives();
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
--------------------------------------------------------------------------
|
|
3
|
+
|
|
4
|
+
This program, "bzip2", the associated library "libbzip2", and all
|
|
5
|
+
documentation, are copyright (C) 1996-2019 Julian R Seward. All
|
|
6
|
+
rights reserved.
|
|
7
|
+
|
|
8
|
+
Redistribution and use in source and binary forms, with or without
|
|
9
|
+
modification, are permitted provided that the following conditions
|
|
10
|
+
are met:
|
|
11
|
+
|
|
12
|
+
1. Redistributions of source code must retain the above copyright
|
|
13
|
+
notice, this list of conditions and the following disclaimer.
|
|
14
|
+
|
|
15
|
+
2. The origin of this software must not be misrepresented; you must
|
|
16
|
+
not claim that you wrote the original software. If you use this
|
|
17
|
+
software in a product, an acknowledgment in the product
|
|
18
|
+
documentation would be appreciated but is not required.
|
|
19
|
+
|
|
20
|
+
3. Altered source versions must be plainly marked as such, and must
|
|
21
|
+
not be misrepresented as being the original software.
|
|
22
|
+
|
|
23
|
+
4. The name of the author may not be used to endorse or promote
|
|
24
|
+
products derived from this software without specific prior written
|
|
25
|
+
permission.
|
|
26
|
+
|
|
27
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
|
28
|
+
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
29
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
30
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
31
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
32
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
|
33
|
+
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
34
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
35
|
+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
36
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
37
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
38
|
+
|
|
39
|
+
Julian Seward, jseward@acm.org
|
|
40
|
+
bzip2/libbzip2 version 1.0.8 of 13 July 2019
|
|
41
|
+
|
|
42
|
+
--------------------------------------------------------------------------
|