expo-updates 29.0.8 → 29.0.9

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,12 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 29.0.9 — 2025-09-10
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - [Android] Propagate controller scope to state machine. ([#39526](https://github.com/expo/expo/pull/39526) by [@alanjhughes](https://github.com/alanjhughes))
18
+
13
19
  ## 29.0.8 — 2025-09-02
14
20
 
15
21
  _This version does not introduce any user-facing changes._
@@ -42,7 +42,7 @@ expoModule {
42
42
  }
43
43
 
44
44
  group = 'host.exp.exponent'
45
- version = '29.0.8'
45
+ version = '29.0.9'
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
@@ -88,7 +88,7 @@ android {
88
88
  namespace "expo.modules.updates"
89
89
  defaultConfig {
90
90
  versionCode 31
91
- versionName '29.0.8'
91
+ versionName '29.0.9'
92
92
  consumerProguardFiles("proguard-rules.pro")
93
93
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
94
94
 
@@ -19,6 +19,7 @@ import expo.modules.updates.statemachine.UpdatesStateValue
19
19
  import kotlinx.coroutines.CompletableDeferred
20
20
  import kotlinx.coroutines.CoroutineScope
21
21
  import kotlinx.coroutines.Dispatchers
22
+ import kotlinx.coroutines.SupervisorJob
22
23
  import kotlinx.coroutines.cancel
23
24
  import kotlinx.coroutines.launch
24
25
  import kotlinx.coroutines.runBlocking
@@ -45,13 +46,13 @@ class DisabledUpdatesController(
45
46
  ) : IUpdatesController {
46
47
  /** Keep the activity for [RecreateReactContextProcedure] to relaunch the app. */
47
48
  private var weakActivity: WeakReference<Activity>? = null
48
- private val controllerScope = CoroutineScope(Dispatchers.IO)
49
+ private val controllerScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
49
50
 
50
51
  private val logger = UpdatesLogger(context.filesDir)
51
52
  override val eventManager: IUpdatesEventManager = UpdatesEventManager(logger)
52
53
 
53
54
  // disabled controller state machine can only be idle or restarting
54
- private val stateMachine = UpdatesStateMachine(logger, eventManager, setOf(UpdatesStateValue.Idle, UpdatesStateValue.Restarting))
55
+ private val stateMachine = UpdatesStateMachine(logger, eventManager, setOf(UpdatesStateValue.Idle, UpdatesStateValue.Restarting), controllerScope)
55
56
 
56
57
  private var isStarted = false
57
58
  private var startupStartTimeMillis: Long? = null
@@ -106,7 +107,7 @@ class DisabledUpdatesController(
106
107
  isStarted = true
107
108
  startupStartTimeMillis = System.currentTimeMillis()
108
109
 
109
- launcher = NoDatabaseLauncher(context, logger, fatalException)
110
+ launcher = NoDatabaseLauncher(context, logger, fatalException, controllerScope)
110
111
 
111
112
  startupEndTimeMillis = System.currentTimeMillis()
112
113
  notifyController()
@@ -143,7 +144,8 @@ class DisabledUpdatesController(
143
144
  override fun onSuccess() {
144
145
  continuation.resume(Unit)
145
146
  }
146
- }
147
+ },
148
+ controllerScope
147
149
  )
148
150
  stateMachine.queueExecution(procedure)
149
151
  }
@@ -32,6 +32,7 @@ import expo.modules.updates.statemachine.UpdatesStateValue
32
32
  import kotlinx.coroutines.CompletableDeferred
33
33
  import kotlinx.coroutines.CoroutineScope
34
34
  import kotlinx.coroutines.Dispatchers
35
+ import kotlinx.coroutines.SupervisorJob
35
36
  import kotlinx.coroutines.cancel
36
37
  import kotlinx.coroutines.launch
37
38
  import kotlinx.coroutines.runBlocking
@@ -60,8 +61,8 @@ class EnabledUpdatesController(
60
61
 
61
62
  private val selectionPolicy: SelectionPolicy
62
63
  get() = SelectionPolicyFactory.createFilterAwarePolicy(updatesConfiguration.getRuntimeVersion(), updatesConfiguration)
63
- private val stateMachine = UpdatesStateMachine(logger, eventManager, UpdatesStateValue.entries.toSet())
64
- private val controllerScope = CoroutineScope(Dispatchers.IO)
64
+ private val controllerScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
65
+ private val stateMachine = UpdatesStateMachine(logger, eventManager, UpdatesStateValue.entries.toSet(), controllerScope)
65
66
  private val fileDownloader: FileDownloader
66
67
  get() = FileDownloader(context.filesDir, EASClientID(context).uuid.toString(), updatesConfiguration, logger)
67
68
  private val databaseHolder = DatabaseHolder(UpdatesDatabase.getInstance(context, Dispatchers.IO))
@@ -111,7 +112,8 @@ class EnabledUpdatesController(
111
112
  override fun onRequestRelaunch(shouldRunReaper: Boolean, callback: LauncherCallback) {
112
113
  relaunchReactApplication(shouldRunReaper, callback)
113
114
  }
114
- }
115
+ },
116
+ controllerScope
115
117
  )
116
118
 
117
119
  private val launchedUpdate
@@ -183,7 +185,8 @@ class EnabledUpdatesController(
183
185
  setCurrentLauncher = { currentLauncher -> startupProcedure.setLauncher(currentLauncher) },
184
186
  shouldRunReaper = shouldRunReaper,
185
187
  reloadScreenManager = reloadScreenManager,
186
- callback
188
+ callback,
189
+ controllerScope
187
190
  )
188
191
  stateMachine.queueExecution(procedure)
189
192
  }
@@ -33,6 +33,7 @@ import expo.modules.updatesinterface.UpdatesInterface
33
33
  import expo.modules.updatesinterface.UpdatesInterfaceCallbacks
34
34
  import kotlinx.coroutines.CoroutineScope
35
35
  import kotlinx.coroutines.Dispatchers
36
+ import kotlinx.coroutines.SupervisorJob
36
37
  import kotlinx.coroutines.launch
37
38
  import kotlinx.coroutines.suspendCancellableCoroutine
38
39
  import org.json.JSONObject
@@ -67,7 +68,7 @@ class UpdatesDevLauncherController(
67
68
  private var updatesConfiguration: UpdatesConfiguration? = initialUpdatesConfiguration
68
69
 
69
70
  private val databaseHolder = DatabaseHolder(UpdatesDatabase.getInstance(context, Dispatchers.IO))
70
- private val controllerScope = CoroutineScope(Dispatchers.IO)
71
+ private val controllerScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
71
72
 
72
73
  private var mSelectionPolicy: SelectionPolicy? = null
73
74
  private var defaultSelectionPolicy: SelectionPolicy = SelectionPolicy(
@@ -5,6 +5,7 @@ import expo.modules.updates.loader.EmbeddedLoader
5
5
  import expo.modules.updates.logging.UpdatesLogger
6
6
  import kotlinx.coroutines.CoroutineScope
7
7
  import kotlinx.coroutines.Dispatchers
8
+ import kotlinx.coroutines.SupervisorJob
8
9
  import kotlinx.coroutines.launch
9
10
  import java.io.File
10
11
 
@@ -20,7 +21,7 @@ class NoDatabaseLauncher @JvmOverloads constructor(
20
21
  private val context: Context,
21
22
  private val logger: UpdatesLogger,
22
23
  fatalException: Exception? = null,
23
- launcherScope: CoroutineScope = CoroutineScope(Dispatchers.IO)
24
+ launcherScope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
24
25
  ) : Launcher {
25
26
  override val bundleAssetName = EmbeddedLoader.BARE_BUNDLE_FILENAME
26
27
  override val launchedUpdate = null
@@ -19,6 +19,7 @@ import expo.modules.updates.manifest.ManifestMetadata
19
19
  import expo.modules.updates.manifest.Update
20
20
  import kotlinx.coroutines.CoroutineScope
21
21
  import kotlinx.coroutines.Dispatchers
22
+ import kotlinx.coroutines.SupervisorJob
22
23
  import java.io.File
23
24
  import java.io.IOException
24
25
  import java.util.*
@@ -38,7 +39,7 @@ abstract class Loader protected constructor(
38
39
  private val database: UpdatesDatabase,
39
40
  private val updatesDirectory: File,
40
41
  private val loaderFiles: LoaderFiles,
41
- private var scope: CoroutineScope = CoroutineScope(Dispatchers.IO)
42
+ private var scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
42
43
  ) {
43
44
  private var updateResponse: UpdateResponse? = null
44
45
  private var updateEntity: UpdateEntity? = null
@@ -80,7 +80,7 @@ class StartupProcedure(
80
80
  object : LoaderTask.LoaderTaskCallback {
81
81
  override fun onFailure(e: Exception) {
82
82
  logger.error("UpdatesController loaderTask onFailure", e, UpdatesErrorCode.None)
83
- launcher = NoDatabaseLauncher(context, logger, e)
83
+ launcher = NoDatabaseLauncher(context, logger, e, procedureScope)
84
84
  emergencyLaunchException = e
85
85
  notifyController()
86
86
  }
@@ -4,6 +4,8 @@ import expo.modules.updates.events.IUpdatesEventManager
4
4
  import expo.modules.updates.logging.UpdatesLogger
5
5
  import expo.modules.updates.procedures.StateMachineProcedure
6
6
  import expo.modules.updates.procedures.StateMachineSerialExecutorQueue
7
+ import kotlinx.coroutines.CoroutineScope
8
+ import kotlinx.coroutines.Dispatchers
7
9
  import java.util.Date
8
10
 
9
11
  /**
@@ -13,7 +15,8 @@ import java.util.Date
13
15
  class UpdatesStateMachine(
14
16
  private val logger: UpdatesLogger,
15
17
  private val eventManager: IUpdatesEventManager,
16
- private val validUpdatesStateValues: Set<UpdatesStateValue>
18
+ private val validUpdatesStateValues: Set<UpdatesStateValue>,
19
+ scope: CoroutineScope = CoroutineScope(Dispatchers.IO)
17
20
  ) {
18
21
  private val serialExecutorQueue = StateMachineSerialExecutorQueue(
19
22
  logger,
@@ -30,7 +33,8 @@ class UpdatesStateMachine(
30
33
  override fun resetStateAfterRestart() {
31
34
  resetAndIncrementRestartCount()
32
35
  }
33
- }
36
+ },
37
+ scope
34
38
  )
35
39
 
36
40
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-updates",
3
- "version": "29.0.8",
3
+ "version": "29.0.9",
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",
@@ -60,7 +60,7 @@
60
60
  "@types/node-forge": "^1.0.0",
61
61
  "@types/picomatch": "^4.0.0",
62
62
  "@vercel/ncc": "^0.38.3",
63
- "expo-module-scripts": "^5.0.6",
63
+ "expo-module-scripts": "^5.0.7",
64
64
  "express": "^5.1.0",
65
65
  "form-data": "^4.0.4",
66
66
  "js-yaml": "^4.1.0",
@@ -73,5 +73,5 @@
73
73
  "react": "*",
74
74
  "react-native": "*"
75
75
  },
76
- "gitHead": "d635404a12ea7996b987ce0fb7679a238ebcf31b"
76
+ "gitHead": "87186d10c8239c6469e055417e67bd4d0ed63efb"
77
77
  }