expo-updates 0.25.5 → 0.25.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/CHANGELOG.md +12 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/updates/db/dao/AssetDao.kt +9 -0
- package/android/src/main/java/expo/modules/updates/db/dao/UpdateDao.kt +6 -6
- package/android/src/main/java/expo/modules/updates/db/entity/UpdateEntity.kt +2 -0
- package/android/src/main/java/expo/modules/updates/launcher/DatabaseLauncher.kt +9 -4
- package/android/src/main/java/expo/modules/updates/selectionpolicy/ReaperSelectionPolicyFilterAware.kt +4 -1
- package/build/Updates.d.ts +2 -0
- package/build/Updates.d.ts.map +1 -1
- package/build/Updates.js +2 -0
- package/build/Updates.js.map +1 -1
- package/expo-updates-gradle-plugin/src/main/kotlin/expo/modules/updates/ExpoUpdatesPlugin.kt +19 -3
- package/package.json +2 -2
- package/src/Updates.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 0.25.7 — 2024-05-02
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Fixed Gradle Plugin build error when no specified `entryFile` in **android/app/build.gradle**. ([#28546](https://github.com/expo/expo/pull/28546) by [@kudo](https://github.com/kudo))
|
|
18
|
+
|
|
19
|
+
## 0.25.6 — 2024-05-01
|
|
20
|
+
|
|
21
|
+
### 🐛 Bug fixes
|
|
22
|
+
|
|
23
|
+
- Android: Fix hard crash due to missing asset edge row. ([#28264](https://github.com/expo/expo/pull/28264) by [@douglowder](https://github.com/douglowder))
|
|
24
|
+
|
|
13
25
|
## 0.25.5 — 2024-04-24
|
|
14
26
|
|
|
15
27
|
_This version does not introduce any user-facing changes._
|
package/android/build.gradle
CHANGED
|
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
|
|
|
2
2
|
apply plugin: 'kotlin-kapt'
|
|
3
3
|
|
|
4
4
|
group = 'host.exp.exponent'
|
|
5
|
-
version = '0.25.
|
|
5
|
+
version = '0.25.7'
|
|
6
6
|
|
|
7
7
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
8
8
|
apply from: expoModulesCorePlugin
|
|
@@ -48,7 +48,7 @@ android {
|
|
|
48
48
|
namespace "expo.modules.updates"
|
|
49
49
|
defaultConfig {
|
|
50
50
|
versionCode 31
|
|
51
|
-
versionName '0.25.
|
|
51
|
+
versionName '0.25.7'
|
|
52
52
|
consumerProguardFiles("proguard-rules.pro")
|
|
53
53
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
54
54
|
|
|
@@ -37,6 +37,14 @@ abstract class AssetDao {
|
|
|
37
37
|
)
|
|
38
38
|
abstract fun _unmarkUsedAssetsFromDeletion()
|
|
39
39
|
|
|
40
|
+
@Query(
|
|
41
|
+
"UPDATE assets SET marked_for_deletion = 0 WHERE id IN (" +
|
|
42
|
+
" SELECT launch_asset_id" +
|
|
43
|
+
" FROM updates" +
|
|
44
|
+
" WHERE updates.keep);"
|
|
45
|
+
)
|
|
46
|
+
abstract fun _unmarkUsedLaunchAssetsFromDeletion()
|
|
47
|
+
|
|
40
48
|
@Query(
|
|
41
49
|
"UPDATE assets SET marked_for_deletion = 0 WHERE relative_path IN (" +
|
|
42
50
|
" SELECT relative_path" +
|
|
@@ -145,6 +153,7 @@ abstract class AssetDao {
|
|
|
145
153
|
// this is safe since this is a transaction and will be rolled back upon failure
|
|
146
154
|
_markAllAssetsForDeletion()
|
|
147
155
|
_unmarkUsedAssetsFromDeletion()
|
|
156
|
+
_unmarkUsedLaunchAssetsFromDeletion()
|
|
148
157
|
// check for duplicate rows representing a single file on disk
|
|
149
158
|
_unmarkDuplicateUsedAssetsFromDeletion()
|
|
150
159
|
val deletedAssets = _loadAssetsMarkedForDeletion()
|
|
@@ -25,8 +25,8 @@ abstract class UpdateDao {
|
|
|
25
25
|
@Query("SELECT * FROM updates WHERE id = :id;")
|
|
26
26
|
abstract fun _loadUpdatesWithId(id: UUID): List<UpdateEntity>
|
|
27
27
|
|
|
28
|
-
@Query("SELECT assets.* FROM assets INNER JOIN updates ON updates.launch_asset_id = assets.id WHERE updates.id = :
|
|
29
|
-
abstract fun
|
|
28
|
+
@Query("SELECT assets.* FROM assets INNER JOIN updates ON updates.launch_asset_id = assets.id WHERE updates.id = :updateId;")
|
|
29
|
+
abstract fun _loadLaunchAssetForUpdate(updateId: UUID): AssetEntity?
|
|
30
30
|
|
|
31
31
|
@Query("UPDATE updates SET keep = 1 WHERE id = :id;")
|
|
32
32
|
abstract fun _keepUpdate(id: UUID)
|
|
@@ -67,10 +67,10 @@ abstract class UpdateDao {
|
|
|
67
67
|
return if (updateEntities.isNotEmpty()) updateEntities[0] else null
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
fun
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
fun loadLaunchAssetForUpdate(updateId: UUID): AssetEntity? {
|
|
71
|
+
return _loadLaunchAssetForUpdate(updateId)?.apply {
|
|
72
|
+
isLaunchAsset = true
|
|
73
|
+
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
@Insert
|
|
@@ -71,7 +71,7 @@ class DatabaseLauncher(
|
|
|
71
71
|
|
|
72
72
|
launchedUpdate = getLaunchableUpdate(database, context)
|
|
73
73
|
if (launchedUpdate == null) {
|
|
74
|
-
this.callback!!.onFailure(Exception("No launchable update was found. If this is a
|
|
74
|
+
this.callback!!.onFailure(Exception("No launchable update was found. If this is a generic app, ensure expo-updates is configured correctly."))
|
|
75
75
|
return
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -83,9 +83,14 @@ class DatabaseLauncher(
|
|
|
83
83
|
|
|
84
84
|
// verify that we have all assets on disk
|
|
85
85
|
// according to the database, we should, but something could have gone wrong on disk
|
|
86
|
-
val launchAsset = database.updateDao().
|
|
86
|
+
val launchAsset = database.updateDao().loadLaunchAssetForUpdate(launchedUpdate!!.id)
|
|
87
|
+
if (launchAsset == null) {
|
|
88
|
+
this.callback!!.onFailure(Exception("Launch asset not found for update; this should never happen. Debug info: ${launchedUpdate!!.debugInfo()}"))
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
87
92
|
if (launchAsset.relativePath == null) {
|
|
88
|
-
|
|
93
|
+
this.callback!!.onFailure(Exception("Launch asset relative path should not be null. Debug info: ${launchedUpdate!!.debugInfo()}"))
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
val launchAssetFile = ensureAssetExists(launchAsset, database, context)
|
|
@@ -113,7 +118,7 @@ class DatabaseLauncher(
|
|
|
113
118
|
|
|
114
119
|
if (assetsToDownload == 0) {
|
|
115
120
|
if (this.launchAssetFile == null) {
|
|
116
|
-
this.callback!!.onFailure(Exception("
|
|
121
|
+
this.callback!!.onFailure(Exception("Launch asset file was null with no assets to download reported; this should never happen. Debug info: ${launchedUpdate!!.debugInfo()}"))
|
|
117
122
|
} else {
|
|
118
123
|
this.callback!!.onSuccess()
|
|
119
124
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package expo.modules.updates.selectionpolicy
|
|
2
2
|
|
|
3
3
|
import expo.modules.updates.db.entity.UpdateEntity
|
|
4
|
+
import expo.modules.updates.db.enums.UpdateStatus
|
|
4
5
|
import org.json.JSONObject
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -50,6 +51,8 @@ class ReaperSelectionPolicyFilterAware : ReaperSelectionPolicy {
|
|
|
50
51
|
} else if (nextNewestUpdate != null) {
|
|
51
52
|
updatesToDelete.remove(nextNewestUpdate)
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
+
|
|
55
|
+
// don't delete embedded update
|
|
56
|
+
return updatesToDelete.filter { it.status != UpdateStatus.EMBEDDED }
|
|
54
57
|
}
|
|
55
58
|
}
|
package/build/Updates.d.ts
CHANGED
|
@@ -80,6 +80,8 @@ export declare const createdAt: Date | null;
|
|
|
80
80
|
* Instructs the app to reload using the most recently downloaded version. This is useful for
|
|
81
81
|
* triggering a newly downloaded update to launch without the user needing to manually restart the
|
|
82
82
|
* app.
|
|
83
|
+
* Unlike `Expo.reloadAppAsync()` provided by the `expo` package,
|
|
84
|
+
* this function not only reloads the app but also changes the loaded JavaScript bundle to that of the most recently downloaded update.
|
|
83
85
|
*
|
|
84
86
|
* It is not recommended to place any meaningful logic after a call to `await
|
|
85
87
|
* Updates.reloadAsync()`. This is because the promise is resolved after verifying that the app can
|
package/build/Updates.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Updates.d.ts","sourceRoot":"","sources":["../src/Updates.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,WAAW,EACX,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,EAC9B,eAAe,EACf,gCAAgC,EACjC,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,EAAE,OAAiC,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,GAAG,IAGtB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,GAAG,IAAkC,CAAC;AAElE;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,GAAG,IAAyC,CAAC;AAShF;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,8BAA8B,GAAG,IACQ,CAAC;AAG3E;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,WAA2C,CAAC;AAEtE;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,SAAgC,CAAC;AAE/D;;;GAGG;AACH,eAAO,MAAM,qBAAqB,eAAoC,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,OAA+C,CAAC;AAG/E;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,OAAoD,CAAC;AAEzF;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAEnC,CAAC;AAEL;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,IAAI,GAAG,IAEvB,CAAC;AAoBT
|
|
1
|
+
{"version":3,"file":"Updates.d.ts","sourceRoot":"","sources":["../src/Updates.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,WAAW,EACX,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,EACjB,8BAA8B,EAC9B,eAAe,EACf,gCAAgC,EACjC,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,EAAE,OAAiC,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,GAAG,IAGtB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,GAAG,IAAkC,CAAC;AAElE;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,GAAG,IAAyC,CAAC;AAShF;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,8BAA8B,GAAG,IACQ,CAAC;AAG3E;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,WAA2C,CAAC;AAEtE;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,SAAgC,CAAC;AAE/D;;;GAGG;AACH,eAAO,MAAM,qBAAqB,eAAoC,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,OAA+C,CAAC;AAG/E;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,OAAoD,CAAC;AAEzF;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAEnC,CAAC;AAEL;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,IAAI,GAAG,IAEvB,CAAC;AAoBT;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAWjD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAoBtE;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAE3E;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,GAAE,MAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAE9F;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAoBnE;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,WAAW,CAAC,EAAE,MAAM,QAIrE;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,qBAAqB,EAAE,gCAAgC,GAAG;IACxD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,gCAAgC,CAmBlC;AAED;;GAEG;AACH,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,gCAAgC,CAAC,CAGnG"}
|
package/build/Updates.js
CHANGED
|
@@ -106,6 +106,8 @@ const manualUpdatesInstructions = 'To test usage of the expo-updates JS API in y
|
|
|
106
106
|
* Instructs the app to reload using the most recently downloaded version. This is useful for
|
|
107
107
|
* triggering a newly downloaded update to launch without the user needing to manually restart the
|
|
108
108
|
* app.
|
|
109
|
+
* Unlike `Expo.reloadAppAsync()` provided by the `expo` package,
|
|
110
|
+
* this function not only reloads the app but also changes the loaded JavaScript bundle to that of the most recently downloaded update.
|
|
109
111
|
*
|
|
110
112
|
* It is not recommended to place any meaningful logic after a call to `await
|
|
111
113
|
* Updates.reloadAsync()`. This is because the promise is resolved after verifying that the app can
|
package/build/Updates.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Updates.js","sourceRoot":"","sources":["../src/Updates.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError } from 'expo-modules-core';\n\nimport ExpoUpdates from './ExpoUpdates';\nimport {\n LocalAssets,\n Manifest,\n UpdateCheckResult,\n UpdateFetchResult,\n UpdatesCheckAutomaticallyValue,\n UpdatesLogEntry,\n UpdatesNativeStateMachineContext,\n} from './Updates.types';\n\n/**\n * Whether `expo-updates` is enabled. This may be false in a variety of cases including:\n * - enabled set to false in configuration\n * - missing or invalid URL in configuration\n * - missing runtime version or SDK version in configuration\n * - error accessing storage on device during initialization\n *\n * When false, the embedded update is loaded.\n */\nexport const isEnabled: boolean = !!ExpoUpdates.isEnabled;\n\n/**\n * The UUID that uniquely identifies the currently running update. The\n * UUID is represented in its canonical string form and will always use lowercase letters.\n * This value is `null` when running in a local development environment or any other environment where `expo-updates` is disabled.\n * @example\n * `\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"`\n */\nexport const updateId: string | null =\n ExpoUpdates.updateId && typeof ExpoUpdates.updateId === 'string'\n ? ExpoUpdates.updateId.toLowerCase()\n : null;\n\n/**\n * The channel name of the current build, if configured for use with EAS Update. `null` otherwise.\n *\n * Expo Go and development builds are not set to a specific channel and can run any updates compatible with their native runtime. Therefore, this value will always be `null` when running an update on Expo Go or a development build.\n */\nexport const channel: string | null = ExpoUpdates.channel ?? null;\n\n/**\n * The runtime version of the current build.\n */\nexport const runtimeVersion: string | null = ExpoUpdates.runtimeVersion ?? null;\n\nconst _checkAutomaticallyMapNativeToJS = {\n ALWAYS: 'ON_LOAD',\n ERROR_RECOVERY_ONLY: 'ON_ERROR_RECOVERY',\n NEVER: 'NEVER',\n WIFI_ONLY: 'WIFI_ONLY',\n};\n\n/**\n * Determines if and when `expo-updates` checks for and downloads updates automatically on startup.\n */\nexport const checkAutomatically: UpdatesCheckAutomaticallyValue | null =\n _checkAutomaticallyMapNativeToJS[ExpoUpdates.checkAutomatically] ?? null;\n\n// @docsMissing\n/**\n * @hidden\n */\nexport const localAssets: LocalAssets = ExpoUpdates.localAssets ?? {};\n\n/**\n * `expo-updates` does its very best to always launch monotonically newer versions of your app so\n * you don't need to worry about backwards compatibility when you put out an update. In very rare\n * cases, it's possible that `expo-updates` may need to fall back to the update that's embedded in\n * the app binary, even after newer updates have been downloaded and run (an \"emergency launch\").\n * This boolean will be `true` if the app is launching under this fallback mechanism and `false`\n * otherwise. If you are concerned about backwards compatibility of future updates to your app, you\n * can use this constant to provide special behavior for this rare case.\n */\nexport const isEmergencyLaunch = ExpoUpdates.isEmergencyLaunch;\n\n/**\n * If `isEmergencyLaunch` is set to true, this will contain a string error message describing\n * what failed during initialization.\n */\nexport const emergencyLaunchReason = ExpoUpdates.emergencyLaunchReason;\n\n/**\n * This will be true if the currently running update is the one embedded in the build,\n * and not one downloaded from the updates server.\n */\nexport const isEmbeddedLaunch: boolean = ExpoUpdates.isEmbeddedLaunch || false;\n\n// @docsMissing\n/**\n * @hidden\n */\nexport const isUsingEmbeddedAssets: boolean = ExpoUpdates.isUsingEmbeddedAssets || false;\n\n/**\n * If `expo-updates` is enabled, this is the\n * [manifest](/versions/latest/sdk/constants/#manifest) (or\n * [classic manifest](/versions/latest/sdk/constants/#appmanifest))\n * object for the update that's currently running.\n *\n * In development mode, or any other environment in which `expo-updates` is disabled, this object is\n * empty.\n */\nexport const manifest: Partial<Manifest> =\n (ExpoUpdates.manifestString ? JSON.parse(ExpoUpdates.manifestString) : ExpoUpdates.manifest) ??\n {};\n\n/**\n * If `expo-updates` is enabled, this is a `Date` object representing the creation time of the update that's currently running (whether it was embedded or downloaded at runtime).\n *\n * In development mode, or any other environment in which `expo-updates` is disabled, this value is\n * null.\n */\nexport const createdAt: Date | null = ExpoUpdates.commitTime\n ? new Date(ExpoUpdates.commitTime)\n : null;\n\n/**\n * During non-expo development we block accessing the updates API methods on the JS side, but when developing in\n * Expo Go or a development client build, the controllers should have control over which API methods should\n * be allowed.\n */\nconst shouldDeferToNativeForAPIMethodAvailabilityInDevelopment =\n !!ExpoUpdates.shouldDeferToNativeForAPIMethodAvailabilityInDevelopment;\n\n/**\n * Developer tool is set when a project is served by `expo start`.\n */\nconst isUsingDeveloperTool =\n 'extra' in manifest ? !!manifest.extra?.expoGo?.developer?.tool : false;\n\nconst manualUpdatesInstructions =\n 'To test usage of the expo-updates JS API in your app, make a release build with `npx expo run:ios --configuration Release` or ' +\n '`npx expo run:android --variant Release`.';\n\n/**\n * Instructs the app to reload using the most recently downloaded version. This is useful for\n * triggering a newly downloaded update to launch without the user needing to manually restart the\n * app.\n *\n * It is not recommended to place any meaningful logic after a call to `await\n * Updates.reloadAsync()`. This is because the promise is resolved after verifying that the app can\n * be reloaded, and immediately before posting an asynchronous task to the main thread to actually\n * reload the app. It is unsafe to make any assumptions about whether any more JS code will be\n * executed after the `Updates.reloadAsync` method call resolves, since that depends on the OS and\n * the state of the native module and main threads.\n *\n * This method cannot be used in Expo Go or development mode, and the returned promise will be rejected if you\n * try to do so. It also rejects when `expo-updates` is not enabled.\n *\n * @return A promise that fulfills right before the reload instruction is sent to the JS runtime, or\n * rejects if it cannot find a reference to the JS runtime. If the promise is rejected in production\n * mode, it most likely means you have installed the module incorrectly. Double check you've\n * followed the installation instructions. In particular, on iOS ensure that you set the `bridge`\n * property on `EXUpdatesAppController` with a pointer to the `RCTBridge` you want to reload, and on\n * Android ensure you either call `UpdatesController.initialize` with the instance of\n * `ReactApplication` you want to reload, or call `UpdatesController.setReactNativeHost` with the\n * proper instance of `ReactNativeHost`.\n */\nexport async function reloadAsync(): Promise<void> {\n if (\n (__DEV__ || isUsingDeveloperTool) &&\n !shouldDeferToNativeForAPIMethodAvailabilityInDevelopment\n ) {\n throw new CodedError(\n 'ERR_UPDATES_DISABLED',\n `You cannot use the Updates module in development mode in a production app. ${manualUpdatesInstructions}`\n );\n }\n await ExpoUpdates.reload();\n}\n\n/**\n * Checks the server to see if a newly deployed update to your project is available. Does not\n * actually download the update. This method cannot be used in development mode, and the returned\n * promise will be rejected if you try to do so.\n *\n * Checking for an update uses a device's bandwidth and battery life like any network call.\n * Additionally, updates served by Expo may be rate limited. A good rule of thumb to check for\n * updates judiciously is to check when the user launches or foregrounds the app. Avoid polling for\n * updates in a frequent loop.\n *\n * @return A promise that fulfills with an [`UpdateCheckResult`](#updatecheckresult) object.\n *\n * The promise rejects in Expo Go or if the app is in development mode, or if there is an unexpected error or\n * timeout communicating with the server. It also rejects when `expo-updates` is not enabled.\n */\nexport async function checkForUpdateAsync(): Promise<UpdateCheckResult> {\n if (\n (__DEV__ || isUsingDeveloperTool) &&\n !shouldDeferToNativeForAPIMethodAvailabilityInDevelopment\n ) {\n throw new CodedError(\n 'ERR_UPDATES_DISABLED',\n `You cannot check for updates in development mode. ${manualUpdatesInstructions}`\n );\n }\n\n const result = await ExpoUpdates.checkForUpdateAsync();\n if ('manifestString' in result) {\n const { manifestString, ...rest } = result;\n return {\n ...rest,\n manifest: JSON.parse(manifestString),\n };\n }\n return result;\n}\n\n/**\n * Retrieves the current extra params.\n *\n * This method cannot be used in Expo Go or development mode. It also rejects when `expo-updates` is not enabled.\n */\nexport async function getExtraParamsAsync(): Promise<Record<string, string>> {\n return await ExpoUpdates.getExtraParamsAsync();\n}\n\n/**\n * Sets an extra param if value is non-null, otherwise unsets the param.\n * Extra params are sent as an [Expo Structured Field Value Dictionary](/technical-specs/expo-sfv-0/)\n * in the `Expo-Extra-Params` header of update requests. A compliant update server may use these params when selecting an update to serve.\n *\n * This method cannot be used in Expo Go or development mode. It also rejects when `expo-updates` is not enabled.\n */\nexport async function setExtraParamAsync(\n key: string,\n value: string | null | undefined\n): Promise<void> {\n return await ExpoUpdates.setExtraParamAsync(key, value ?? null);\n}\n\n/**\n * Retrieves the most recent `expo-updates` log entries.\n *\n * @param maxAge Sets the max age of retrieved log entries in milliseconds. Default to `3600000` ms (1 hour).\n *\n * @return A promise that fulfills with an array of [`UpdatesLogEntry`](#updateslogentry) objects;\n *\n * The promise rejects if there is an unexpected error in retrieving the logs.\n */\nexport async function readLogEntriesAsync(maxAge: number = 3600000): Promise<UpdatesLogEntry[]> {\n return await ExpoUpdates.readLogEntriesAsync(maxAge);\n}\n\n/**\n * Clears existing `expo-updates` log entries.\n *\n * > For now, this operation does nothing on the client. Once log persistence has been\n * > implemented, this operation will actually remove existing logs.\n *\n * @return A promise that fulfills if the clear operation was successful.\n *\n * The promise rejects if there is an unexpected error in clearing the logs.\n *\n */\nexport async function clearLogEntriesAsync(): Promise<void> {\n await ExpoUpdates.clearLogEntriesAsync();\n}\n\n/**\n * Downloads the most recently deployed update to your project from server to the device's local\n * storage. This method cannot be used in development mode, and the returned promise will be\n * rejected if you try to do so.\n *\n > **Note:** [`reloadAsync()`](#updatesreloadasync) can be called after promise resolution to\n * reload the app using the most recently downloaded version. Otherwise, the update will be applied\n * on the next app cold start.\n *\n * @return A promise that fulfills with an [`UpdateFetchResult`](#updatefetchresult) object.\n *\n * The promise rejects in Expo Go or if the app is in development mode, or if there is an unexpected error or\n * timeout communicating with the server. It also rejects when `expo-updates` is not enabled.\n */\nexport async function fetchUpdateAsync(): Promise<UpdateFetchResult> {\n if (\n (__DEV__ || isUsingDeveloperTool) &&\n !shouldDeferToNativeForAPIMethodAvailabilityInDevelopment\n ) {\n throw new CodedError(\n 'ERR_UPDATES_DISABLED',\n `You cannot fetch updates in development mode. ${manualUpdatesInstructions}`\n );\n }\n\n const result = await ExpoUpdates.fetchUpdateAsync();\n if ('manifestString' in result) {\n const { manifestString, ...rest } = result;\n return {\n ...rest,\n manifest: JSON.parse(manifestString),\n };\n }\n return result;\n}\n\n/**\n * @hidden\n */\nexport function clearUpdateCacheExperimentalAsync(_sdkVersion?: string) {\n console.warn(\n \"This method is no longer necessary. `expo-updates` now automatically deletes your app's old bundle files!\"\n );\n}\n\n/**\n * @hidden\n */\nexport function transformNativeStateMachineContext(\n originalNativeContext: UpdatesNativeStateMachineContext & {\n latestManifestString?: string;\n downloadedManifestString?: string;\n lastCheckForUpdateTimeString?: string;\n rollbackString?: string;\n }\n): UpdatesNativeStateMachineContext {\n const nativeContext = { ...originalNativeContext };\n if (nativeContext.latestManifestString) {\n nativeContext.latestManifest = JSON.parse(nativeContext.latestManifestString);\n delete nativeContext.latestManifestString;\n }\n if (nativeContext.downloadedManifestString) {\n nativeContext.downloadedManifest = JSON.parse(nativeContext.downloadedManifestString);\n delete nativeContext.downloadedManifestString;\n }\n if (nativeContext.lastCheckForUpdateTimeString) {\n nativeContext.lastCheckForUpdateTime = new Date(nativeContext.lastCheckForUpdateTimeString);\n delete nativeContext.lastCheckForUpdateTimeString;\n }\n if (nativeContext.rollbackString) {\n nativeContext.rollback = JSON.parse(nativeContext.rollbackString);\n delete nativeContext.rollbackString;\n }\n return nativeContext;\n}\n\n/**\n * @hidden\n */\nexport async function getNativeStateMachineContextAsync(): Promise<UpdatesNativeStateMachineContext> {\n const nativeContext = await ExpoUpdates.getNativeStateMachineContextAsync();\n return transformNativeStateMachineContext(nativeContext);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Updates.js","sourceRoot":"","sources":["../src/Updates.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError } from 'expo-modules-core';\n\nimport ExpoUpdates from './ExpoUpdates';\nimport {\n LocalAssets,\n Manifest,\n UpdateCheckResult,\n UpdateFetchResult,\n UpdatesCheckAutomaticallyValue,\n UpdatesLogEntry,\n UpdatesNativeStateMachineContext,\n} from './Updates.types';\n\n/**\n * Whether `expo-updates` is enabled. This may be false in a variety of cases including:\n * - enabled set to false in configuration\n * - missing or invalid URL in configuration\n * - missing runtime version or SDK version in configuration\n * - error accessing storage on device during initialization\n *\n * When false, the embedded update is loaded.\n */\nexport const isEnabled: boolean = !!ExpoUpdates.isEnabled;\n\n/**\n * The UUID that uniquely identifies the currently running update. The\n * UUID is represented in its canonical string form and will always use lowercase letters.\n * This value is `null` when running in a local development environment or any other environment where `expo-updates` is disabled.\n * @example\n * `\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"`\n */\nexport const updateId: string | null =\n ExpoUpdates.updateId && typeof ExpoUpdates.updateId === 'string'\n ? ExpoUpdates.updateId.toLowerCase()\n : null;\n\n/**\n * The channel name of the current build, if configured for use with EAS Update. `null` otherwise.\n *\n * Expo Go and development builds are not set to a specific channel and can run any updates compatible with their native runtime. Therefore, this value will always be `null` when running an update on Expo Go or a development build.\n */\nexport const channel: string | null = ExpoUpdates.channel ?? null;\n\n/**\n * The runtime version of the current build.\n */\nexport const runtimeVersion: string | null = ExpoUpdates.runtimeVersion ?? null;\n\nconst _checkAutomaticallyMapNativeToJS = {\n ALWAYS: 'ON_LOAD',\n ERROR_RECOVERY_ONLY: 'ON_ERROR_RECOVERY',\n NEVER: 'NEVER',\n WIFI_ONLY: 'WIFI_ONLY',\n};\n\n/**\n * Determines if and when `expo-updates` checks for and downloads updates automatically on startup.\n */\nexport const checkAutomatically: UpdatesCheckAutomaticallyValue | null =\n _checkAutomaticallyMapNativeToJS[ExpoUpdates.checkAutomatically] ?? null;\n\n// @docsMissing\n/**\n * @hidden\n */\nexport const localAssets: LocalAssets = ExpoUpdates.localAssets ?? {};\n\n/**\n * `expo-updates` does its very best to always launch monotonically newer versions of your app so\n * you don't need to worry about backwards compatibility when you put out an update. In very rare\n * cases, it's possible that `expo-updates` may need to fall back to the update that's embedded in\n * the app binary, even after newer updates have been downloaded and run (an \"emergency launch\").\n * This boolean will be `true` if the app is launching under this fallback mechanism and `false`\n * otherwise. If you are concerned about backwards compatibility of future updates to your app, you\n * can use this constant to provide special behavior for this rare case.\n */\nexport const isEmergencyLaunch = ExpoUpdates.isEmergencyLaunch;\n\n/**\n * If `isEmergencyLaunch` is set to true, this will contain a string error message describing\n * what failed during initialization.\n */\nexport const emergencyLaunchReason = ExpoUpdates.emergencyLaunchReason;\n\n/**\n * This will be true if the currently running update is the one embedded in the build,\n * and not one downloaded from the updates server.\n */\nexport const isEmbeddedLaunch: boolean = ExpoUpdates.isEmbeddedLaunch || false;\n\n// @docsMissing\n/**\n * @hidden\n */\nexport const isUsingEmbeddedAssets: boolean = ExpoUpdates.isUsingEmbeddedAssets || false;\n\n/**\n * If `expo-updates` is enabled, this is the\n * [manifest](/versions/latest/sdk/constants/#manifest) (or\n * [classic manifest](/versions/latest/sdk/constants/#appmanifest))\n * object for the update that's currently running.\n *\n * In development mode, or any other environment in which `expo-updates` is disabled, this object is\n * empty.\n */\nexport const manifest: Partial<Manifest> =\n (ExpoUpdates.manifestString ? JSON.parse(ExpoUpdates.manifestString) : ExpoUpdates.manifest) ??\n {};\n\n/**\n * If `expo-updates` is enabled, this is a `Date` object representing the creation time of the update that's currently running (whether it was embedded or downloaded at runtime).\n *\n * In development mode, or any other environment in which `expo-updates` is disabled, this value is\n * null.\n */\nexport const createdAt: Date | null = ExpoUpdates.commitTime\n ? new Date(ExpoUpdates.commitTime)\n : null;\n\n/**\n * During non-expo development we block accessing the updates API methods on the JS side, but when developing in\n * Expo Go or a development client build, the controllers should have control over which API methods should\n * be allowed.\n */\nconst shouldDeferToNativeForAPIMethodAvailabilityInDevelopment =\n !!ExpoUpdates.shouldDeferToNativeForAPIMethodAvailabilityInDevelopment;\n\n/**\n * Developer tool is set when a project is served by `expo start`.\n */\nconst isUsingDeveloperTool =\n 'extra' in manifest ? !!manifest.extra?.expoGo?.developer?.tool : false;\n\nconst manualUpdatesInstructions =\n 'To test usage of the expo-updates JS API in your app, make a release build with `npx expo run:ios --configuration Release` or ' +\n '`npx expo run:android --variant Release`.';\n\n/**\n * Instructs the app to reload using the most recently downloaded version. This is useful for\n * triggering a newly downloaded update to launch without the user needing to manually restart the\n * app.\n * Unlike `Expo.reloadAppAsync()` provided by the `expo` package,\n * this function not only reloads the app but also changes the loaded JavaScript bundle to that of the most recently downloaded update.\n *\n * It is not recommended to place any meaningful logic after a call to `await\n * Updates.reloadAsync()`. This is because the promise is resolved after verifying that the app can\n * be reloaded, and immediately before posting an asynchronous task to the main thread to actually\n * reload the app. It is unsafe to make any assumptions about whether any more JS code will be\n * executed after the `Updates.reloadAsync` method call resolves, since that depends on the OS and\n * the state of the native module and main threads.\n *\n * This method cannot be used in Expo Go or development mode, and the returned promise will be rejected if you\n * try to do so. It also rejects when `expo-updates` is not enabled.\n *\n * @return A promise that fulfills right before the reload instruction is sent to the JS runtime, or\n * rejects if it cannot find a reference to the JS runtime. If the promise is rejected in production\n * mode, it most likely means you have installed the module incorrectly. Double check you've\n * followed the installation instructions. In particular, on iOS ensure that you set the `bridge`\n * property on `EXUpdatesAppController` with a pointer to the `RCTBridge` you want to reload, and on\n * Android ensure you either call `UpdatesController.initialize` with the instance of\n * `ReactApplication` you want to reload, or call `UpdatesController.setReactNativeHost` with the\n * proper instance of `ReactNativeHost`.\n */\nexport async function reloadAsync(): Promise<void> {\n if (\n (__DEV__ || isUsingDeveloperTool) &&\n !shouldDeferToNativeForAPIMethodAvailabilityInDevelopment\n ) {\n throw new CodedError(\n 'ERR_UPDATES_DISABLED',\n `You cannot use the Updates module in development mode in a production app. ${manualUpdatesInstructions}`\n );\n }\n await ExpoUpdates.reload();\n}\n\n/**\n * Checks the server to see if a newly deployed update to your project is available. Does not\n * actually download the update. This method cannot be used in development mode, and the returned\n * promise will be rejected if you try to do so.\n *\n * Checking for an update uses a device's bandwidth and battery life like any network call.\n * Additionally, updates served by Expo may be rate limited. A good rule of thumb to check for\n * updates judiciously is to check when the user launches or foregrounds the app. Avoid polling for\n * updates in a frequent loop.\n *\n * @return A promise that fulfills with an [`UpdateCheckResult`](#updatecheckresult) object.\n *\n * The promise rejects in Expo Go or if the app is in development mode, or if there is an unexpected error or\n * timeout communicating with the server. It also rejects when `expo-updates` is not enabled.\n */\nexport async function checkForUpdateAsync(): Promise<UpdateCheckResult> {\n if (\n (__DEV__ || isUsingDeveloperTool) &&\n !shouldDeferToNativeForAPIMethodAvailabilityInDevelopment\n ) {\n throw new CodedError(\n 'ERR_UPDATES_DISABLED',\n `You cannot check for updates in development mode. ${manualUpdatesInstructions}`\n );\n }\n\n const result = await ExpoUpdates.checkForUpdateAsync();\n if ('manifestString' in result) {\n const { manifestString, ...rest } = result;\n return {\n ...rest,\n manifest: JSON.parse(manifestString),\n };\n }\n return result;\n}\n\n/**\n * Retrieves the current extra params.\n *\n * This method cannot be used in Expo Go or development mode. It also rejects when `expo-updates` is not enabled.\n */\nexport async function getExtraParamsAsync(): Promise<Record<string, string>> {\n return await ExpoUpdates.getExtraParamsAsync();\n}\n\n/**\n * Sets an extra param if value is non-null, otherwise unsets the param.\n * Extra params are sent as an [Expo Structured Field Value Dictionary](/technical-specs/expo-sfv-0/)\n * in the `Expo-Extra-Params` header of update requests. A compliant update server may use these params when selecting an update to serve.\n *\n * This method cannot be used in Expo Go or development mode. It also rejects when `expo-updates` is not enabled.\n */\nexport async function setExtraParamAsync(\n key: string,\n value: string | null | undefined\n): Promise<void> {\n return await ExpoUpdates.setExtraParamAsync(key, value ?? null);\n}\n\n/**\n * Retrieves the most recent `expo-updates` log entries.\n *\n * @param maxAge Sets the max age of retrieved log entries in milliseconds. Default to `3600000` ms (1 hour).\n *\n * @return A promise that fulfills with an array of [`UpdatesLogEntry`](#updateslogentry) objects;\n *\n * The promise rejects if there is an unexpected error in retrieving the logs.\n */\nexport async function readLogEntriesAsync(maxAge: number = 3600000): Promise<UpdatesLogEntry[]> {\n return await ExpoUpdates.readLogEntriesAsync(maxAge);\n}\n\n/**\n * Clears existing `expo-updates` log entries.\n *\n * > For now, this operation does nothing on the client. Once log persistence has been\n * > implemented, this operation will actually remove existing logs.\n *\n * @return A promise that fulfills if the clear operation was successful.\n *\n * The promise rejects if there is an unexpected error in clearing the logs.\n *\n */\nexport async function clearLogEntriesAsync(): Promise<void> {\n await ExpoUpdates.clearLogEntriesAsync();\n}\n\n/**\n * Downloads the most recently deployed update to your project from server to the device's local\n * storage. This method cannot be used in development mode, and the returned promise will be\n * rejected if you try to do so.\n *\n > **Note:** [`reloadAsync()`](#updatesreloadasync) can be called after promise resolution to\n * reload the app using the most recently downloaded version. Otherwise, the update will be applied\n * on the next app cold start.\n *\n * @return A promise that fulfills with an [`UpdateFetchResult`](#updatefetchresult) object.\n *\n * The promise rejects in Expo Go or if the app is in development mode, or if there is an unexpected error or\n * timeout communicating with the server. It also rejects when `expo-updates` is not enabled.\n */\nexport async function fetchUpdateAsync(): Promise<UpdateFetchResult> {\n if (\n (__DEV__ || isUsingDeveloperTool) &&\n !shouldDeferToNativeForAPIMethodAvailabilityInDevelopment\n ) {\n throw new CodedError(\n 'ERR_UPDATES_DISABLED',\n `You cannot fetch updates in development mode. ${manualUpdatesInstructions}`\n );\n }\n\n const result = await ExpoUpdates.fetchUpdateAsync();\n if ('manifestString' in result) {\n const { manifestString, ...rest } = result;\n return {\n ...rest,\n manifest: JSON.parse(manifestString),\n };\n }\n return result;\n}\n\n/**\n * @hidden\n */\nexport function clearUpdateCacheExperimentalAsync(_sdkVersion?: string) {\n console.warn(\n \"This method is no longer necessary. `expo-updates` now automatically deletes your app's old bundle files!\"\n );\n}\n\n/**\n * @hidden\n */\nexport function transformNativeStateMachineContext(\n originalNativeContext: UpdatesNativeStateMachineContext & {\n latestManifestString?: string;\n downloadedManifestString?: string;\n lastCheckForUpdateTimeString?: string;\n rollbackString?: string;\n }\n): UpdatesNativeStateMachineContext {\n const nativeContext = { ...originalNativeContext };\n if (nativeContext.latestManifestString) {\n nativeContext.latestManifest = JSON.parse(nativeContext.latestManifestString);\n delete nativeContext.latestManifestString;\n }\n if (nativeContext.downloadedManifestString) {\n nativeContext.downloadedManifest = JSON.parse(nativeContext.downloadedManifestString);\n delete nativeContext.downloadedManifestString;\n }\n if (nativeContext.lastCheckForUpdateTimeString) {\n nativeContext.lastCheckForUpdateTime = new Date(nativeContext.lastCheckForUpdateTimeString);\n delete nativeContext.lastCheckForUpdateTimeString;\n }\n if (nativeContext.rollbackString) {\n nativeContext.rollback = JSON.parse(nativeContext.rollbackString);\n delete nativeContext.rollbackString;\n }\n return nativeContext;\n}\n\n/**\n * @hidden\n */\nexport async function getNativeStateMachineContextAsync(): Promise<UpdatesNativeStateMachineContext> {\n const nativeContext = await ExpoUpdates.getNativeStateMachineContextAsync();\n return transformNativeStateMachineContext(nativeContext);\n}\n"]}
|
package/expo-updates-gradle-plugin/src/main/kotlin/expo/modules/updates/ExpoUpdatesPlugin.kt
CHANGED
|
@@ -10,11 +10,11 @@ import org.gradle.api.file.DirectoryProperty
|
|
|
10
10
|
import org.gradle.api.provider.ListProperty
|
|
11
11
|
import org.gradle.api.provider.Property
|
|
12
12
|
import org.gradle.api.tasks.Input
|
|
13
|
-
import org.gradle.api.tasks.Internal
|
|
14
13
|
import org.gradle.api.tasks.OutputDirectory
|
|
15
14
|
import org.gradle.api.tasks.TaskAction
|
|
16
15
|
import org.slf4j.LoggerFactory
|
|
17
16
|
import java.io.ByteArrayOutputStream
|
|
17
|
+
import java.io.File
|
|
18
18
|
import java.util.Locale
|
|
19
19
|
|
|
20
20
|
abstract class ExpoUpdatesPlugin : Plugin<Project> {
|
|
@@ -23,6 +23,7 @@ abstract class ExpoUpdatesPlugin : Plugin<Project> {
|
|
|
23
23
|
logger.warn("Stop expo-updates resource generation because ReactExtension is not registered")
|
|
24
24
|
return
|
|
25
25
|
}
|
|
26
|
+
val entryFile = detectedEntryFile(reactExtension)
|
|
26
27
|
val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java)
|
|
27
28
|
|
|
28
29
|
if (System.getenv("EX_UPDATES_NATIVE_DEBUG") == "1") {
|
|
@@ -33,14 +34,14 @@ abstract class ExpoUpdatesPlugin : Plugin<Project> {
|
|
|
33
34
|
androidComponents.onVariants(androidComponents.selector().all()) { variant ->
|
|
34
35
|
val targetName = variant.name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() }
|
|
35
36
|
val projectRoot = project.rootProject.projectDir.parentFile.toPath()
|
|
36
|
-
val
|
|
37
|
+
val entryFileRelativePath = projectRoot.relativize(entryFile.toPath())
|
|
37
38
|
val isDebuggableVariant =
|
|
38
39
|
reactExtension.debuggableVariants.get().any { it.equals(variant.name, ignoreCase = true) }
|
|
39
40
|
|
|
40
41
|
val createUpdatesResourcesTask = project.tasks.register("create${targetName}UpdatesResources", CreateUpdatesResourcesTask::class.java) {
|
|
41
42
|
it.description = "expo-updates: Create updates resources for ${targetName}."
|
|
42
43
|
it.projectRoot.set(projectRoot.toString())
|
|
43
|
-
it.entryFile.set(
|
|
44
|
+
it.entryFile.set(entryFileRelativePath.toString())
|
|
44
45
|
it.nodeExecutableAndArgs.set(reactExtension.nodeExecutableAndArgs.get())
|
|
45
46
|
it.enabled = !isDebuggableVariant
|
|
46
47
|
}
|
|
@@ -108,3 +109,18 @@ abstract class ExpoUpdatesPlugin : Plugin<Project> {
|
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Synced implementation from [RNGP](https://github.com/facebook/react-native/blob/9bdd777fd766ff/packages/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/utils/PathUtils.kt#L20-L33)
|
|
115
|
+
*/
|
|
116
|
+
private fun detectedEntryFile(config: ReactExtension): File {
|
|
117
|
+
val envVariableOverride = System.getenv("ENTRY_FILE") ?: null
|
|
118
|
+
val entryFile = config.entryFile.orNull?.asFile
|
|
119
|
+
val reactRoot = config.root.get().asFile
|
|
120
|
+
return when {
|
|
121
|
+
envVariableOverride != null -> File(reactRoot, envVariableOverride)
|
|
122
|
+
entryFile != null -> entryFile
|
|
123
|
+
File(reactRoot, "index.android.js").exists() -> File(reactRoot, "index.android.js")
|
|
124
|
+
else -> File(reactRoot, "index.js")
|
|
125
|
+
}
|
|
126
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-updates",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.7",
|
|
4
4
|
"description": "Fetches and manages remotely-hosted assets and updates to your app's JS bundle.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"peerDependencies": {
|
|
68
68
|
"expo": "*"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "71b2f4339ef7b5b42ce87c1d8c17fe41c60355e0"
|
|
71
71
|
}
|
package/src/Updates.ts
CHANGED
|
@@ -139,6 +139,8 @@ const manualUpdatesInstructions =
|
|
|
139
139
|
* Instructs the app to reload using the most recently downloaded version. This is useful for
|
|
140
140
|
* triggering a newly downloaded update to launch without the user needing to manually restart the
|
|
141
141
|
* app.
|
|
142
|
+
* Unlike `Expo.reloadAppAsync()` provided by the `expo` package,
|
|
143
|
+
* this function not only reloads the app but also changes the loaded JavaScript bundle to that of the most recently downloaded update.
|
|
142
144
|
*
|
|
143
145
|
* It is not recommended to place any meaningful logic after a call to `await
|
|
144
146
|
* Updates.reloadAsync()`. This is because the promise is resolved after verifying that the app can
|