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.
Files changed (47) hide show
  1. package/DEVELOPMENT.md +10 -0
  2. package/android/CMakeLists.txt +53 -0
  3. package/android/build.gradle +24 -2
  4. package/android/src/main/cpp/BSPatch.h +23 -0
  5. package/android/src/main/cpp/BSPatchModule.cpp +36 -0
  6. package/android/src/main/cpp/ExpoUpdatesMain.cpp +11 -0
  7. package/android/src/main/cpp/third-party/bzip2/LICENSE +42 -0
  8. package/android/src/main/cpp/third-party/bzip2/blocksort.c +1094 -0
  9. package/android/src/main/cpp/third-party/bzip2/bzlib.c +1572 -0
  10. package/android/src/main/cpp/third-party/bzip2/bzlib.h +282 -0
  11. package/android/src/main/cpp/third-party/bzip2/bzlib_private.h +509 -0
  12. package/android/src/main/cpp/third-party/bzip2/compress.c +672 -0
  13. package/android/src/main/cpp/third-party/bzip2/crctable.c +104 -0
  14. package/android/src/main/cpp/third-party/bzip2/decompress.c +652 -0
  15. package/android/src/main/cpp/third-party/bzip2/huffman.c +205 -0
  16. package/android/src/main/cpp/third-party/bzip2/randtable.c +84 -0
  17. package/android/src/main/java/expo/modules/updates/BSPatch.kt +14 -0
  18. package/android/src/main/java/expo/modules/updates/EnabledUpdatesController.kt +7 -1
  19. package/android/src/main/java/expo/modules/updates/UpdatesConfiguration.kt +5 -0
  20. package/android/src/main/java/expo/modules/updates/UpdatesDevLauncherController.kt +7 -1
  21. package/android/src/main/java/expo/modules/updates/UpdatesUtils.kt +16 -4
  22. package/android/src/main/java/expo/modules/updates/launcher/DatabaseLauncher.kt +5 -3
  23. package/android/src/main/java/expo/modules/updates/loader/EmbeddedLoader.kt +1 -1
  24. package/android/src/main/java/expo/modules/updates/loader/FileDownloader.kt +360 -66
  25. package/android/src/main/java/expo/modules/updates/loader/Loader.kt +1 -1
  26. package/android/src/main/java/expo/modules/updates/loader/RemoteLoader.kt +3 -3
  27. package/ios/EXUpdates/AppLauncher/AppLauncherWithDatabase.swift +10 -2
  28. package/ios/EXUpdates/AppLoader/AppLoader.swift +13 -2
  29. package/ios/EXUpdates/AppLoader/FileDownloader.swift +348 -6
  30. package/ios/EXUpdates/AppLoader/RemoteAppLoader.swift +18 -2
  31. package/ios/EXUpdates/BSPatch.swift +30 -0
  32. package/ios/EXUpdates/EXUpdatesBSPatch.h +9 -0
  33. package/ios/EXUpdates/EXUpdatesBSPatch.m +18 -0
  34. package/ios/EXUpdates/EnabledAppController.swift +2 -1
  35. package/ios/EXUpdates/Procedures/CheckForUpdateProcedure.swift +7 -2
  36. package/ios/EXUpdates/UpdatesConfig.swift +6 -0
  37. package/ios/EXUpdates.podspec +14 -2
  38. package/ios/Tests/FileDownloaderManifestParsingSpec.swift +27 -16
  39. package/ios/Tests/FileDownloaderSpec.swift +320 -13
  40. package/ios/Tests/HermesDiffSpec.swift +68 -0
  41. package/ios/Tests/Support/fixtures/new.hbc +0 -0
  42. package/ios/Tests/Support/fixtures/old.hbc +0 -0
  43. package/ios/Tests/Support/fixtures/test.patch +0 -0
  44. package/ios/Tests/UpdatesConfigSpec.swift +3 -0
  45. package/package.json +8 -8
  46. package/vendor/bspatch/LICENSE +25 -0
  47. 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
+ )
@@ -42,7 +42,7 @@ expoModule {
42
42
  }
43
43
 
44
44
  group = 'host.exp.exponent'
45
- version = '29.1.0-canary-20251013-623c5a6'
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-20251013-623c5a6'
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
+ --------------------------------------------------------------------------