expo-updates 1.0.0-canary-20250303-4dba60e → 1.0.0-canary-20250304-8a21aa7

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.
@@ -138,6 +138,7 @@ dependencies {
138
138
  androidTestImplementation 'androidx.test:rules:1.5.0'
139
139
  androidTestImplementation "io.mockk:mockk-android:$mockk_version"
140
140
  androidTestImplementation "androidx.room:room-testing:$room_version"
141
+ androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
141
142
  androidTestImplementation "org.jetbrains.kotlin:kotlin-test-junit:${kotlinVersion}"
142
143
 
143
144
  implementation "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}"
@@ -35,7 +35,7 @@ class DisabledUpdatesController(
35
35
  /** Keep the activity for [RecreateReactContextProcedure] to relaunch the app. */
36
36
  private var weakActivity: WeakReference<Activity>? = null
37
37
 
38
- private val logger = UpdatesLogger(context)
38
+ private val logger = UpdatesLogger(context.filesDir)
39
39
  override val eventManager: IUpdatesEventManager = UpdatesEventManager(logger)
40
40
 
41
41
  // disabled controller state machine can only be idle or restarting
@@ -44,7 +44,7 @@ class EnabledUpdatesController(
44
44
  ) : IUpdatesController {
45
45
  /** Keep the activity for [RelaunchProcedure] to relaunch the app. */
46
46
  private var weakActivity: WeakReference<Activity>? = null
47
- private val logger = UpdatesLogger(context)
47
+ private val logger = UpdatesLogger(context.filesDir)
48
48
  override val eventManager: IUpdatesEventManager = UpdatesEventManager(logger)
49
49
 
50
50
  private val fileDownloader = FileDownloader(context, updatesConfiguration, logger)
@@ -56,7 +56,7 @@ class EnabledUpdatesController(
56
56
  private val controllerScope = CoroutineScope(Dispatchers.IO)
57
57
 
58
58
  private fun purgeUpdatesLogsOlderThanOneDay() {
59
- UpdatesLogReader(context).purgeLogEntries {
59
+ UpdatesLogReader(context.filesDir).purgeLogEntries {
60
60
  if (it != null) {
61
61
  logger.error("UpdatesLogReader: error in purgeLogEntries", it, UpdatesErrorCode.Unknown)
62
62
  }
@@ -18,146 +18,156 @@ import java.lang.ref.WeakReference
18
18
  * start the process of loading and launching an update, then responds appropriately depending on
19
19
  * the callbacks that are invoked.
20
20
  */
21
- class UpdatesController {
22
- companion object {
23
- private var singletonInstance: IUpdatesController? = null
24
- private var overrideConfiguration: UpdatesConfiguration? = null
25
-
26
- @JvmStatic val instance: IUpdatesController
27
- get() {
28
- return checkNotNull(singletonInstance) { "UpdatesController.instance was called before the module was initialized" }
29
- }
21
+ object UpdatesController {
22
+ private var singletonInstance: IUpdatesController? = null
23
+ private var overrideConfiguration: UpdatesConfiguration? = null
24
+
25
+ @JvmStatic
26
+ val instance: IUpdatesController
27
+ get() {
28
+ return checkNotNull(singletonInstance) { "UpdatesController.instance was called before the module was initialized" }
29
+ }
30
30
 
31
- @JvmStatic fun initializeWithoutStarting(context: Context) {
32
- if (singletonInstance != null) {
33
- return
31
+ @JvmStatic
32
+ fun initializeWithoutStarting(context: Context) {
33
+ if (singletonInstance != null) {
34
+ return
35
+ }
36
+ val useDeveloperSupport =
37
+ (context as? ReactApplication)?.reactNativeHost?.useDeveloperSupport ?: false
38
+ if (useDeveloperSupport && !BuildConfig.EX_UPDATES_NATIVE_DEBUG) {
39
+ if (BuildConfig.USE_DEV_CLIENT) {
40
+ val devLauncherController = initializeAsDevLauncherWithoutStarting(context)
41
+ singletonInstance = devLauncherController
42
+ UpdatesControllerRegistry.controller = WeakReference(devLauncherController)
43
+ } else {
44
+ singletonInstance = DisabledUpdatesController(context, null)
34
45
  }
35
- val useDeveloperSupport = (context as? ReactApplication)?.reactNativeHost?.useDeveloperSupport ?: false
36
- if (useDeveloperSupport && !BuildConfig.EX_UPDATES_NATIVE_DEBUG) {
37
- if (BuildConfig.USE_DEV_CLIENT) {
38
- val devLauncherController = initializeAsDevLauncherWithoutStarting(context)
39
- singletonInstance = devLauncherController
40
- UpdatesControllerRegistry.controller = WeakReference(devLauncherController)
41
- } else {
42
- singletonInstance = DisabledUpdatesController(context, null)
46
+ return
47
+ }
48
+
49
+ val logger = UpdatesLogger(context.filesDir)
50
+
51
+ val updatesDirectory = try {
52
+ UpdatesUtils.getOrCreateUpdatesDirectory(context)
53
+ } catch (e: Exception) {
54
+ logger.error(
55
+ "The expo-updates system is disabled due to a storage access error",
56
+ e,
57
+ UpdatesErrorCode.InitializationError
58
+ )
59
+ singletonInstance = DisabledUpdatesController(context, e)
60
+ return
61
+ }
62
+
63
+ val updatesConfiguration: UpdatesConfiguration? = overrideConfiguration ?: run {
64
+ when (UpdatesConfiguration.getUpdatesConfigurationValidationResult(context, null)) {
65
+ UpdatesConfigurationValidationResult.VALID -> {
66
+ return@run UpdatesConfiguration(context, null)
43
67
  }
44
- return
45
- }
46
68
 
47
- val logger = UpdatesLogger(context)
69
+ UpdatesConfigurationValidationResult.INVALID_NOT_ENABLED -> logger.warn(
70
+ "The expo-updates system is explicitly disabled. To enable it, set the enabled setting to true.",
71
+ UpdatesErrorCode.InitializationError
72
+ )
48
73
 
49
- val updatesDirectory = try {
50
- UpdatesUtils.getOrCreateUpdatesDirectory(context)
51
- } catch (e: Exception) {
52
- logger.error(
53
- "The expo-updates system is disabled due to a storage access error",
54
- e,
74
+ UpdatesConfigurationValidationResult.INVALID_MISSING_URL -> logger.warn(
75
+ "The expo-updates system is disabled due to an invalid configuration. Ensure a valid URL is supplied.",
55
76
  UpdatesErrorCode.InitializationError
56
77
  )
57
- singletonInstance = DisabledUpdatesController(context, e)
58
- return
59
- }
60
78
 
61
- val updatesConfiguration: UpdatesConfiguration? = overrideConfiguration ?: run {
62
- when (UpdatesConfiguration.getUpdatesConfigurationValidationResult(context, null)) {
63
- UpdatesConfigurationValidationResult.VALID -> {
64
- return@run UpdatesConfiguration(context, null)
65
- }
66
- UpdatesConfigurationValidationResult.INVALID_NOT_ENABLED -> logger.warn(
67
- "The expo-updates system is explicitly disabled. To enable it, set the enabled setting to true.",
68
- UpdatesErrorCode.InitializationError
69
- )
70
- UpdatesConfigurationValidationResult.INVALID_MISSING_URL -> logger.warn(
71
- "The expo-updates system is disabled due to an invalid configuration. Ensure a valid URL is supplied.",
72
- UpdatesErrorCode.InitializationError
73
- )
74
- UpdatesConfigurationValidationResult.INVALID_MISSING_RUNTIME_VERSION -> logger.warn(
75
- "The expo-updates system is disabled due to an invalid configuration. Ensure a runtime version is supplied.",
76
- UpdatesErrorCode.InitializationError
77
- )
78
- }
79
- return@run null
79
+ UpdatesConfigurationValidationResult.INVALID_MISSING_RUNTIME_VERSION -> logger.warn(
80
+ "The expo-updates system is disabled due to an invalid configuration. Ensure a runtime version is supplied.",
81
+ UpdatesErrorCode.InitializationError
82
+ )
80
83
  }
84
+ return@run null
85
+ }
81
86
 
82
- singletonInstance = if (updatesConfiguration != null) {
83
- EnabledUpdatesController(context, updatesConfiguration, updatesDirectory)
84
- } else {
85
- DisabledUpdatesController(context, null)
86
- }
87
+ singletonInstance = if (updatesConfiguration != null) {
88
+ EnabledUpdatesController(context, updatesConfiguration, updatesDirectory)
89
+ } else {
90
+ DisabledUpdatesController(context, null)
87
91
  }
92
+ }
88
93
 
89
- private fun initializeAsDevLauncherWithoutStarting(context: Context): UpdatesDevLauncherController {
90
- check(singletonInstance == null) { "UpdatesController must not be initialized prior to calling initializeAsDevLauncherWithoutStarting" }
94
+ private fun initializeAsDevLauncherWithoutStarting(context: Context): UpdatesDevLauncherController {
95
+ check(singletonInstance == null) { "UpdatesController must not be initialized prior to calling initializeAsDevLauncherWithoutStarting" }
91
96
 
92
- var updatesDirectoryException: Exception? = null
93
- val updatesDirectory = try {
94
- UpdatesUtils.getOrCreateUpdatesDirectory(context)
95
- } catch (e: Exception) {
96
- updatesDirectoryException = e
97
- null
98
- }
97
+ var updatesDirectoryException: Exception? = null
98
+ val updatesDirectory = try {
99
+ UpdatesUtils.getOrCreateUpdatesDirectory(context)
100
+ } catch (e: Exception) {
101
+ updatesDirectoryException = e
102
+ null
103
+ }
99
104
 
100
- val initialUpdatesConfiguration = overrideConfiguration ?: run {
101
- if (UpdatesConfiguration.getUpdatesConfigurationValidationResult(context, null) == UpdatesConfigurationValidationResult.VALID) {
102
- UpdatesConfiguration(context, null)
103
- } else {
105
+ val initialUpdatesConfiguration = overrideConfiguration ?: run {
106
+ if (UpdatesConfiguration.getUpdatesConfigurationValidationResult(
107
+ context,
104
108
  null
105
- }
109
+ ) == UpdatesConfigurationValidationResult.VALID
110
+ ) {
111
+ UpdatesConfiguration(context, null)
112
+ } else {
113
+ null
106
114
  }
107
-
108
- val instance = UpdatesDevLauncherController(
109
- context,
110
- initialUpdatesConfiguration,
111
- updatesDirectory,
112
- updatesDirectoryException
113
- )
114
- singletonInstance = instance
115
- return instance
116
115
  }
117
116
 
118
- /**
119
- * Initializes the UpdatesController singleton. This should be called as early as possible in the
120
- * application's lifecycle. Can pass additional configuration to this method to set or override
121
- * configuration values at runtime rather than just AndroidManifest.xml.
122
- * @param context the base context of the application, ideally a [ReactApplication]
123
- */
124
- @JvmStatic fun initialize(context: Context) {
125
- if (singletonInstance == null) {
126
- initializeWithoutStarting(context)
127
- singletonInstance!!.start()
128
- }
129
- }
117
+ val instance = UpdatesDevLauncherController(
118
+ context,
119
+ initialUpdatesConfiguration,
120
+ updatesDirectory,
121
+ updatesDirectoryException
122
+ )
123
+ singletonInstance = instance
124
+ return instance
125
+ }
130
126
 
131
- /**
132
- * Overrides the [UpdatesConfiguration] that will be used inside [UpdatesController]
133
- * This should be called as early as possible in the application's lifecycle.
134
- * Can pass additional configuration to this method to set or override
135
- * configuration values at runtime rather than just AndroidManifest.xml.
136
- *
137
- * @param context the base context of the application, ideally a [ReactApplication]
138
- * @param configuration map of configuration pairs to override those from AndroidManifest.xml
139
- */
140
- @JvmStatic
141
- fun overrideConfiguration(context: Context, configuration: Map<String, Any>) {
142
- if (singletonInstance != null) {
143
- throw AssertionError("The method should be called before UpdatesController.initialize()")
144
- }
145
- val updatesConfigurationValidationResult = UpdatesConfiguration.getUpdatesConfigurationValidationResult(context, configuration)
146
- if (updatesConfigurationValidationResult == UpdatesConfigurationValidationResult.VALID) {
147
- overrideConfiguration = UpdatesConfiguration(context, configuration)
148
- } else {
149
- val logger = UpdatesLogger(context)
150
- logger.warn("Failed to overrideConfiguration: invalid configuration: ${updatesConfigurationValidationResult.name}")
151
- }
127
+ /**
128
+ * Initializes the UpdatesController singleton. This should be called as early as possible in the
129
+ * application's lifecycle. Can pass additional configuration to this method to set or override
130
+ * configuration values at runtime rather than just AndroidManifest.xml.
131
+ * @param context the base context of the application, ideally a [ReactApplication]
132
+ */
133
+ @JvmStatic
134
+ fun initialize(context: Context) {
135
+ if (singletonInstance == null) {
136
+ initializeWithoutStarting(context)
137
+ singletonInstance!!.start()
152
138
  }
139
+ }
153
140
 
154
- internal fun setUpdatesEventManagerObserver(observer: WeakReference<IUpdatesEventManagerObserver>) {
155
- singletonInstance?.eventManager?.observer = observer
156
- singletonInstance?.onEventListenerStartObserving()
141
+ /**
142
+ * Overrides the [UpdatesConfiguration] that will be used inside [UpdatesController]
143
+ * This should be called as early as possible in the application's lifecycle.
144
+ * Can pass additional configuration to this method to set or override
145
+ * configuration values at runtime rather than just AndroidManifest.xml.
146
+ *
147
+ * @param context the base context of the application, ideally a [ReactApplication]
148
+ * @param configuration map of configuration pairs to override those from AndroidManifest.xml
149
+ */
150
+ @JvmStatic
151
+ fun overrideConfiguration(context: Context, configuration: Map<String, Any>) {
152
+ if (singletonInstance != null) {
153
+ throw AssertionError("The method should be called before UpdatesController.initialize()")
157
154
  }
158
-
159
- internal fun removeUpdatesEventManagerObserver() {
160
- singletonInstance?.eventManager?.observer = null
155
+ val updatesConfigurationValidationResult =
156
+ UpdatesConfiguration.getUpdatesConfigurationValidationResult(context, configuration)
157
+ if (updatesConfigurationValidationResult == UpdatesConfigurationValidationResult.VALID) {
158
+ overrideConfiguration = UpdatesConfiguration(context, configuration)
159
+ } else {
160
+ val logger = UpdatesLogger(context.filesDir)
161
+ logger.warn("Failed to overrideConfiguration: invalid configuration: ${updatesConfigurationValidationResult.name}")
161
162
  }
162
163
  }
164
+
165
+ internal fun setUpdatesEventManagerObserver(observer: WeakReference<IUpdatesEventManagerObserver>) {
166
+ singletonInstance?.eventManager?.observer = observer
167
+ singletonInstance?.onEventListenerStartObserving()
168
+ }
169
+
170
+ internal fun removeUpdatesEventManagerObserver() {
171
+ singletonInstance?.eventManager?.observer = null
172
+ }
163
173
  }
@@ -54,7 +54,7 @@ class UpdatesDevLauncherController(
54
54
 
55
55
  private var launcher: Launcher? = null
56
56
 
57
- private val logger = UpdatesLogger(context)
57
+ private val logger = UpdatesLogger(context.filesDir)
58
58
 
59
59
  private var previousUpdatesConfiguration: UpdatesConfiguration? = null
60
60
  private var updatesConfiguration: UpdatesConfiguration? = initialUpdatesConfiguration
@@ -2,11 +2,11 @@ package expo.modules.updates
2
2
 
3
3
  import android.content.Context
4
4
  import android.net.Uri
5
- import android.os.AsyncTask
6
5
  import android.os.Bundle
7
6
  import expo.modules.kotlin.Promise
8
7
  import expo.modules.kotlin.exception.CodedException
9
8
  import expo.modules.kotlin.exception.Exceptions
9
+ import expo.modules.kotlin.functions.Coroutine
10
10
  import expo.modules.kotlin.modules.Module
11
11
  import expo.modules.kotlin.modules.ModuleDefinition
12
12
  import expo.modules.kotlin.records.Field
@@ -18,6 +18,12 @@ import expo.modules.updates.logging.UpdatesLogEntry
18
18
  import expo.modules.updates.logging.UpdatesLogReader
19
19
  import expo.modules.updates.logging.UpdatesLogger
20
20
  import expo.modules.updates.statemachine.UpdatesStateContext
21
+ import kotlinx.coroutines.CoroutineScope
22
+ import kotlinx.coroutines.Dispatchers
23
+ import kotlinx.coroutines.cancel
24
+ import kotlinx.coroutines.launch
25
+ import kotlinx.coroutines.withContext
26
+ import java.io.File
21
27
  import java.lang.ref.WeakReference
22
28
  import java.util.Date
23
29
 
@@ -32,18 +38,20 @@ enum class UpdatesJSEvent(val eventName: String) : Enumerable {
32
38
  */
33
39
  class UpdatesModule : Module(), IUpdatesEventManagerObserver {
34
40
  private val logger: UpdatesLogger
35
- get() = UpdatesLogger(context)
41
+ get() = UpdatesLogger(context.filesDir)
36
42
 
37
43
  private val context: Context
38
44
  get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
39
45
 
46
+ private val moduleScope = CoroutineScope(Dispatchers.IO)
47
+
40
48
  override fun definition() = ModuleDefinition {
41
49
  Name("ExpoUpdates")
42
50
 
43
51
  Events<UpdatesJSEvent>()
44
52
 
45
53
  Constants {
46
- UpdatesLogger(context).info("UpdatesModule: getConstants called", UpdatesErrorCode.None)
54
+ UpdatesLogger(context.filesDir).info("UpdatesModule: getConstants called", UpdatesErrorCode.None)
47
55
  UpdatesController.instance.getConstantsForModule().toModuleConstantsMap()
48
56
  }
49
57
 
@@ -81,6 +89,7 @@ class UpdatesModule : Module(), IUpdatesEventManagerObserver {
81
89
  is IUpdatesController.CheckForUpdateResult.ErrorResult -> {
82
90
  promise.reject("ERR_UPDATES_CHECK", "Failed to check for update", result.error)
83
91
  }
92
+
84
93
  is IUpdatesController.CheckForUpdateResult.NoUpdateAvailable -> {
85
94
  promise.resolve(
86
95
  Bundle().apply {
@@ -90,6 +99,7 @@ class UpdatesModule : Module(), IUpdatesEventManagerObserver {
90
99
  }
91
100
  )
92
101
  }
102
+
93
103
  is IUpdatesController.CheckForUpdateResult.RollBackToEmbedded -> {
94
104
  promise.resolve(
95
105
  Bundle().apply {
@@ -98,6 +108,7 @@ class UpdatesModule : Module(), IUpdatesEventManagerObserver {
98
108
  }
99
109
  )
100
110
  }
111
+
101
112
  is IUpdatesController.CheckForUpdateResult.UpdateAvailable -> {
102
113
  promise.resolve(
103
114
  Bundle().apply {
@@ -128,6 +139,7 @@ class UpdatesModule : Module(), IUpdatesEventManagerObserver {
128
139
  is IUpdatesController.FetchUpdateResult.ErrorResult -> {
129
140
  promise.reject("ERR_UPDATES_FETCH", "Failed to download new update", result.error)
130
141
  }
142
+
131
143
  is IUpdatesController.FetchUpdateResult.Failure -> {
132
144
  promise.resolve(
133
145
  Bundle().apply {
@@ -136,6 +148,7 @@ class UpdatesModule : Module(), IUpdatesEventManagerObserver {
136
148
  }
137
149
  )
138
150
  }
151
+
139
152
  is IUpdatesController.FetchUpdateResult.RollBackToEmbedded -> {
140
153
  promise.resolve(
141
154
  Bundle().apply {
@@ -144,6 +157,7 @@ class UpdatesModule : Module(), IUpdatesEventManagerObserver {
144
157
  }
145
158
  )
146
159
  }
160
+
147
161
  is IUpdatesController.FetchUpdateResult.Success -> {
148
162
  promise.resolve(
149
163
  Bundle().apply {
@@ -193,15 +207,13 @@ class UpdatesModule : Module(), IUpdatesEventManagerObserver {
193
207
  )
194
208
  }
195
209
 
196
- AsyncFunction("readLogEntriesAsync") { maxAge: Long, promise: Promise ->
197
- AsyncTask.execute {
198
- promise.resolve(readLogEntries(context, maxAge))
199
- }
210
+ AsyncFunction("readLogEntriesAsync") Coroutine { maxAge: Long ->
211
+ return@Coroutine readLogEntries(context.filesDir, maxAge)
200
212
  }
201
213
 
202
214
  AsyncFunction("clearLogEntriesAsync") { promise: Promise ->
203
- AsyncTask.execute {
204
- clearLogEntries(context) { error ->
215
+ moduleScope.launch {
216
+ clearLogEntries(context.filesDir) { error ->
205
217
  if (error != null) {
206
218
  promise.reject(
207
219
  "ERR_UPDATES_READ_LOGS",
@@ -218,16 +230,24 @@ class UpdatesModule : Module(), IUpdatesEventManagerObserver {
218
230
  Function("setUpdateURLAndRequestHeadersOverride") { configOverride: UpdatesConfigurationOverrideParam? ->
219
231
  UpdatesController.instance.setUpdateURLAndRequestHeadersOverride(configOverride?.toUpdatesConfigurationOverride())
220
232
  }
233
+
234
+ OnDestroy {
235
+ try {
236
+ moduleScope.cancel()
237
+ } catch (e: IllegalStateException) {
238
+ logger.error("The scope does not have a job in it", e)
239
+ }
240
+ }
221
241
  }
222
242
 
223
243
  companion object {
224
244
  private val TAG = UpdatesModule::class.java.simpleName
225
245
 
226
- internal fun readLogEntries(context: Context, maxAge: Long): List<Bundle> {
227
- val reader = UpdatesLogReader(context)
246
+ internal suspend fun readLogEntries(filesDirectory: File, maxAge: Long) = withContext(Dispatchers.IO) {
247
+ val reader = UpdatesLogReader(filesDirectory)
228
248
  val date = Date()
229
249
  val epoch = Date(date.time - maxAge)
230
- return reader.getLogEntries(epoch)
250
+ reader.getLogEntries(epoch)
231
251
  .mapNotNull { UpdatesLogEntry.create(it) }
232
252
  .map { entry ->
233
253
  Bundle().apply {
@@ -248,8 +268,8 @@ class UpdatesModule : Module(), IUpdatesEventManagerObserver {
248
268
  }
249
269
  }
250
270
 
251
- internal fun clearLogEntries(context: Context, completionHandler: (_: Exception?) -> Unit) {
252
- val reader = UpdatesLogReader(context)
271
+ internal suspend fun clearLogEntries(filesDirectory: File, completionHandler: (_: Exception?) -> Unit) {
272
+ val reader = UpdatesLogReader(filesDirectory)
253
273
  reader.purgeLogEntries(
254
274
  olderThan = Date(),
255
275
  completionHandler
@@ -1,8 +1,8 @@
1
1
  package expo.modules.updates.logging
2
2
 
3
- import android.content.Context
4
3
  import expo.modules.core.logging.PersistentFileLog
5
4
  import expo.modules.updates.logging.UpdatesLogger.Companion.EXPO_UPDATES_LOGGING_TAG
5
+ import java.io.File
6
6
  import java.lang.Long.max
7
7
  import java.util.*
8
8
 
@@ -10,7 +10,7 @@ import java.util.*
10
10
  * Class for reading expo-updates logs
11
11
  */
12
12
  class UpdatesLogReader(
13
- context: Context
13
+ filesDirectory: File
14
14
  ) {
15
15
 
16
16
  /**
@@ -37,7 +37,7 @@ class UpdatesLogReader(
37
37
  .filter { entryString -> isEntryStringLaterThanTimestamp(entryString, epochTimestamp) }
38
38
  }
39
39
 
40
- private val persistentLog = PersistentFileLog(EXPO_UPDATES_LOGGING_TAG, context)
40
+ private val persistentLog = PersistentFileLog(EXPO_UPDATES_LOGGING_TAG, filesDirectory)
41
41
 
42
42
  private fun isEntryStringLaterThanTimestamp(entryString: String, timestamp: Long): Boolean {
43
43
  val entry = UpdatesLogEntry.create(entryString) ?: return false
@@ -1,10 +1,10 @@
1
1
  package expo.modules.updates.logging
2
2
 
3
- import android.content.Context
4
3
  import expo.modules.core.logging.LogHandlers
5
4
  import expo.modules.core.logging.LogType
6
5
  import expo.modules.core.logging.Logger
7
6
  import expo.modules.core.logging.LoggerTimer
7
+ import java.io.File
8
8
  import java.util.Date
9
9
 
10
10
  interface IUpdatesLogger {
@@ -14,7 +14,7 @@ interface IUpdatesLogger {
14
14
  /**
15
15
  * Class that implements logging for expo-updates with its own logcat tag
16
16
  */
17
- class UpdatesLogger(context: Context) : IUpdatesLogger {
17
+ class UpdatesLogger(filesDirectory: File) : IUpdatesLogger {
18
18
 
19
19
  fun trace(
20
20
  message: String,
@@ -127,7 +127,7 @@ class UpdatesLogger(context: Context) : IUpdatesLogger {
127
127
  private val logger = Logger(
128
128
  listOf(
129
129
  LogHandlers.createOSLogHandler(EXPO_UPDATES_LOGGING_TAG),
130
- LogHandlers.createPersistentFileLogHandler(context, EXPO_UPDATES_LOGGING_TAG)
130
+ LogHandlers.createPersistentFileLogHandler(filesDirectory, EXPO_UPDATES_LOGGING_TAG)
131
131
  )
132
132
  )
133
133
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-updates",
3
- "version": "1.0.0-canary-20250303-4dba60e",
3
+ "version": "1.0.0-canary-20250304-8a21aa7",
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.5",
42
- "@expo/config": "11.0.0-canary-20250303-4dba60e",
43
- "@expo/config-plugins": "9.1.0-canary-20250303-4dba60e",
42
+ "@expo/config": "11.0.0-canary-20250304-8a21aa7",
43
+ "@expo/config-plugins": "9.1.0-canary-20250304-8a21aa7",
44
44
  "@expo/spawn-async": "^1.7.2",
45
45
  "arg": "4.1.0",
46
46
  "chalk": "^4.1.2",
47
- "expo-eas-client": "0.13.4-canary-20250303-4dba60e",
48
- "expo-manifests": "0.15.8-canary-20250303-4dba60e",
49
- "expo-structured-headers": "4.0.1-canary-20250303-4dba60e",
50
- "expo-updates-interface": "1.0.1-canary-20250303-4dba60e",
47
+ "expo-eas-client": "0.13.4-canary-20250304-8a21aa7",
48
+ "expo-manifests": "0.15.8-canary-20250304-8a21aa7",
49
+ "expo-structured-headers": "4.0.1-canary-20250304-8a21aa7",
50
+ "expo-updates-interface": "1.0.1-canary-20250304-8a21aa7",
51
51
  "fbemitter": "^3.0.0",
52
52
  "glob": "^10.4.2",
53
53
  "ignore": "^5.3.1",
@@ -57,15 +57,15 @@
57
57
  "@types/jest": "^29.2.1",
58
58
  "@types/node": "^18.19.34",
59
59
  "@types/node-forge": "^1.0.0",
60
- "expo-module-scripts": "4.0.5-canary-20250303-4dba60e",
60
+ "expo-module-scripts": "4.0.5-canary-20250304-8a21aa7",
61
61
  "express": "^4.21.1",
62
62
  "form-data": "^4.0.0",
63
63
  "memfs": "^3.2.0",
64
64
  "xstate": "^4.37.2"
65
65
  },
66
66
  "peerDependencies": {
67
- "expo": "53.0.0-canary-20250303-4dba60e",
67
+ "expo": "53.0.0-canary-20250304-8a21aa7",
68
68
  "react": "*"
69
69
  },
70
- "gitHead": "4dba60e10b5d44b453073aa4968e9dbf312dea6c"
70
+ "gitHead": "8a21aa734aadf339bb2778a80d32602ed561405b"
71
71
  }