expo-updates 55.0.2 → 55.0.3
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 +4 -1
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/updates/DisabledUpdatesController.kt +1 -13
- package/android/src/main/java/expo/modules/updates/EnabledUpdatesController.kt +3 -21
- package/android/src/main/java/expo/modules/updates/UpdatesController.kt +2 -4
- package/android/src/main/java/expo/modules/updates/UpdatesDevLauncherController.kt +5 -11
- package/android/src/main/java/expo/modules/updates/statemachine/UpdatesStateMachine.kt +0 -23
- package/ios/EXUpdates/AppController.swift +1 -4
- package/ios/EXUpdates/AppLoader/FileDownloader.swift +1 -10
- package/ios/EXUpdates/AppLoader/RemoteAppLoader.swift +0 -4
- package/ios/EXUpdates/BSPatch.swift +4 -5
- package/ios/EXUpdates/DevLauncherAppController.swift +4 -14
- package/ios/EXUpdates/DisabledAppController.swift +1 -22
- package/ios/EXUpdates/EnabledAppController.swift +3 -34
- package/ios/EXUpdates/Multipart/UpdatesMultipartStreamReader.swift +0 -2
- package/ios/EXUpdates/UpdatesStateMachine.swift +0 -26
- package/package.json +5 -5
- package/android/src/main/java/expo/modules/updates/UpdatesStateChangeSubscription.kt +0 -14
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 55.0.3 — 2026-01-22
|
|
14
|
+
|
|
15
|
+
_This version does not introduce any user-facing changes._
|
|
16
|
+
|
|
13
17
|
## 55.0.2 — 2026-01-22
|
|
14
18
|
|
|
15
19
|
### 🐛 Bug fixes
|
|
@@ -26,7 +30,6 @@ _This version does not introduce any user-facing changes._
|
|
|
26
30
|
|
|
27
31
|
- Remove `ExpoAppDelegate` inheritance requirement ([#39417](https://github.com/expo/expo/pull/39417) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
28
32
|
- Add patch content negotiation headers. ([#40583](https://github.com/expo/expo/pull/40583) by [@alanjhughes](https://github.com/alanjhughes))
|
|
29
|
-
- Full native interface for updates. ([#41527](https://github.com/expo/expo/pull/41527) by [@douglowder](https://github.com/douglowder))
|
|
30
33
|
|
|
31
34
|
### 🐛 Bug fixes
|
|
32
35
|
|
package/android/build.gradle
CHANGED
|
@@ -42,7 +42,7 @@ expoModule {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
group = 'host.exp.exponent'
|
|
45
|
-
version = '55.0.
|
|
45
|
+
version = '55.0.3'
|
|
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
|
|
@@ -89,7 +89,7 @@ android {
|
|
|
89
89
|
namespace "expo.modules.updates"
|
|
90
90
|
defaultConfig {
|
|
91
91
|
versionCode 31
|
|
92
|
-
versionName '55.0.
|
|
92
|
+
versionName '55.0.3'
|
|
93
93
|
consumerProguardFiles("proguard-rules.pro")
|
|
94
94
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
95
95
|
|
|
@@ -2,7 +2,6 @@ package expo.modules.updates
|
|
|
2
2
|
|
|
3
3
|
import android.app.Activity
|
|
4
4
|
import android.content.Context
|
|
5
|
-
import android.net.Uri
|
|
6
5
|
import android.os.Bundle
|
|
7
6
|
import com.facebook.react.bridge.ReactContext
|
|
8
7
|
import com.facebook.react.devsupport.interfaces.DevSupportManager
|
|
@@ -17,9 +16,6 @@ import expo.modules.updates.procedures.RecreateReactContextProcedure
|
|
|
17
16
|
import expo.modules.updates.reloadscreen.ReloadScreenManager
|
|
18
17
|
import expo.modules.updates.statemachine.UpdatesStateMachine
|
|
19
18
|
import expo.modules.updates.statemachine.UpdatesStateValue
|
|
20
|
-
import expo.modules.updatesinterface.UpdatesInterface
|
|
21
|
-
import expo.modules.updatesinterface.UpdatesStateChangeListener
|
|
22
|
-
import expo.modules.updatesinterface.UpdatesStateChangeSubscription
|
|
23
19
|
import kotlinx.coroutines.CompletableDeferred
|
|
24
20
|
import kotlinx.coroutines.CoroutineScope
|
|
25
21
|
import kotlinx.coroutines.Dispatchers
|
|
@@ -47,7 +43,7 @@ import kotlin.time.toDuration
|
|
|
47
43
|
class DisabledUpdatesController(
|
|
48
44
|
private val context: Context,
|
|
49
45
|
private val fatalException: Exception?
|
|
50
|
-
) : IUpdatesController
|
|
46
|
+
) : IUpdatesController {
|
|
51
47
|
/** Keep the activity for [RecreateReactContextProcedure] to relaunch the app. */
|
|
52
48
|
private var weakActivity: WeakReference<Activity>? = null
|
|
53
49
|
private val controllerScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
|
@@ -199,14 +195,6 @@ class DisabledUpdatesController(
|
|
|
199
195
|
controllerScope.cancel()
|
|
200
196
|
}
|
|
201
197
|
|
|
202
|
-
override val runtimeVersion: String? = null
|
|
203
|
-
|
|
204
|
-
override val updateUrl: Uri? = null
|
|
205
|
-
|
|
206
|
-
override fun subscribeToUpdatesStateChanges(listener: UpdatesStateChangeListener): UpdatesStateChangeSubscription {
|
|
207
|
-
return DisabledUpdatesStateChangeSubscription()
|
|
208
|
-
}
|
|
209
|
-
|
|
210
198
|
companion object {
|
|
211
199
|
private val TAG = DisabledUpdatesController::class.java.simpleName
|
|
212
200
|
}
|
|
@@ -31,9 +31,7 @@ import expo.modules.updates.selectionpolicy.SelectionPolicy
|
|
|
31
31
|
import expo.modules.updates.selectionpolicy.SelectionPolicyFactory
|
|
32
32
|
import expo.modules.updates.statemachine.UpdatesStateMachine
|
|
33
33
|
import expo.modules.updates.statemachine.UpdatesStateValue
|
|
34
|
-
import expo.modules.updatesinterface.
|
|
35
|
-
import expo.modules.updatesinterface.UpdatesStateChangeListener
|
|
36
|
-
import expo.modules.updatesinterface.UpdatesStateChangeSubscription
|
|
34
|
+
import expo.modules.updatesinterface.UpdatesMetricsInterface
|
|
37
35
|
import kotlinx.coroutines.CompletableDeferred
|
|
38
36
|
import kotlinx.coroutines.CoroutineScope
|
|
39
37
|
import kotlinx.coroutines.Dispatchers
|
|
@@ -59,7 +57,7 @@ class EnabledUpdatesController(
|
|
|
59
57
|
private val context: Context,
|
|
60
58
|
private var updatesConfiguration: UpdatesConfiguration,
|
|
61
59
|
override val updatesDirectory: File
|
|
62
|
-
) : IUpdatesController,
|
|
60
|
+
) : IUpdatesController, UpdatesMetricsInterface {
|
|
63
61
|
/** Keep the activity for [RelaunchProcedure] to relaunch the app. */
|
|
64
62
|
private var weakActivity: WeakReference<Activity>? = null
|
|
65
63
|
private val logger = UpdatesLogger(context.filesDir)
|
|
@@ -82,8 +80,6 @@ class EnabledUpdatesController(
|
|
|
82
80
|
private val startupFinishedMutex = Mutex()
|
|
83
81
|
override val reloadScreenManager = ReloadScreenManager()
|
|
84
82
|
|
|
85
|
-
internal val stateChangeListenerMap: MutableMap<String, UpdatesStateChangeListener> = mutableMapOf()
|
|
86
|
-
|
|
87
83
|
private fun purgeUpdatesLogsOlderThanOneDay() {
|
|
88
84
|
UpdatesLogReader(context.filesDir).purgeLogEntries {
|
|
89
85
|
if (it != null) {
|
|
@@ -324,7 +320,7 @@ class EnabledUpdatesController(
|
|
|
324
320
|
updatesConfiguration = UpdatesConfiguration.create(context, updatesConfiguration, configOverride)
|
|
325
321
|
}
|
|
326
322
|
|
|
327
|
-
//
|
|
323
|
+
// UpdatesMetricsInterface implementations
|
|
328
324
|
|
|
329
325
|
override val runtimeVersion: String?
|
|
330
326
|
get() = updatesConfiguration.runtimeVersionRaw
|
|
@@ -338,20 +334,6 @@ class EnabledUpdatesController(
|
|
|
338
334
|
override val embeddedUpdateId: UUID?
|
|
339
335
|
get() = getEmbeddedUpdate()?.id
|
|
340
336
|
|
|
341
|
-
override fun subscribeToUpdatesStateChanges(listener: UpdatesStateChangeListener): UpdatesStateChangeSubscription {
|
|
342
|
-
val subscriptionId = UUID.randomUUID().toString()
|
|
343
|
-
stateChangeListenerMap[subscriptionId] = listener
|
|
344
|
-
return EnabledUpdatesStateChangeSubscription(subscriptionId = subscriptionId)
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
fun unsubscribeFromUpdatesStateChanges(subscriptionId: String) {
|
|
348
|
-
if (stateChangeListenerMap.containsKey(subscriptionId)) {
|
|
349
|
-
stateChangeListenerMap.remove(subscriptionId)
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
override val isEnabled: Boolean = true
|
|
354
|
-
|
|
355
337
|
companion object {
|
|
356
338
|
private val TAG = EnabledUpdatesController::class.java.simpleName
|
|
357
339
|
}
|
|
@@ -87,12 +87,10 @@ object UpdatesController {
|
|
|
87
87
|
|
|
88
88
|
singletonInstance = if (updatesConfiguration != null) {
|
|
89
89
|
val enabledUpdatesController = EnabledUpdatesController(context, updatesConfiguration, updatesDirectory)
|
|
90
|
-
UpdatesControllerRegistry.
|
|
90
|
+
UpdatesControllerRegistry.metricsController = WeakReference(enabledUpdatesController)
|
|
91
91
|
enabledUpdatesController
|
|
92
92
|
} else {
|
|
93
|
-
|
|
94
|
-
UpdatesControllerRegistry.controller = WeakReference(disabledUpdatesController)
|
|
95
|
-
disabledUpdatesController
|
|
93
|
+
DisabledUpdatesController(context, null)
|
|
96
94
|
}
|
|
97
95
|
}
|
|
98
96
|
|
|
@@ -29,10 +29,8 @@ import expo.modules.updates.selectionpolicy.ReaperSelectionPolicyDevelopmentClie
|
|
|
29
29
|
import expo.modules.updates.selectionpolicy.ReaperSelectionPolicyFilterAware
|
|
30
30
|
import expo.modules.updates.selectionpolicy.SelectionPolicy
|
|
31
31
|
import expo.modules.updates.statemachine.UpdatesStateContext
|
|
32
|
-
import expo.modules.updatesinterface.
|
|
32
|
+
import expo.modules.updatesinterface.UpdatesInterface
|
|
33
33
|
import expo.modules.updatesinterface.UpdatesInterfaceCallbacks
|
|
34
|
-
import expo.modules.updatesinterface.UpdatesStateChangeListener
|
|
35
|
-
import expo.modules.updatesinterface.UpdatesStateChangeSubscription
|
|
36
34
|
import kotlinx.coroutines.CoroutineScope
|
|
37
35
|
import kotlinx.coroutines.Dispatchers
|
|
38
36
|
import kotlinx.coroutines.SupervisorJob
|
|
@@ -58,7 +56,7 @@ class UpdatesDevLauncherController(
|
|
|
58
56
|
initialUpdatesConfiguration: UpdatesConfiguration?,
|
|
59
57
|
override val updatesDirectory: File?,
|
|
60
58
|
private val updatesDirectoryException: Exception?
|
|
61
|
-
) : IUpdatesController,
|
|
59
|
+
) : IUpdatesController, UpdatesInterface {
|
|
62
60
|
override val eventManager = NoOpUpdatesEventManager()
|
|
63
61
|
override var updatesInterfaceCallbacks: WeakReference<UpdatesInterfaceCallbacks>? = null
|
|
64
62
|
|
|
@@ -140,17 +138,13 @@ class UpdatesDevLauncherController(
|
|
|
140
138
|
override val updateUrl: Uri?
|
|
141
139
|
get() = updatesConfiguration?.updateUrl
|
|
142
140
|
|
|
143
|
-
override fun subscribeToUpdatesStateChanges(listener: UpdatesStateChangeListener): UpdatesStateChangeSubscription {
|
|
144
|
-
return DisabledUpdatesStateChangeSubscription()
|
|
145
|
-
}
|
|
146
|
-
|
|
147
141
|
/**
|
|
148
142
|
* Fetch an update using a dynamically generated configuration object (including a potentially
|
|
149
143
|
* different update URL than the one embedded in the build).
|
|
150
144
|
*/
|
|
151
145
|
override fun fetchUpdateWithConfiguration(
|
|
152
146
|
configuration: HashMap<String, Any>,
|
|
153
|
-
callback:
|
|
147
|
+
callback: UpdatesInterface.UpdateCallback
|
|
154
148
|
) {
|
|
155
149
|
val newUpdatesConfiguration: UpdatesConfiguration
|
|
156
150
|
try {
|
|
@@ -272,7 +266,7 @@ class UpdatesDevLauncherController(
|
|
|
272
266
|
update: UpdateEntity,
|
|
273
267
|
configuration: UpdatesConfiguration,
|
|
274
268
|
fileDownloader: FileDownloader,
|
|
275
|
-
callback:
|
|
269
|
+
callback: UpdatesInterface.UpdateCallback
|
|
276
270
|
) {
|
|
277
271
|
// ensure that we launch the update we want, even if it isn't the latest one
|
|
278
272
|
val currentSelectionPolicy = selectionPolicy
|
|
@@ -300,7 +294,7 @@ class UpdatesDevLauncherController(
|
|
|
300
294
|
try {
|
|
301
295
|
launcher.launch(databaseHolder.database)
|
|
302
296
|
this@UpdatesDevLauncherController.launcher = launcher
|
|
303
|
-
callback.onSuccess(object :
|
|
297
|
+
callback.onSuccess(object : UpdatesInterface.Update {
|
|
304
298
|
override val manifest: JSONObject
|
|
305
299
|
get() = launcher.launchedUpdate!!.manifest
|
|
306
300
|
override val launchAssetPath: String
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
package expo.modules.updates.statemachine
|
|
2
2
|
|
|
3
|
-
import expo.modules.manifests.core.toMap
|
|
4
|
-
import expo.modules.updates.EnabledUpdatesController
|
|
5
3
|
import expo.modules.updates.events.IUpdatesEventManager
|
|
6
4
|
import expo.modules.updates.logging.UpdatesLogger
|
|
7
5
|
import expo.modules.updates.procedures.StateMachineProcedure
|
|
8
6
|
import expo.modules.updates.procedures.StateMachineSerialExecutorQueue
|
|
9
|
-
import expo.modules.updatesinterface.UpdatesControllerRegistry
|
|
10
7
|
import kotlinx.coroutines.CoroutineScope
|
|
11
8
|
import kotlinx.coroutines.Dispatchers
|
|
12
9
|
import java.util.Date
|
|
@@ -68,18 +65,6 @@ class UpdatesStateMachine(
|
|
|
68
65
|
sendContextToJS()
|
|
69
66
|
}
|
|
70
67
|
|
|
71
|
-
private fun toMap(event: UpdatesStateEvent): Map<String, Any> {
|
|
72
|
-
return when (event) {
|
|
73
|
-
is UpdatesStateEvent.DownloadCompleteWithUpdate -> mapOf("type" to event.type.type, "manifest" to event.manifest.toMap())
|
|
74
|
-
is UpdatesStateEvent.CheckCompleteWithUpdate -> mapOf("type" to "checkCompleteWithUpdate", "manifest" to event.manifest.toMap())
|
|
75
|
-
is UpdatesStateEvent.CheckCompleteWithRollback -> mapOf("type" to "checkCompleteWithRollback")
|
|
76
|
-
is UpdatesStateEvent.CheckError -> mapOf("type" to event.type.type, "errorMessage" to event.error.message)
|
|
77
|
-
is UpdatesStateEvent.DownloadError -> mapOf("type" to event.type.type, "errorMessage" to event.error.message)
|
|
78
|
-
is UpdatesStateEvent.DownloadProgress -> mapOf("type" to event.type.type, "progress" to event.progress)
|
|
79
|
-
else -> mapOf("type" to event.type.type)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
68
|
/**
|
|
84
69
|
* Transition the state machine forward to a new state.
|
|
85
70
|
*/
|
|
@@ -89,14 +74,6 @@ class UpdatesStateMachine(
|
|
|
89
74
|
if (event !is UpdatesStateEvent.DownloadProgress) {
|
|
90
75
|
logger.info("Updates state change: ${event.type}, context = ${context.json}")
|
|
91
76
|
}
|
|
92
|
-
UpdatesControllerRegistry.controller?.get()?.let {
|
|
93
|
-
if (it is EnabledUpdatesController) {
|
|
94
|
-
// Notify the controller state change listener
|
|
95
|
-
it.stateChangeListenerMap.keys.forEach { key ->
|
|
96
|
-
it.stateChangeListenerMap[key]?.updatesStateDidChange(toMap(event))
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
77
|
sendContextToJS()
|
|
101
78
|
}
|
|
102
79
|
}
|
|
@@ -219,10 +219,9 @@ public class AppController: NSObject {
|
|
|
219
219
|
// which expo-dev-client can access.
|
|
220
220
|
let devLauncherController = initializeAsDevLauncherWithoutStarting()
|
|
221
221
|
_sharedInstance = devLauncherController
|
|
222
|
-
UpdatesControllerRegistry.sharedInstance.controller = devLauncherController
|
|
222
|
+
UpdatesControllerRegistry.sharedInstance.controller = devLauncherController
|
|
223
223
|
#else
|
|
224
224
|
_sharedInstance = DisabledAppController(error: nil)
|
|
225
|
-
UpdatesControllerRegistry.sharedInstance.controller = _sharedInstance as? (any UpdatesInterface)
|
|
226
225
|
#endif
|
|
227
226
|
return
|
|
228
227
|
}
|
|
@@ -274,7 +273,6 @@ public class AppController: NSObject {
|
|
|
274
273
|
let directory = try initializeUpdatesDirectory()
|
|
275
274
|
try initializeUpdatesDatabase(updatesDatabase: updatesDatabase, inUpdatesDirectory: directory, logger: logger)
|
|
276
275
|
_sharedInstance = EnabledAppController(config: config, database: updatesDatabase, updatesDirectory: directory)
|
|
277
|
-
UpdatesControllerRegistry.sharedInstance.controller = _sharedInstance as? (any UpdatesInterface)
|
|
278
276
|
} catch {
|
|
279
277
|
let cause = UpdatesError.appControllerInitializationError(cause: error)
|
|
280
278
|
logger.error(
|
|
@@ -282,7 +280,6 @@ public class AppController: NSObject {
|
|
|
282
280
|
code: .initializationError
|
|
283
281
|
)
|
|
284
282
|
_sharedInstance = DisabledAppController(error: cause)
|
|
285
|
-
UpdatesControllerRegistry.sharedInstance.controller = _sharedInstance as? (any UpdatesInterface)
|
|
286
283
|
return
|
|
287
284
|
}
|
|
288
285
|
} else {
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
// Copyright © 2019 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
|
-
// swiftlint:disable file_length
|
|
4
3
|
// swiftlint:disable force_cast
|
|
5
4
|
// swiftlint:disable function_parameter_count
|
|
6
5
|
// swiftlint:disable implicitly_unwrapped_optional
|
|
7
6
|
// swiftlint:disable identifier_name
|
|
8
7
|
// swiftlint:disable legacy_objc_type
|
|
9
|
-
// swiftlint:disable closure_body_length
|
|
10
|
-
// swiftlint:disable type_body_length
|
|
11
|
-
// swiftlint:disable force_unwrapping
|
|
12
|
-
// swiftlint:disable no_grouping_extension
|
|
13
8
|
|
|
14
9
|
import Foundation
|
|
15
10
|
import EASClient
|
|
@@ -74,6 +69,7 @@ public final class FileDownloader {
|
|
|
74
69
|
private static let IMHeader = "im"
|
|
75
70
|
private static let ExpoBaseUpdateIdResponseHeader = "expo-base-update-id"
|
|
76
71
|
|
|
72
|
+
// swiftlint:disable:next force_unwrapping
|
|
77
73
|
private static let ParameterParserSemicolonDelimiter = ";".utf16.first!
|
|
78
74
|
|
|
79
75
|
// these can be made non-forced lets when NSObject protocol is removed
|
|
@@ -1292,8 +1288,3 @@ extension FileDownloader.DiffError: CustomStringConvertible {
|
|
|
1292
1288
|
// swiftlint:enable implicitly_unwrapped_optional
|
|
1293
1289
|
// swiftlint:enable identifier_name
|
|
1294
1290
|
// swiftlint:enable legacy_objc_type
|
|
1295
|
-
// swiftlint:enable closure_body_length
|
|
1296
|
-
// swiftlint:enable type_body_length
|
|
1297
|
-
// swiftlint:enable force_unwrapping
|
|
1298
|
-
// swiftlint:enable no_grouping_extension
|
|
1299
|
-
// swiftlint:enable file_length
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Copyright © 2019 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
3
|
// swiftlint:disable function_parameter_count
|
|
4
|
-
// swiftlint:disable closure_body_length
|
|
5
4
|
|
|
6
5
|
import Foundation
|
|
7
6
|
|
|
@@ -133,9 +132,7 @@ public final class RemoteAppLoader: AppLoader {
|
|
|
133
132
|
let canApplyPatch = asset.isLaunchAsset &&
|
|
134
133
|
self.launchedUpdate != nil &&
|
|
135
134
|
self.requestedUpdate != nil &&
|
|
136
|
-
// swiftlint:disable force_unwrapping
|
|
137
135
|
self.launchedUpdate!.updateId != self.requestedUpdate!.updateId
|
|
138
|
-
// swiftlint:enable force_unwrapping
|
|
139
136
|
|
|
140
137
|
self.downloader.downloadAsset(
|
|
141
138
|
asset: asset,
|
|
@@ -270,4 +267,3 @@ public final class RemoteAppLoader: AppLoader {
|
|
|
270
267
|
}
|
|
271
268
|
|
|
272
269
|
// swiftlint:enable function_parameter_count
|
|
273
|
-
// swiftlint:enable closure_body_length
|
|
@@ -7,11 +7,10 @@ enum BSPatchError: Error {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
struct BSPatch {
|
|
10
|
-
static func applyPatch(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
) throws {
|
|
10
|
+
static func applyPatch(oldPath: String,
|
|
11
|
+
newPath: String,
|
|
12
|
+
patchPath: String) throws {
|
|
13
|
+
|
|
15
14
|
guard let oldPath = oldPath.cString(using: .utf8),
|
|
16
15
|
let newPath = newPath.cString(using: .utf8),
|
|
17
16
|
let patchPath = patchPath.cString(using: .utf8) else {
|
|
@@ -45,24 +45,14 @@ enum DevLauncherAppControllerError: Int, Error, LocalizedError {
|
|
|
45
45
|
*/
|
|
46
46
|
@objc(EXUpdatesDevLauncherController)
|
|
47
47
|
@objcMembers
|
|
48
|
-
public final class DevLauncherAppController: NSObject, InternalAppControllerInterface,
|
|
49
|
-
public func subscribeToUpdatesStateChanges(_ listener: any UpdatesStateChangeListener) -> UpdatesStateChangeSubscription {
|
|
50
|
-
return DisabledUpdatesStateChangeSubscription()
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public var launchedUpdateId: UUID?
|
|
54
|
-
|
|
55
|
-
public var embeddedUpdateId: UUID?
|
|
56
|
-
|
|
57
|
-
public var isEnabled: Bool
|
|
58
|
-
|
|
48
|
+
public final class DevLauncherAppController: NSObject, InternalAppControllerInterface, UpdatesExternalInterface {
|
|
59
49
|
public let eventManager: UpdatesEventManager = NoOpUpdatesEventManager()
|
|
60
50
|
public var reloadScreenManager: Reloadable? = ReloadScreenManager()
|
|
61
51
|
|
|
62
52
|
private let logger = UpdatesLogger()
|
|
63
53
|
|
|
64
|
-
public var delegate: AppControllerDelegate?
|
|
65
|
-
public var updatesExternalInterfaceDelegate: (any UpdatesExternalInterfaceDelegate)?
|
|
54
|
+
public weak var delegate: AppControllerDelegate?
|
|
55
|
+
public weak var updatesExternalInterfaceDelegate: (any EXUpdatesInterface.UpdatesExternalInterfaceDelegate)?
|
|
66
56
|
|
|
67
57
|
public func launchAssetUrl() -> URL? {
|
|
68
58
|
return launcher?.launchAssetUrl
|
|
@@ -117,7 +107,7 @@ public final class DevLauncherAppController: NSObject, InternalAppControllerInte
|
|
|
117
107
|
loaderSelectionPolicy: LoaderSelectionPolicyDevelopmentClient(config: self.config),
|
|
118
108
|
reaperSelectionPolicy: ReaperSelectionPolicyDevelopmentClient()
|
|
119
109
|
)
|
|
120
|
-
|
|
110
|
+
|
|
121
111
|
super.init()
|
|
122
112
|
}
|
|
123
113
|
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
// Copyright © 2019 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
3
|
import ExpoModulesCore
|
|
4
|
-
import EXUpdatesInterface
|
|
5
|
-
|
|
6
|
-
internal class DisabledUpdatesStateChangeSubscription: UpdatesStateChangeSubscription {
|
|
7
|
-
func remove() {}
|
|
8
|
-
}
|
|
9
4
|
|
|
10
5
|
/**
|
|
11
6
|
* Updates controller for applications that either disable updates explicitly or have an error
|
|
@@ -14,15 +9,7 @@ internal class DisabledUpdatesStateChangeSubscription: UpdatesStateChangeSubscri
|
|
|
14
9
|
* - Internal database initialization errors
|
|
15
10
|
* - Configuration errors (missing required configuration)
|
|
16
11
|
*/
|
|
17
|
-
public class DisabledAppController: InternalAppControllerInterface
|
|
18
|
-
public func subscribeToUpdatesStateChanges(_ listener: any UpdatesStateChangeListener) -> UpdatesStateChangeSubscription {
|
|
19
|
-
return DisabledUpdatesStateChangeSubscription()
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
public var launchedUpdateId: UUID?
|
|
23
|
-
|
|
24
|
-
public var embeddedUpdateId: UUID?
|
|
25
|
-
|
|
12
|
+
public class DisabledAppController: InternalAppControllerInterface {
|
|
26
13
|
public var reloadScreenManager: Reloadable?
|
|
27
14
|
|
|
28
15
|
public let isActiveController = false
|
|
@@ -115,14 +102,6 @@ public class DisabledAppController: InternalAppControllerInterface, UpdatesInter
|
|
|
115
102
|
)
|
|
116
103
|
}
|
|
117
104
|
|
|
118
|
-
// MARK: UpdatesInterface
|
|
119
|
-
|
|
120
|
-
public var runtimeVersion: String?
|
|
121
|
-
|
|
122
|
-
public var updateURL: URL?
|
|
123
|
-
|
|
124
|
-
public var isEnabled: Bool = false
|
|
125
|
-
|
|
126
105
|
public func requestRelaunch(
|
|
127
106
|
success successBlockArg: @escaping () -> Void,
|
|
128
107
|
error errorBlockArg: @escaping (ExpoModulesCore.Exception) -> Void
|
|
@@ -4,24 +4,10 @@ import SwiftUI
|
|
|
4
4
|
import ExpoModulesCore
|
|
5
5
|
import EXUpdatesInterface
|
|
6
6
|
|
|
7
|
-
internal class EnabledUpdatesStateChangeSubscription: UpdatesStateChangeSubscription {
|
|
8
|
-
private let subscriptionId: String
|
|
9
|
-
|
|
10
|
-
required init(_ subscriptionId: String) {
|
|
11
|
-
self.subscriptionId = subscriptionId
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
func remove() {
|
|
15
|
-
if let updatesController = AppController.sharedInstance as? EnabledAppController {
|
|
16
|
-
updatesController.unsubscribeFromUpdatesStateChanges(subscriptionId)
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
7
|
/**
|
|
22
8
|
* Updates controller for applications that have updates enabled and properly-configured.
|
|
23
9
|
*/
|
|
24
|
-
public class EnabledAppController: InternalAppControllerInterface,
|
|
10
|
+
public class EnabledAppController: InternalAppControllerInterface, UpdatesExternalMetricsInterface, StartupProcedureDelegate {
|
|
25
11
|
public weak var delegate: AppControllerDelegate?
|
|
26
12
|
public var reloadScreenManager: Reloadable? = ReloadScreenManager()
|
|
27
13
|
|
|
@@ -73,6 +59,7 @@ public class EnabledAppController: InternalAppControllerInterface, UpdatesInterf
|
|
|
73
59
|
self.logger.info(message: "AppController sharedInstance created")
|
|
74
60
|
self.eventManager = QueueUpdatesEventManager(logger: logger)
|
|
75
61
|
self.stateMachine = UpdatesStateMachine(logger: self.logger, eventManager: self.eventManager, validUpdatesStateValues: Set(UpdatesStateValue.allCases))
|
|
62
|
+
UpdatesControllerRegistry.sharedInstance.metricsController = self
|
|
76
63
|
}
|
|
77
64
|
|
|
78
65
|
public func start() {
|
|
@@ -172,23 +159,7 @@ public class EnabledAppController: InternalAppControllerInterface, UpdatesInterf
|
|
|
172
159
|
stateMachine.queueExecution(stateMachineProcedure: procedure)
|
|
173
160
|
}
|
|
174
161
|
|
|
175
|
-
// MARK: -
|
|
176
|
-
|
|
177
|
-
internal var stateChangeListeners: [String: any UpdatesStateChangeListener] = [:]
|
|
178
|
-
|
|
179
|
-
public func subscribeToUpdatesStateChanges(_ listener: any UpdatesStateChangeListener) -> UpdatesStateChangeSubscription {
|
|
180
|
-
let subscriptionId = UUID().uuidString
|
|
181
|
-
let subscription = EnabledUpdatesStateChangeSubscription(subscriptionId)
|
|
182
|
-
|
|
183
|
-
stateChangeListeners[subscriptionId] = listener
|
|
184
|
-
return subscription
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
internal func unsubscribeFromUpdatesStateChanges(_ subscriptionId: String) {
|
|
188
|
-
if stateChangeListeners[subscriptionId] != nil {
|
|
189
|
-
stateChangeListeners.removeValue(forKey: subscriptionId)
|
|
190
|
-
}
|
|
191
|
-
}
|
|
162
|
+
// MARK: - UpdatesExternalMetricsInterface
|
|
192
163
|
|
|
193
164
|
public var runtimeVersion: String? {
|
|
194
165
|
return config.runtimeVersion
|
|
@@ -206,8 +177,6 @@ public class EnabledAppController: InternalAppControllerInterface, UpdatesInterf
|
|
|
206
177
|
return getEmbeddedUpdate()?.updateId
|
|
207
178
|
}
|
|
208
179
|
|
|
209
|
-
public var isEnabled: Bool = true
|
|
210
|
-
|
|
211
180
|
// MARK: - Internal
|
|
212
181
|
|
|
213
182
|
private func purgeUpdatesLogsOlderThanOneDay() {
|
|
@@ -162,10 +162,8 @@ public final class UpdatesMultipartStreamReader {
|
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
// swiftlint:disable legacy_objc_type
|
|
166
165
|
private extension Data {
|
|
167
166
|
func range(of data: Data, options: Data.SearchOptions = [], in range: NSRange) -> NSRange {
|
|
168
167
|
return (self as NSData).range(of: data, options: options, in: range)
|
|
169
168
|
}
|
|
170
169
|
}
|
|
171
|
-
// swiftlint:enable legacy_objc_type
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
// swiftlint:disable no_grouping_extension
|
|
4
4
|
|
|
5
5
|
import Foundation
|
|
6
|
-
import EXUpdatesInterface
|
|
7
6
|
|
|
8
7
|
// MARK: - Enums
|
|
9
8
|
|
|
@@ -85,23 +84,6 @@ internal enum UpdatesStateEvent {
|
|
|
85
84
|
return .restart
|
|
86
85
|
}
|
|
87
86
|
}
|
|
88
|
-
|
|
89
|
-
var toMap: [String: Any] {
|
|
90
|
-
switch self {
|
|
91
|
-
case .checkCompleteWithUpdate(manifest: let manifest):
|
|
92
|
-
return ["type": "checkCompleteWithUpdate", "manifest": manifest]
|
|
93
|
-
case .downloadCompleteWithUpdate(manifest: let manifest):
|
|
94
|
-
return ["type": "downloadCompleteWithUpdate", "manifest": manifest]
|
|
95
|
-
case .checkError(errorMessage: let errorMessage):
|
|
96
|
-
return ["type": type, "errorMessage": errorMessage]
|
|
97
|
-
case .downloadError(errorMessage: let errorMessage):
|
|
98
|
-
return ["type": type, "errorMessage": errorMessage]
|
|
99
|
-
case .downloadProgress(progress: let progress):
|
|
100
|
-
return ["type": type, "progress": progress]
|
|
101
|
-
default:
|
|
102
|
-
return ["type": type]
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
87
|
}
|
|
106
88
|
|
|
107
89
|
/**
|
|
@@ -337,14 +319,6 @@ internal class UpdatesStateMachine {
|
|
|
337
319
|
if event.type != .downloadProgress {
|
|
338
320
|
logger.info(message: "Updates state change: state = \(state), event = \(event.type), context = \(context)")
|
|
339
321
|
}
|
|
340
|
-
// Notify the controller state change listener
|
|
341
|
-
if let controller = UpdatesControllerRegistry.sharedInstance.controller as? EnabledAppController {
|
|
342
|
-
controller.stateChangeListeners.keys.forEach {subscriptionId in
|
|
343
|
-
if let listener = controller.stateChangeListeners[subscriptionId] {
|
|
344
|
-
listener.updatesStateDidChange(event.toMap)
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
322
|
sendContextToJS()
|
|
349
323
|
}
|
|
350
324
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-updates",
|
|
3
|
-
"version": "55.0.
|
|
3
|
+
"version": "55.0.3",
|
|
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",
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@expo/code-signing-certificates": "^0.0.6",
|
|
42
|
-
"@expo/plist": "^0.5.
|
|
42
|
+
"@expo/plist": "^0.5.1",
|
|
43
43
|
"@expo/spawn-async": "^1.7.2",
|
|
44
44
|
"arg": "4.1.0",
|
|
45
45
|
"chalk": "^4.1.2",
|
|
46
46
|
"debug": "^4.3.4",
|
|
47
|
-
"expo-eas-client": "~55.0.
|
|
47
|
+
"expo-eas-client": "~55.0.1",
|
|
48
48
|
"expo-manifests": "~55.0.1",
|
|
49
49
|
"expo-structured-headers": "~55.0.0",
|
|
50
|
-
"expo-updates-interface": "~55.1.
|
|
50
|
+
"expo-updates-interface": "~55.1.1",
|
|
51
51
|
"getenv": "^2.0.0",
|
|
52
52
|
"glob": "^13.0.0",
|
|
53
53
|
"ignore": "^5.3.1",
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"react": "*",
|
|
72
72
|
"react-native": "*"
|
|
73
73
|
},
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "4728ba25fbd4d5835780306de78a83bd1628e271"
|
|
75
75
|
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
package expo.modules.updates
|
|
2
|
-
|
|
3
|
-
import expo.modules.updatesinterface.UpdatesStateChangeSubscription
|
|
4
|
-
|
|
5
|
-
class DisabledUpdatesStateChangeSubscription : UpdatesStateChangeSubscription {
|
|
6
|
-
override fun remove() {}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
class EnabledUpdatesStateChangeSubscription(val subscriptionId: String) : UpdatesStateChangeSubscription {
|
|
10
|
-
override fun remove() {
|
|
11
|
-
val updatesController: EnabledUpdatesController? = UpdatesController.instance as EnabledUpdatesController
|
|
12
|
-
updatesController?.unsubscribeFromUpdatesStateChanges(subscriptionId)
|
|
13
|
-
}
|
|
14
|
-
}
|