expo-updates 0.18.0 → 0.18.2

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 CHANGED
@@ -10,6 +10,16 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 0.18.2 — 2023-06-23
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - [Android] fix instrumentation tests. ([#23037](https://github.com/expo/expo/pull/23037) by [@douglowder](https://github.com/douglowder))
18
+
19
+ ## 0.18.1 — 2023-06-22
20
+
21
+ _This version does not introduce any user-facing changes._
22
+
13
23
  ## 0.18.0 — 2023-06-22
14
24
 
15
25
  _This version does not introduce any user-facing changes._
@@ -4,7 +4,7 @@ apply plugin: 'kotlin-kapt'
4
4
  apply plugin: 'maven-publish'
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '0.18.0'
7
+ version = '0.18.2'
8
8
 
9
9
  def ex_updates_native_debug = System.getenv("EX_UPDATES_NATIVE_DEBUG") == "1" ? "true" : "false"
10
10
 
@@ -70,7 +70,7 @@ android {
70
70
  minSdkVersion safeExtGet("minSdkVersion", 21)
71
71
  targetSdkVersion safeExtGet("targetSdkVersion", 33)
72
72
  versionCode 31
73
- versionName '0.18.0'
73
+ versionName '0.18.2'
74
74
  consumerProguardFiles("proguard-rules.pro")
75
75
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
76
76
 
@@ -286,7 +286,7 @@ class UpdatesController private constructor(
286
286
  }
287
287
 
288
288
  override fun onRemoteCheckForUpdateFinished(result: LoaderTask.RemoteCheckResult) {
289
- var event = UpdatesStateEvent.CheckComplete()
289
+ var event: UpdatesStateEvent = UpdatesStateEvent.CheckCompleteUnavailable()
290
290
  if (result.manifest != null) {
291
291
  event = UpdatesStateEvent.CheckCompleteWithUpdate(
292
292
  result.manifest
@@ -378,7 +378,7 @@ class UpdatesController private constructor(
378
378
  params.putString("manifestString", update.manifest.toString())
379
379
  sendLegacyUpdateEventToJS(UPDATE_AVAILABLE_EVENT, params)
380
380
  stateMachine.processEvent(
381
- UpdatesStateEvent.DownloadCompleteWithUpdate(update.manifest)
381
+ UpdatesStateEvent.DownloadCompleteWithUpdate(update.manifest!!)
382
382
  )
383
383
  }
384
384
  RemoteUpdateStatus.NO_UPDATE_AVAILABLE -> {
@@ -10,6 +10,7 @@ import expo.modules.core.ModuleRegistryDelegate
10
10
  import expo.modules.core.Promise
11
11
  import expo.modules.core.interfaces.ExpoMethod
12
12
  import expo.modules.updates.db.entity.AssetEntity
13
+ import expo.modules.updates.db.entity.UpdateEntity
13
14
  import expo.modules.updates.launcher.Launcher.LauncherCallback
14
15
  import expo.modules.updates.loader.*
15
16
  import expo.modules.updates.loader.FileDownloader.RemoteUpdateDownloadCallback
@@ -23,7 +24,7 @@ import java.util.Date
23
24
 
24
25
  // these unused imports must stay because of versioning
25
26
  /* ktlint-disable no-unused-imports */
26
-
27
+ import expo.modules.updates.UpdatesConfiguration
27
28
  /* ktlint-enable no-unused-imports */
28
29
 
29
30
  /**
@@ -184,7 +185,7 @@ class UpdatesModule(
184
185
  updateInfo.putBoolean("isAvailable", false)
185
186
  promise.resolve(updateInfo)
186
187
  updatesServiceLocal.stateMachine?.processEvent(
187
- UpdatesStateEvent.CheckComplete()
188
+ UpdatesStateEvent.CheckCompleteUnavailable()
188
189
  )
189
190
  return
190
191
  }
@@ -222,7 +223,7 @@ class UpdatesModule(
222
223
  updateInfo.putBoolean("isAvailable", false)
223
224
  promise.resolve(updateInfo)
224
225
  updatesServiceLocal.stateMachine?.processEvent(
225
- UpdatesStateEvent.CheckComplete()
226
+ UpdatesStateEvent.CheckCompleteUnavailable()
226
227
  )
227
228
  }
228
229
  }
@@ -317,12 +318,18 @@ class UpdatesModule(
317
318
  } else {
318
319
  updatesServiceLocal.resetSelectionPolicy()
319
320
  updateInfo.putBoolean("isNew", true)
321
+
322
+ // We need the explicit casting here because when in versioned expo-updates,
323
+ // the UpdateEntity and UpdatesModule are in different package namespace,
324
+ // Kotlin cannot do the smart casting for that case.
325
+ val updateEntity = loaderResult.updateEntity as UpdateEntity
326
+
320
327
  updateInfo.putString(
321
328
  "manifestString",
322
- loaderResult.updateEntity.manifest.toString()
329
+ updateEntity.manifest.toString()
323
330
  )
324
331
  updatesServiceLocal.stateMachine?.processEvent(
325
- UpdatesStateEvent.DownloadCompleteWithUpdate(loaderResult.updateEntity.manifest)
332
+ UpdatesStateEvent.DownloadCompleteWithUpdate(updateEntity.manifest!!)
326
333
  )
327
334
  }
328
335
  }
@@ -105,15 +105,11 @@ class LegacyUpdateManifest private constructor(
105
105
  commitTime = Date()
106
106
  } else {
107
107
  id = UUID.fromString(manifest.getReleaseId())
108
- val commitTimeString = manifest.getCommitTime()
109
- commitTime = if (commitTimeString != null) {
110
- try {
111
- UpdatesUtils.parseDateString(commitTimeString)
112
- } catch (e: ParseException) {
113
- Log.e(TAG, "Could not parse commitTime", e)
114
- Date()
115
- }
116
- } else {
108
+ commitTime = try {
109
+ val commitTimeString = manifest.getCommitTime() ?: throw JSONException("missing commitTime")
110
+ UpdatesUtils.parseDateString(commitTimeString)
111
+ } catch (e: ParseException) {
112
+ Log.e(TAG, "Could not parse commitTime", e)
117
113
  Date()
118
114
  }
119
115
  }
@@ -5,50 +5,26 @@ import org.json.JSONObject
5
5
  /**
6
6
  Structure representing an event that can be sent to the machine.
7
7
  */
8
- data class UpdatesStateEvent(
9
- val type: UpdatesStateEventType,
10
- val manifest: JSONObject? = null,
11
- private val errorMessage: String? = null,
12
- val isRollback: Boolean = false
13
- ) {
14
- val error: UpdatesStateError?
15
- get() {
16
- return errorMessage?.let { UpdatesStateError(it) }
17
- }
18
-
19
- companion object {
20
- fun Check(): UpdatesStateEvent {
21
- return UpdatesStateEvent(UpdatesStateEventType.Check)
22
- }
23
- fun Download(): UpdatesStateEvent {
24
- return UpdatesStateEvent(UpdatesStateEventType.Download)
25
- }
26
- fun CheckError(message: String): UpdatesStateEvent {
27
- return UpdatesStateEvent(UpdatesStateEventType.CheckError, errorMessage = message)
28
- }
29
- fun DownloadError(message: String): UpdatesStateEvent {
30
- return UpdatesStateEvent(UpdatesStateEventType.DownloadError, errorMessage = message)
31
- }
32
- fun CheckComplete(): UpdatesStateEvent {
33
- return UpdatesStateEvent(UpdatesStateEventType.CheckCompleteUnavailable)
34
- }
35
- fun CheckCompleteWithUpdate(manifest: JSONObject?): UpdatesStateEvent {
36
- return UpdatesStateEvent(UpdatesStateEventType.CheckCompleteAvailable, manifest = manifest)
37
- }
38
- fun CheckCompleteWithRollback(): UpdatesStateEvent {
39
- return UpdatesStateEvent(UpdatesStateEventType.CheckCompleteAvailable, isRollback = true)
40
- }
41
- fun DownloadComplete(): UpdatesStateEvent {
42
- return UpdatesStateEvent(UpdatesStateEventType.DownloadComplete)
43
- }
44
- fun DownloadCompleteWithUpdate(manifest: JSONObject?): UpdatesStateEvent {
45
- return UpdatesStateEvent(UpdatesStateEventType.DownloadComplete, manifest = manifest)
46
- }
47
- fun DownloadCompleteWithRollback(): UpdatesStateEvent {
48
- return UpdatesStateEvent(UpdatesStateEventType.DownloadComplete, isRollback = true)
49
- }
50
- fun Restart(): UpdatesStateEvent {
51
- return UpdatesStateEvent(UpdatesStateEventType.Restart)
52
- }
8
+ sealed class UpdatesStateEvent(val type: UpdatesStateEventType) {
9
+ class Check : UpdatesStateEvent(UpdatesStateEventType.Check)
10
+ class Download : UpdatesStateEvent(UpdatesStateEventType.Download)
11
+ class CheckError(private val errorMessage: String) : UpdatesStateEvent(UpdatesStateEventType.CheckError) {
12
+ val error: UpdatesStateError
13
+ get() {
14
+ return UpdatesStateError(errorMessage)
15
+ }
16
+ }
17
+ class DownloadError(private val errorMessage: String) : UpdatesStateEvent(UpdatesStateEventType.DownloadError) {
18
+ val error: UpdatesStateError
19
+ get() {
20
+ return UpdatesStateError(errorMessage)
21
+ }
53
22
  }
23
+ class CheckCompleteUnavailable : UpdatesStateEvent(UpdatesStateEventType.CheckCompleteUnavailable)
24
+ class CheckCompleteWithUpdate(val manifest: JSONObject) : UpdatesStateEvent(UpdatesStateEventType.CheckCompleteAvailable)
25
+ class CheckCompleteWithRollback : UpdatesStateEvent(UpdatesStateEventType.CheckCompleteAvailable)
26
+ class DownloadComplete : UpdatesStateEvent(UpdatesStateEventType.DownloadComplete)
27
+ class DownloadCompleteWithUpdate(val manifest: JSONObject) : UpdatesStateEvent(UpdatesStateEventType.DownloadComplete)
28
+ class DownloadCompleteWithRollback : UpdatesStateEvent(UpdatesStateEventType.DownloadComplete)
29
+ class Restart : UpdatesStateEvent(UpdatesStateEventType.Restart)
54
30
  }
@@ -9,7 +9,7 @@ import expo.modules.updates.logging.UpdatesLogger
9
9
  */
10
10
  class UpdatesStateMachine(
11
11
  androidContext: Context,
12
- val changeEventSender: UpdatesStateChangeEventSender
12
+ private val changeEventSender: UpdatesStateChangeEventSender
13
13
  ) {
14
14
 
15
15
  private val logger = UpdatesLogger(androidContext)
@@ -32,7 +32,7 @@ class UpdatesStateMachine(
32
32
  state = UpdatesStateValue.Idle
33
33
  context = UpdatesStateContext()
34
34
  logger.info("Updates state change: reset, context = ${context.json}")
35
- sendChangeEventToJS()
35
+ sendChangeEventToJS(UpdatesStateEvent.Restart())
36
36
  }
37
37
 
38
38
  /**
@@ -61,15 +61,9 @@ class UpdatesStateMachine(
61
61
  return true
62
62
  }
63
63
 
64
- /**
65
- * If a state change event is passed in, the JS sender
66
- * is called with just the fields and values that changed.
67
- * During a reset, this method is called with no event passed in,
68
- * and then all the fields and the entire context are passed to the JS sender.
69
- */
70
- private fun sendChangeEventToJS(event: UpdatesStateEvent? = null) {
64
+ private fun sendChangeEventToJS(event: UpdatesStateEvent) {
71
65
  changeEventSender.sendUpdateStateChangeEventToBridge(
72
- event?.type ?: UpdatesStateEventType.Restart,
66
+ event.type,
73
67
  context.copy()
74
68
  )
75
69
  }
@@ -105,43 +99,57 @@ class UpdatesStateMachine(
105
99
  * made by processing the event.
106
100
  */
107
101
  private fun reduceContext(context: UpdatesStateContext, event: UpdatesStateEvent): UpdatesStateContext {
108
- return when (event.type) {
109
- UpdatesStateEventType.Check -> context.copy(isChecking = true)
110
- UpdatesStateEventType.CheckCompleteUnavailable -> context.copy(
102
+ return when (event) {
103
+ is UpdatesStateEvent.Check -> context.copy(isChecking = true)
104
+ is UpdatesStateEvent.CheckCompleteUnavailable -> context.copy(
111
105
  isChecking = false,
112
106
  checkError = null,
113
107
  latestManifest = null,
114
108
  isUpdateAvailable = false,
115
109
  isRollback = false
116
110
  )
117
- UpdatesStateEventType.CheckCompleteAvailable -> context.copy(
111
+ is UpdatesStateEvent.CheckCompleteWithRollback -> context.copy(
112
+ isChecking = false,
113
+ checkError = null,
114
+ latestManifest = null,
115
+ isUpdateAvailable = true,
116
+ isRollback = true
117
+ )
118
+ is UpdatesStateEvent.CheckCompleteWithUpdate -> context.copy(
118
119
  isChecking = false,
119
120
  checkError = null,
120
121
  latestManifest = event.manifest,
121
122
  isUpdateAvailable = true,
122
- isRollback = event.isRollback
123
+ isRollback = false
123
124
  )
124
- UpdatesStateEventType.CheckError -> context.copy(
125
+ is UpdatesStateEvent.CheckError -> context.copy(
125
126
  isChecking = false,
126
127
  checkError = event.error
127
128
  )
128
- UpdatesStateEventType.Download -> context.copy(isDownloading = true)
129
- UpdatesStateEventType.DownloadComplete -> context.copy(
129
+ is UpdatesStateEvent.Download -> context.copy(isDownloading = true)
130
+ is UpdatesStateEvent.DownloadComplete -> context.copy(
130
131
  isDownloading = false,
131
132
  downloadError = null,
132
- latestManifest = event.manifest ?: context.latestManifest,
133
- downloadedManifest = event.manifest ?: context.downloadedManifest,
134
133
  isUpdatePending = true,
135
- isUpdateAvailable = when (event.manifest) {
136
- null -> context.isUpdateAvailable
137
- else -> true
138
- }
139
134
  )
140
- UpdatesStateEventType.DownloadError -> context.copy(
135
+ is UpdatesStateEvent.DownloadCompleteWithRollback -> context.copy(
136
+ isDownloading = false,
137
+ downloadError = null,
138
+ isUpdatePending = true,
139
+ )
140
+ is UpdatesStateEvent.DownloadCompleteWithUpdate -> context.copy(
141
+ isDownloading = false,
142
+ downloadError = null,
143
+ latestManifest = event.manifest,
144
+ downloadedManifest = event.manifest,
145
+ isUpdatePending = true,
146
+ isUpdateAvailable = true
147
+ )
148
+ is UpdatesStateEvent.DownloadError -> context.copy(
141
149
  isDownloading = false,
142
150
  downloadError = event.error
143
151
  )
144
- UpdatesStateEventType.Restart -> context.copy(
152
+ is UpdatesStateEvent.Restart -> context.copy(
145
153
  isRestarting = true
146
154
  )
147
155
  }
@@ -20,6 +20,8 @@ public final class UpdatesModule: Module {
20
20
 
21
21
  public required init(appContext: AppContext) {
22
22
  updatesService = appContext.legacyModule(implementing: EXUpdatesModuleInterface.self)
23
+ // Ensures the universal UpdatesConfig can cast to versioned UpdatesConfig without exception in Swift
24
+ object_setClass(updatesService?.config, UpdatesConfig.self)
23
25
  super.init(appContext: appContext)
24
26
  }
25
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-updates",
3
- "version": "0.18.0",
3
+ "version": "0.18.2",
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",
@@ -65,5 +65,5 @@
65
65
  "peerDependencies": {
66
66
  "expo": "*"
67
67
  },
68
- "gitHead": "e2e2d23c044f4d0ded6d82ea7d93ff5e725c8a2e"
68
+ "gitHead": "a72ae33519fe54eaf195dc3e61a49db8345103db"
69
69
  }