expo-updates 0.26.0 → 0.26.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,26 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 0.26.2 — 2024-10-24
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - Move event emitting responsibility to module. ([#32248](https://github.com/expo/expo/pull/32248) by [@wschurman](https://github.com/wschurman))
18
+
19
+ ### 💡 Others
20
+
21
+ - Use enum event in OnStartObserving and OnStopObserving. ([#32252](https://github.com/expo/expo/pull/32252) by [@wschurman](https://github.com/wschurman))
22
+
23
+ ## 0.26.1 — 2024-10-22
24
+
25
+ ### 🐛 Bug fixes
26
+
27
+ - Fixed Android launch crash when R8 is enabled. ([#32226](https://github.com/expo/expo/pull/32226) by [@kudo](https://github.com/kudo))
28
+
29
+ ### 💡 Others
30
+
31
+ - Fixed updates E2E tests. ([#32226](https://github.com/expo/expo/pull/32226) by [@kudo](https://github.com/kudo))
32
+
13
33
  ## 0.26.0 — 2024-10-22
14
34
 
15
35
  ### 🛠 Breaking changes
@@ -16,7 +16,7 @@ apply plugin: 'com.android.library'
16
16
  apply plugin: 'com.google.devtools.ksp'
17
17
 
18
18
  group = 'host.exp.exponent'
19
- version = '0.26.0'
19
+ version = '0.26.2'
20
20
 
21
21
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
22
22
  apply from: expoModulesCorePlugin
@@ -62,7 +62,7 @@ android {
62
62
  namespace "expo.modules.updates"
63
63
  defaultConfig {
64
64
  versionCode 31
65
- versionName '0.26.0'
65
+ versionName '0.26.2'
66
66
  consumerProguardFiles("proguard-rules.pro")
67
67
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
68
68
 
@@ -3,5 +3,5 @@
3
3
  }
4
4
 
5
5
  -keepclassmembers class com.facebook.react.devsupport.ReleaseDevSupportManager {
6
- private final com.facebook.react.bridge.DefaultJSExceptionHandler mDefaultJSExceptionHandler;
6
+ private final com.facebook.react.bridge.DefaultJSExceptionHandler defaultJSExceptionHandler;
7
7
  }
@@ -2,7 +2,7 @@ package expo.modules.updates
2
2
 
3
3
  import android.content.Context
4
4
  import com.facebook.react.ReactApplication
5
- import expo.modules.kotlin.events.EventEmitter
5
+ import expo.modules.updates.events.IUpdatesEventManagerObserver
6
6
  import expo.modules.updates.loader.LoaderTask
7
7
  import expo.modules.updates.logging.UpdatesErrorCode
8
8
  import expo.modules.updates.logging.UpdatesLogger
@@ -151,13 +151,13 @@ class UpdatesController {
151
151
  }
152
152
  }
153
153
 
154
- internal fun onEventListenerStartObserving(eventEmitter: EventEmitter?) {
155
- singletonInstance?.eventManager?.eventEmitter = eventEmitter
154
+ internal fun setUpdatesEventManagerObserver(observer: WeakReference<IUpdatesEventManagerObserver>) {
155
+ singletonInstance?.eventManager?.observer = observer
156
156
  singletonInstance?.onEventListenerStartObserving()
157
157
  }
158
158
 
159
- internal fun onEventListenerStopObserving() {
160
- singletonInstance?.eventManager?.eventEmitter = null
159
+ internal fun removeUpdatesEventManagerObserver() {
160
+ singletonInstance?.eventManager?.observer = null
161
161
  }
162
162
  }
163
163
  }
@@ -8,19 +8,26 @@ import expo.modules.kotlin.exception.CodedException
8
8
  import expo.modules.kotlin.exception.Exceptions
9
9
  import expo.modules.kotlin.modules.Module
10
10
  import expo.modules.kotlin.modules.ModuleDefinition
11
- import expo.modules.updates.events.UpdatesJSEvent
11
+ import expo.modules.kotlin.types.Enumerable
12
+ import expo.modules.updates.events.IUpdatesEventManagerObserver
12
13
  import expo.modules.updates.logging.UpdatesErrorCode
13
14
  import expo.modules.updates.logging.UpdatesLogEntry
14
15
  import expo.modules.updates.logging.UpdatesLogReader
15
16
  import expo.modules.updates.logging.UpdatesLogger
17
+ import expo.modules.updates.statemachine.UpdatesStateContext
18
+ import java.lang.ref.WeakReference
16
19
  import java.util.Date
17
20
 
21
+ enum class UpdatesJSEvent(val eventName: String) : Enumerable {
22
+ StateChange("Expo.nativeUpdatesStateChangeEvent")
23
+ }
24
+
18
25
  /**
19
26
  * Exported module which provides to the JS runtime information about the currently running update
20
27
  * and updates state, along with methods to check for and download new updates, reload with the
21
28
  * newest downloaded update applied, and read/clear native log entries.
22
29
  */
23
- class UpdatesModule : Module() {
30
+ class UpdatesModule : Module(), IUpdatesEventManagerObserver {
24
31
  private val logger: UpdatesLogger
25
32
  get() = UpdatesLogger(context)
26
33
 
@@ -30,21 +37,23 @@ class UpdatesModule : Module() {
30
37
  override fun definition() = ModuleDefinition {
31
38
  Name("ExpoUpdates")
32
39
 
33
- Events(
34
- UpdatesJSEvent.StateChange.eventName
35
- )
40
+ Events<UpdatesJSEvent>()
36
41
 
37
42
  Constants {
38
43
  UpdatesLogger(context).info("UpdatesModule: getConstants called", UpdatesErrorCode.None)
39
44
  UpdatesController.instance.getConstantsForModule().toModuleConstantsMap()
40
45
  }
41
46
 
42
- OnStartObserving {
43
- UpdatesController.onEventListenerStartObserving(appContext.eventEmitter(this@UpdatesModule))
47
+ OnStartObserving(UpdatesJSEvent.StateChange) {
48
+ UpdatesController.setUpdatesEventManagerObserver(WeakReference(this@UpdatesModule))
49
+ }
50
+
51
+ OnStopObserving(UpdatesJSEvent.StateChange) {
52
+ UpdatesController.removeUpdatesEventManagerObserver()
44
53
  }
45
54
 
46
- OnStopObserving {
47
- UpdatesController.onEventListenerStopObserving()
55
+ OnDestroy {
56
+ UpdatesController.removeUpdatesEventManagerObserver()
48
57
  }
49
58
 
50
59
  AsyncFunction("reload") { promise: Promise ->
@@ -240,4 +249,8 @@ class UpdatesModule : Module() {
240
249
  )
241
250
  }
242
251
  }
252
+
253
+ override fun onStateMachineContextEvent(context: UpdatesStateContext) {
254
+ sendEvent(UpdatesJSEvent.StateChange, Bundle().apply { putBundle("context", context.bundle) })
255
+ }
243
256
  }
@@ -120,7 +120,7 @@ class ErrorRecovery(
120
120
  }
121
121
  }
122
122
  val devSupportManagerClass = devSupportManager.javaClass
123
- previousExceptionHandler = devSupportManagerClass.getDeclaredField("mDefaultJSExceptionHandler").let { field ->
123
+ previousExceptionHandler = devSupportManagerClass.getDeclaredField("defaultJSExceptionHandler").let { field ->
124
124
  field.isAccessible = true
125
125
  val previousValue = field[devSupportManager]
126
126
  field[devSupportManager] = defaultJSExceptionHandler
@@ -152,7 +152,7 @@ class ErrorRecovery(
152
152
  }
153
153
 
154
154
  val devSupportManagerClass = devSupportManager.javaClass
155
- devSupportManagerClass.getDeclaredField("mDefaultJSExceptionHandler").let { field ->
155
+ devSupportManagerClass.getDeclaredField("defaultJSExceptionHandler").let { field ->
156
156
  field.isAccessible = true
157
157
  field[devSupportManager] = previousExceptionHandler
158
158
  }
@@ -1,13 +1,13 @@
1
1
  package expo.modules.updates.events
2
2
 
3
- import expo.modules.kotlin.events.EventEmitter
4
3
  import expo.modules.updates.statemachine.UpdatesStateContext
4
+ import java.lang.ref.WeakReference
5
5
 
6
- enum class UpdatesJSEvent(val eventName: String) {
7
- StateChange("Expo.nativeUpdatesStateChangeEvent")
6
+ interface IUpdatesEventManagerObserver {
7
+ fun onStateMachineContextEvent(context: UpdatesStateContext)
8
8
  }
9
9
 
10
10
  interface IUpdatesEventManager {
11
- var eventEmitter: EventEmitter?
11
+ var observer: WeakReference<IUpdatesEventManagerObserver>?
12
12
  fun sendStateMachineContextEvent(context: UpdatesStateContext)
13
13
  }
@@ -1,9 +1,9 @@
1
1
  package expo.modules.updates.events
2
2
 
3
- import expo.modules.kotlin.events.EventEmitter
4
3
  import expo.modules.updates.statemachine.UpdatesStateContext
4
+ import java.lang.ref.WeakReference
5
5
 
6
6
  class NoOpUpdatesEventManager : IUpdatesEventManager {
7
- override var eventEmitter: EventEmitter? = null
7
+ override var observer: WeakReference<IUpdatesEventManagerObserver>? = null
8
8
  override fun sendStateMachineContextEvent(context: UpdatesStateContext) {}
9
9
  }
@@ -1,31 +1,27 @@
1
1
  package expo.modules.updates.events
2
2
 
3
- import expo.modules.kotlin.events.EventEmitter
4
3
  import expo.modules.updates.logging.UpdatesErrorCode
5
4
  import expo.modules.updates.logging.UpdatesLogger
6
5
  import expo.modules.updates.statemachine.UpdatesStateContext
6
+ import java.lang.ref.WeakReference
7
7
 
8
8
  class UpdatesEventManager(private val logger: UpdatesLogger) : IUpdatesEventManager {
9
- override var eventEmitter: EventEmitter? = null
9
+ override var observer: WeakReference<IUpdatesEventManagerObserver>? = null
10
10
 
11
11
  override fun sendStateMachineContextEvent(context: UpdatesStateContext) {
12
- val eventName = UpdatesJSEvent.StateChange.eventName
12
+ logger.debug("Sending state machine context to observer")
13
13
 
14
- val eventEmitter = eventEmitter
15
- if (eventEmitter == null) {
16
- logger.info(
17
- "Could not emit $eventName event; no event emitter was found.",
18
- UpdatesErrorCode.JSRuntimeError
19
- )
14
+ val observer = observer?.get() ?: run {
15
+ logger.debug("Unable to send state machine context to observer, no observer", UpdatesErrorCode.JSRuntimeError)
20
16
  return
21
17
  }
22
18
 
23
19
  try {
24
- eventEmitter.emit(eventName, context.writableMap)
25
- logger.info("Emitted event: name = $eventName")
20
+ observer.onStateMachineContextEvent(context)
21
+ logger.debug("Sent state machine context to observer")
26
22
  } catch (e: Exception) {
27
23
  logger.error(
28
- "Could not emit $eventName event",
24
+ "Could not send state machine context to observer",
29
25
  e,
30
26
  UpdatesErrorCode.JSRuntimeError
31
27
  )
@@ -575,7 +575,7 @@ class FileDownloader(
575
575
 
576
576
  val update = UpdateFactory.getUpdate(preManifest, responseHeaderData, extensions, configuration)
577
577
  if (!SelectionPolicies.matchesFilters(update.updateEntity!!, responseHeaderData.manifestFilters)) {
578
- callback.onFailure(Exception("Manifest filters that do not manifest content for downloaded manifest"))
578
+ callback.onFailure(Exception("Manifest filters do not match manifest content for downloaded manifest"))
579
579
  } else {
580
580
  callback.onSuccess(UpdateResponsePart.ManifestUpdateResponsePart(update))
581
581
  }
@@ -1,8 +1,6 @@
1
1
  package expo.modules.updates.statemachine
2
2
 
3
3
  import android.os.Bundle
4
- import com.facebook.react.bridge.Arguments
5
- import com.facebook.react.bridge.WritableMap
6
4
  import org.json.JSONObject
7
5
  import java.text.SimpleDateFormat
8
6
  import java.util.Date
@@ -113,17 +111,7 @@ class UpdatesStateContext private constructor(
113
111
  }
114
112
 
115
113
  /**
116
- * Creates a WritableMap to be sent to JS on a state change.
117
- */
118
- val writableMap: WritableMap
119
- get() {
120
- val result = Arguments.createMap()
121
- result.putMap("context", Arguments.fromBundle(bundle))
122
- return result
123
- }
124
-
125
- /**
126
- * Creates a Bundle to be returned to JS on a call to nativeStateMachineContext()
114
+ * Creates a Bundle to be synchronized with JS state
127
115
  */
128
116
  val bundle: Bundle
129
117
  get() {
@@ -629,23 +629,29 @@ describe('JS API tests', () => {
629
629
  });
630
630
  await waitForAppToBecomeVisible();
631
631
 
632
- // Check state
632
+ // Check state on launch
633
633
  const isUpdatePending = await testElementValueAsync('state.isUpdatePending');
634
634
  const isUpdateAvailable = await testElementValueAsync('state.isUpdateAvailable');
635
635
  const latestManifestId = await testElementValueAsync('state.latestManifest.id');
636
636
  const downloadedManifestId = await testElementValueAsync('state.downloadedManifest.id');
637
637
  const isRollback = await testElementValueAsync('state.isRollback');
638
-
639
638
  console.warn(`isUpdatePending = ${isUpdatePending}`);
640
639
  console.warn(`isUpdateAvailable = ${isUpdateAvailable}`);
641
640
  console.warn(`isRollback = ${isRollback}`);
642
641
  console.warn(`latestManifestId = ${latestManifestId}`);
643
642
  console.warn(`downloadedManifestId = ${downloadedManifestId}`);
643
+ jestExpect(isUpdateAvailable).toEqual('false');
644
+ jestExpect(isUpdatePending).toEqual('false');
645
+ jestExpect(isRollback).toEqual('false');
646
+ jestExpect(latestManifestId).toEqual('null');
647
+ jestExpect(downloadedManifestId).toEqual('null');
644
648
 
645
649
  const updatesExpoClientEmbeddedString = await testElementValueAsync('updates.expoClient');
646
650
  const constantsExpoConfigEmbeddedString = await testElementValueAsync('constants.expoConfig');
647
651
  console.warn(`updatesExpoClientEmbedded = ${updatesExpoClientEmbeddedString}`);
648
652
  console.warn(`constantsExpoConfigEmbedded = ${constantsExpoConfigEmbeddedString}`);
653
+ const updatesExpoConfigEmbedded = JSON.parse(updatesExpoClientEmbeddedString);
654
+ jestExpect(updatesExpoConfigEmbedded).not.toBeNull();
649
655
 
650
656
  // Now serve a manifest
651
657
  Server.start(Update.serverPort, protocolVersion);
@@ -660,12 +666,16 @@ describe('JS API tests', () => {
660
666
  const latestManifestId2 = await testElementValueAsync('state.latestManifest.id');
661
667
  const downloadedManifestId2 = await testElementValueAsync('state.downloadedManifest.id');
662
668
  const isRollback2 = await testElementValueAsync('state.isRollback');
663
-
664
669
  console.warn(`isUpdatePending2 = ${isUpdatePending2}`);
665
670
  console.warn(`isUpdateAvailable2 = ${isUpdateAvailable2}`);
666
671
  console.warn(`isRollback2 = ${isRollback2}`);
667
672
  console.warn(`latestManifestId2 = ${latestManifestId2}`);
668
673
  console.warn(`downloadedManifestId2 = ${downloadedManifestId2}`);
674
+ jestExpect(isUpdateAvailable2).toEqual('true');
675
+ jestExpect(isUpdatePending2).toEqual('false');
676
+ jestExpect(isRollback2).toEqual('false');
677
+ jestExpect(latestManifestId2).toEqual(manifest.id);
678
+ jestExpect(downloadedManifestId2).toEqual('null');
669
679
 
670
680
  // Download update and expect isUpdatePending to be true
671
681
  await pressTestButtonAsync('downloadUpdate');
@@ -676,12 +686,16 @@ describe('JS API tests', () => {
676
686
  const latestManifestId3 = await testElementValueAsync('state.latestManifest.id');
677
687
  const downloadedManifestId3 = await testElementValueAsync('state.downloadedManifest.id');
678
688
  const isRollback3 = await testElementValueAsync('state.isRollback');
679
-
680
689
  console.warn(`isUpdatePending3 = ${isUpdatePending3}`);
681
690
  console.warn(`isUpdateAvailable3 = ${isUpdateAvailable3}`);
682
691
  console.warn(`isRollback3 = ${isRollback3}`);
683
692
  console.warn(`latestManifestId3 = ${latestManifestId3}`);
684
693
  console.warn(`downloadedManifestId3 = ${downloadedManifestId3}`);
694
+ jestExpect(isUpdateAvailable3).toEqual('true');
695
+ jestExpect(isUpdatePending3).toEqual('true');
696
+ jestExpect(isRollback3).toEqual('false');
697
+ jestExpect(latestManifestId3).toEqual(manifest.id);
698
+ jestExpect(downloadedManifestId3).toEqual(manifest.id);
685
699
 
686
700
  // Terminate and relaunch app, we should be running the update, and back to the default state
687
701
  await device.terminateApp();
@@ -694,13 +708,18 @@ describe('JS API tests', () => {
694
708
  const downloadedManifestId4 = await testElementValueAsync('state.downloadedManifest.id');
695
709
  const isRollback4 = await testElementValueAsync('state.isRollback');
696
710
  const rollbackCommitTime4 = await testElementValueAsync('state.rollbackCommitTime');
697
-
698
711
  console.warn(`isUpdatePending4 = ${isUpdatePending4}`);
699
712
  console.warn(`isUpdateAvailable4 = ${isUpdateAvailable4}`);
700
713
  console.warn(`isRollback4 = ${isRollback4}`);
701
714
  console.warn(`latestManifestId4 = ${latestManifestId4}`);
702
715
  console.warn(`downloadedManifestId4 = ${downloadedManifestId4}`);
703
716
  console.warn(`rollbackCommitTime4 = ${rollbackCommitTime4}`);
717
+ jestExpect(isUpdateAvailable4).toEqual('false');
718
+ jestExpect(isUpdatePending4).toEqual('false');
719
+ jestExpect(isRollback4).toEqual('false');
720
+ jestExpect(latestManifestId4).toEqual('null');
721
+ jestExpect(downloadedManifestId4).toEqual('null');
722
+ jestExpect(rollbackCommitTime4).toEqual('null');
704
723
 
705
724
  const updatesExpoClientUpdateString = await testElementValueAsync('updates.expoClient');
706
725
  const constantsExpoConfigUpdateString = await testElementValueAsync('constants.expoConfig');
@@ -721,13 +740,18 @@ describe('JS API tests', () => {
721
740
  const downloadedManifestId5 = await testElementValueAsync('state.downloadedManifest.id');
722
741
  const isRollback5 = await testElementValueAsync('state.isRollback');
723
742
  const rollbackCommitTime5 = await testElementValueAsync('state.rollbackCommitTime');
724
-
725
743
  console.warn(`isUpdatePending5 = ${isUpdatePending5}`);
726
744
  console.warn(`isUpdateAvailable5 = ${isUpdateAvailable5}`);
727
745
  console.warn(`isRollback5 = ${isRollback5}`);
728
746
  console.warn(`latestManifestId5 = ${latestManifestId5}`);
729
747
  console.warn(`downloadedManifestId5 = ${downloadedManifestId5}`);
730
748
  console.warn(`rollbackCommitTime5 = ${rollbackCommitTime5}`);
749
+ jestExpect(isUpdateAvailable5).toEqual('true');
750
+ jestExpect(isUpdatePending5).toEqual('false');
751
+ jestExpect(isRollback5).toEqual('true');
752
+ jestExpect(latestManifestId5).toEqual('null');
753
+ jestExpect(downloadedManifestId5).toEqual('null');
754
+ jestExpect(rollbackCommitTime5).not.toEqual('null');
731
755
 
732
756
  // Terminate and relaunch app, we should be running the original bundle again, and back to the default state
733
757
  await device.terminateApp();
@@ -753,44 +777,6 @@ describe('JS API tests', () => {
753
777
  console.warn(`updatesExpoConfigRollback = ${updatesExpoConfigRollbackString}`);
754
778
  console.warn(`constantsExpoConfigRollback = ${constantsExpoConfigRollbackString}`);
755
779
 
756
- // Unpack expo config values and check them
757
- const updatesExpoConfigEmbedded = JSON.parse(updatesExpoClientEmbeddedString);
758
- jestExpect(updatesExpoConfigEmbedded).not.toBeNull();
759
-
760
- // Verify correct behavior
761
- // On launch
762
- jestExpect(isUpdateAvailable).toEqual('false');
763
- jestExpect(isUpdatePending).toEqual('false');
764
- jestExpect(isRollback).toEqual('false');
765
- jestExpect(latestManifestId).toEqual('null');
766
- jestExpect(downloadedManifestId).toEqual('null');
767
- // After check for update and getting a manifest
768
- jestExpect(isUpdateAvailable2).toEqual('true');
769
- jestExpect(isUpdatePending2).toEqual('false');
770
- jestExpect(isRollback2).toEqual('false');
771
- jestExpect(latestManifestId2).toEqual(manifest.id);
772
- jestExpect(downloadedManifestId2).toEqual('null');
773
- // After downloading the update
774
- jestExpect(isUpdateAvailable3).toEqual('true');
775
- jestExpect(isUpdatePending3).toEqual('true');
776
- jestExpect(isRollback3).toEqual('false');
777
- jestExpect(latestManifestId3).toEqual(manifest.id);
778
- jestExpect(downloadedManifestId3).toEqual(manifest.id);
779
- // After restarting
780
- jestExpect(isUpdateAvailable4).toEqual('false');
781
- jestExpect(isUpdatePending4).toEqual('false');
782
- jestExpect(isRollback4).toEqual('false');
783
- jestExpect(latestManifestId4).toEqual('null');
784
- jestExpect(downloadedManifestId4).toEqual('null');
785
- jestExpect(rollbackCommitTime4).toEqual('null');
786
- // After check for update and getting a rollback
787
- jestExpect(isUpdateAvailable5).toEqual('true');
788
- jestExpect(isUpdatePending5).toEqual('false');
789
- jestExpect(isRollback5).toEqual('true');
790
- jestExpect(latestManifestId5).toEqual('null');
791
- jestExpect(downloadedManifestId5).toEqual('null');
792
- jestExpect(rollbackCommitTime5).not.toEqual('null');
793
-
794
780
  // Check for update, and expect isRollback to be true
795
781
  await pressTestButtonAsync('triggerParallelFetchAndDownload');
796
782
  await waitForAsynchronousTaskCompletion(4000);
@@ -54,6 +54,7 @@ function getExpoDependencyChunks({
54
54
  'expo-blur',
55
55
  'expo-image',
56
56
  'expo-linear-gradient',
57
+ 'expo-linking',
57
58
  'expo-localization',
58
59
  'expo-crypto',
59
60
  'expo-network',
@@ -474,6 +475,7 @@ function transformAppJsonForE2E(
474
475
  owner: 'expo-ci',
475
476
  runtimeVersion,
476
477
  plugins,
478
+ newArchEnabled: false,
477
479
  android: { ...appJson.expo.android, package: 'dev.expo.updatese2e' },
478
480
  ios: { ...appJson.expo.ios, bundleIdentifier: 'dev.expo.updatese2e' },
479
481
  updates: {
@@ -555,6 +557,7 @@ export function transformAppJsonForUpdatesDisabledE2E(
555
557
  owner: 'expo-ci',
556
558
  runtimeVersion,
557
559
  plugins,
560
+ newArchEnabled: false,
558
561
  android: { ...appJson.expo.android, package: 'dev.expo.updatese2e' },
559
562
  ios: { ...appJson.expo.ios, bundleIdentifier: 'dev.expo.updatese2e' },
560
563
  extra: {
@@ -350,13 +350,13 @@ public class AppController: NSObject {
350
350
  }
351
351
  }
352
352
 
353
- internal static func onEventListenerStartObserving(_ eventEmitter: EXEventEmitterService?) {
354
- _sharedInstance?.eventManager.eventEmitter = eventEmitter
353
+ internal static func setUpdatesEventManagerObserver(_ observer: UpdatesEventManagerObserver) {
354
+ _sharedInstance?.eventManager.observer = observer
355
355
  _sharedInstance?.onEventListenerStartObserving()
356
356
  }
357
357
 
358
- internal static func onEventListenerStopObserving() {
359
- _sharedInstance?.eventManager.eventEmitter = nil
358
+ internal static func removeUpdatesEventManagerObserver() {
359
+ _sharedInstance?.eventManager.observer = nil
360
360
  }
361
361
  }
362
362
 
@@ -3,6 +3,6 @@
3
3
  import ExpoModulesCore
4
4
 
5
5
  internal class NoOpUpdatesEventManager: UpdatesEventManager {
6
- internal weak var eventEmitter: EXEventEmitterService?
6
+ internal weak var observer: (any UpdatesEventManagerObserver)?
7
7
  func sendStateMachineContextEvent(context: UpdatesStateContext) {}
8
8
  }
@@ -9,21 +9,15 @@ internal class QueueUpdatesEventManager: UpdatesEventManager {
9
9
  self.logger = logger
10
10
  }
11
11
 
12
- internal weak var eventEmitter: EXEventEmitterService?
12
+ internal weak var observer: (any UpdatesEventManagerObserver)?
13
13
 
14
14
  internal func sendStateMachineContextEvent(context: UpdatesStateContext) {
15
- logger.info(message: "sendUpdateStateAppContext()")
16
- sendEventToAppContext(EXUpdatesStateChangeEventName, body: [
17
- "context": context.json
18
- ])
19
- }
20
-
21
- private func sendEventToAppContext(_ eventName: String, body: [String: Any?]) {
22
- guard let eventEmitter = eventEmitter else {
23
- logger.info(message: "EXUpdates: Could not emit event: name = \(eventName)", code: .jsRuntimeError)
15
+ logger.debug(message: "Sending state machine context to observer")
16
+ guard let observer = observer else {
17
+ logger.debug(message: "Unable to send state machine context to observer, no observer", code: .jsRuntimeError)
24
18
  return
25
19
  }
26
- logger.debug(message: "sendEventToAppContext: \(eventName), \(body)")
27
- eventEmitter.sendEvent(withName: eventName, body: body)
20
+ observer.onStateMachineContextEvent(context: context)
21
+ logger.debug(message: "Sent state machine context to observer")
28
22
  }
29
23
  }
@@ -2,7 +2,11 @@
2
2
 
3
3
  import ExpoModulesCore
4
4
 
5
+ public protocol UpdatesEventManagerObserver: AnyObject {
6
+ func onStateMachineContextEvent(context: UpdatesStateContext)
7
+ }
8
+
5
9
  public protocol UpdatesEventManager: AnyObject {
6
- var eventEmitter: EXEventEmitterService? { get set }
10
+ var observer: UpdatesEventManagerObserver? { get set }
7
11
  func sendStateMachineContextEvent(context: UpdatesStateContext)
8
12
  }
@@ -11,7 +11,7 @@ import ExpoModulesCore
11
11
  * Expo Go and legacy standalone apps) via EXUpdatesService, an internal module which is overridden
12
12
  * by EXUpdatesBinding, a scoped module, in Expo Go.
13
13
  */
14
- public final class UpdatesModule: Module {
14
+ public final class UpdatesModule: Module, UpdatesEventManagerObserver {
15
15
  public func definition() -> ModuleDefinition {
16
16
  Name("ExpoUpdates")
17
17
 
@@ -23,12 +23,16 @@ public final class UpdatesModule: Module {
23
23
  AppController.sharedInstance.getConstantsForModule().toModuleConstantsMap()
24
24
  }
25
25
 
26
- OnStartObserving {
27
- AppController.onEventListenerStartObserving(self.appContext?.eventEmitter)
26
+ OnStartObserving(EXUpdatesStateChangeEventName) {
27
+ AppController.setUpdatesEventManagerObserver(self)
28
28
  }
29
29
 
30
- OnStopObserving {
31
- AppController.onEventListenerStopObserving()
30
+ OnStopObserving(EXUpdatesStateChangeEventName) {
31
+ AppController.removeUpdatesEventManagerObserver()
32
+ }
33
+
34
+ OnDestroy {
35
+ AppController.removeUpdatesEventManagerObserver()
32
36
  }
33
37
 
34
38
  AsyncFunction("reload") { (promise: Promise) in
@@ -137,4 +141,10 @@ public final class UpdatesModule: Module {
137
141
  }
138
142
  }
139
143
  }
144
+
145
+ public func onStateMachineContextEvent(context: UpdatesStateContext) {
146
+ sendEvent(EXUpdatesStateChangeEventName, [
147
+ "context": context.json
148
+ ])
149
+ }
140
150
  }
@@ -359,7 +359,6 @@ internal class UpdatesStateMachine {
359
359
  // Only change context if transition succeeds
360
360
  context = reducedContext(context, event)
361
361
  logger.info(message: "Updates state change: state = \(state), event = \(event.type), context = \(context)")
362
- // Send context to JS
363
362
  sendContextToJS()
364
363
  }
365
364
  }
@@ -9,11 +9,10 @@ import ExpoModulesTestCore
9
9
  import EXManifests
10
10
 
11
11
  class TestStateChangeEventManager: UpdatesEventManager {
12
- var appContext: ExpoModulesCore.AppContext? = nil
13
-
14
12
  var lastContext: UpdatesStateContext? = nil
13
+ weak var observer: (any EXUpdates.UpdatesEventManagerObserver)?
15
14
 
16
- func sendUpdateStateAppContext(context: UpdatesStateContext) {
15
+ func sendStateMachineContextEvent(context: EXUpdates.UpdatesStateContext) {
17
16
  lastContext = context
18
17
  }
19
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-updates",
3
- "version": "0.26.0",
3
+ "version": "0.26.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",
@@ -40,7 +40,7 @@
40
40
  "@expo/code-signing-certificates": "0.0.5",
41
41
  "@expo/config": "~10.0.0",
42
42
  "@expo/config-plugins": "~9.0.0",
43
- "@expo/fingerprint": "^0.10.0",
43
+ "@expo/fingerprint": "^0.11.0",
44
44
  "@expo/spawn-async": "^1.7.2",
45
45
  "arg": "4.1.0",
46
46
  "chalk": "^4.1.2",
@@ -68,5 +68,5 @@
68
68
  "expo": "*",
69
69
  "react": "*"
70
70
  },
71
- "gitHead": "685ebb8a213326cb33c80281ca8756b374ccb63d"
71
+ "gitHead": "0a07b965c4bef67e7718355a0dc770d524ad3cee"
72
72
  }