@ionic/portals-react-native 0.0.3 → 0.0.4

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/README.md CHANGED
@@ -132,44 +132,24 @@ unsubscribe('channel:topic', subscriptionReference)
132
132
  To see an example of Portals Pub/Sub in action that manages the lifecycle of a subscription with the lifecycle of a React Native component, refer to the [`PubSubLabel`](https://github.com/ionic-team/react-native-ionic-portals/blob/af19df0d66059d85ab8dde493504368c3bf39127/example/App.tsx#L53) implementation in the example project.
133
133
 
134
134
  ### Using Capacitor Plugins
135
- If you need to use any Capacitor plugins, you will have to register them in your Android project. This will also require creating and registering your Portals in native code as well:
136
-
137
- **Android**
138
- ```java
139
- public class MainApplication extends Application implements ReactApplication {
140
- @Override
141
- public void onCreate() {
142
- super.onCreate();
143
-
144
- PortalManager.register("YOUR_PORTAL_KEY_HERE");
145
- PortalManager.newPortal("hello")
146
- .addPlugin(MyCapacitorPlugin.class) // Plugin registration
147
- .setInitialContext(Map.of("greeting", "Hello, world!"))
148
- .setStartDir("portals/hello")
149
- .create();
135
+ If you need to use any Capacitor plugins, the classpath of the Android plugins will have to be provided to the `Portal` `androidPlugins` property.
136
+
137
+ ```javascript
138
+ const helloPortal = {
139
+ name: 'hello',
140
+ startDir: 'portals/hello',
141
+ androidPlugins: ['com.capacitorjs.plugins.camera.CameraPlugin'],
142
+ initialContext: {
143
+ greeting: 'Hello, world!'
150
144
  }
151
- }
145
+ };
152
146
  ```
153
147
 
154
- **iOS**
155
- ```objective-c
156
- @implementation RNAppDelegate
157
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDicationary *)launchOptions {
158
- // React Native boilerplate
159
- [PortalManager register:@"YOUR_PORTAL_KEY_HERE"];
160
- PortalBuilder *builder = [[PortalBuilder alloc] init:@"hello"];
161
- [builder setStartDir:@"portals/hello"];
162
- [builder setInitialContext: @{ @"greeting": @"Hello, world!" }]
163
- Portal *portal = [builder create];
164
- [PortalManager addPortal:portal];
165
- }
166
- @end
167
- ```
148
+ No configuration for iOS is needed since plugins are automatically registered when the Capacitor bridge initializes on iOS.
168
149
 
169
150
  ### Bundling Your Web Apps
170
151
  Currently there is no tooling for bundling your web apps directly as part of @ionic/portals-react-native. Please follow the [native guides](https://ionic.io/docs/portals/how-to/pull-in-web-bundle#setup-the-web-asset-directory) to manage this as part of the native build process.
171
152
 
172
-
173
153
  ## Registration
174
154
 
175
155
  Ionic Portals for React Native requires a key to use. Once you have integrated Portals into your project, login to your ionic account to get a key. See our doc on [how to register for free and get your Portals license key](https://ionic.io/docs/portals/how-to/get-a-product-key) and refer to the [usage](#Usage) section on how to add your key to your React Native application.
@@ -10,12 +10,11 @@ Pod::Spec.new do |s|
10
10
  s.license = package["license"]
11
11
  s.authors = package["author"]
12
12
 
13
- s.platforms = { :ios => "14.0" }
13
+ s.platforms = { :ios => "13.0" }
14
14
  s.source = { :git => "https://github.com/ionic-team/react-native-ionic-portals.git", :tag => "#{s.version}" }
15
15
 
16
16
  s.source_files = "ios/**/*.{h,m,mm,swift}"
17
17
 
18
18
  s.dependency "React-Core"
19
- s.dependency "IonicPortals", "0.5.1"
20
- s.dependency "IonicLiveUpdates", "0.0.5"
19
+ s.dependency "IonicPortals", "~> 0.6.1"
21
20
  end
@@ -38,9 +38,14 @@ android {
38
38
  lintOptions {
39
39
  disable 'GradleCompatible'
40
40
  }
41
- compileOptions {
42
- sourceCompatibility JavaVersion.VERSION_1_8
43
- targetCompatibility JavaVersion.VERSION_1_8
41
+ }
42
+
43
+ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
44
+ sourceCompatibility = JavaVersion.VERSION_1_8
45
+ targetCompatibility = JavaVersion.VERSION_1_8
46
+
47
+ kotlinOptions {
48
+ freeCompilerArgs += '-Xopt-in=kotlin.RequiresOptIn'
44
49
  }
45
50
  }
46
51
 
@@ -116,7 +121,12 @@ repositories {
116
121
  }
117
122
 
118
123
  dependencies {
119
- // noinspection GradleDynamicVersion
124
+ //noinspection GradleDynamicVersion
120
125
  api 'com.facebook.react:react-native:+'
121
- implementation "io.ionic:portals:0.5.0"
126
+ //noinspection GradleDynamicVersion
127
+ api "io.ionic:portals:0.6.+"
128
+ //noinspection GradleDynamicVersion
129
+ api "io.ionic:liveupdates:0.0.+"
130
+
131
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0"
122
132
  }
@@ -0,0 +1,187 @@
1
+ package io.ionic.portals.reactnative
2
+
3
+ import com.facebook.react.bridge.*
4
+ import io.ionic.liveupdates.LiveUpdate
5
+ import io.ionic.liveupdates.LiveUpdateManager
6
+ import io.ionic.liveupdates.network.FailStep
7
+ import io.ionic.liveupdates.network.SyncCallback
8
+ import kotlinx.coroutines.*
9
+ import kotlinx.coroutines.channels.awaitClose
10
+ import kotlinx.coroutines.flow.callbackFlow
11
+ import kotlinx.coroutines.flow.fold
12
+ import java.util.concurrent.Executors
13
+
14
+ internal class LiveUpdatesModule(reactContext: ReactApplicationContext) :
15
+ ReactContextBaseJavaModule(reactContext) {
16
+
17
+ override fun getName() = "IONLiveUpdatesManager"
18
+
19
+ private val liveUpdateScope = CoroutineScope(
20
+ Executors.newFixedThreadPool(4)
21
+ .asCoroutineDispatcher()
22
+ )
23
+
24
+ private fun callbackToMap(
25
+ liveUpdate: LiveUpdate,
26
+ failStep: FailStep?,
27
+ failMsg: String?
28
+ ): ReadableMap =
29
+ if (failStep != null) {
30
+ val map = WritableNativeMap()
31
+ map.putString("appId", liveUpdate.appId)
32
+ map.putString("failStep", failStep.name)
33
+ map.putString("message", failMsg ?: "Sync failed for unknown reason")
34
+ map
35
+ } else {
36
+ liveUpdate.toReadableMap()
37
+ }
38
+
39
+ private fun callbackToResult(
40
+ liveUpdate: LiveUpdate,
41
+ failStep: FailStep?,
42
+ failMsg: String?
43
+ ): LiveUpdateResult =
44
+ if (failStep != null) {
45
+ LiveUpdateError(
46
+ appId = liveUpdate.appId,
47
+ failStep = failStep.name,
48
+ failMsg = failMsg ?: "Sync failed for unknown reason"
49
+ )
50
+ } else {
51
+ LiveUpdateSuccess(liveUpdate)
52
+ }
53
+
54
+
55
+ @ReactMethod
56
+ fun addLiveUpdate(map: ReadableMap) {
57
+ val appId = map.getString("appId") ?: return
58
+ val channel = map.getString("channel") ?: return
59
+
60
+ LiveUpdateManager.addLiveUpdateInstance(
61
+ context = reactApplicationContext,
62
+ liveUpdate = LiveUpdate(appId, channel)
63
+ )
64
+ }
65
+
66
+ @ReactMethod
67
+ fun syncOne(appId: String, promise: Promise) {
68
+ LiveUpdateManager.sync(
69
+ context = reactApplicationContext,
70
+ appId = appId,
71
+ callback = object : SyncCallback {
72
+ override fun onAppComplete(
73
+ liveUpdate: LiveUpdate,
74
+ failStep: FailStep?,
75
+ failMsg: String?
76
+ ) {
77
+ val map = callbackToMap(liveUpdate, failStep, failMsg)
78
+ promise.resolve(map)
79
+ }
80
+
81
+ override fun onSyncComplete() {
82
+ // do nothing
83
+ }
84
+ }
85
+ )
86
+ }
87
+
88
+ @ReactMethod
89
+ fun syncSome(appIds: ReadableArray, promise: Promise) {
90
+ @Suppress("NAME_SHADOWING")
91
+ val appIds = (0 until appIds.size())
92
+ .mapNotNull(appIds::getString)
93
+ .toTypedArray()
94
+
95
+ sync(appIds, promise)
96
+ }
97
+
98
+ @ReactMethod
99
+ fun syncAll(promise: Promise) {
100
+ sync(emptyArray(), promise)
101
+ }
102
+
103
+ @OptIn(ExperimentalCoroutinesApi::class)
104
+ private fun sync(appIds: Array<String>, promise: Promise) {
105
+ liveUpdateScope.launch {
106
+ val results = callbackFlow {
107
+ LiveUpdateManager.sync(
108
+ context = reactApplicationContext,
109
+ appIds = appIds,
110
+ callback = object : SyncCallback {
111
+ override fun onAppComplete(
112
+ liveUpdate: LiveUpdate,
113
+ failStep: FailStep?,
114
+ failMsg: String?
115
+ ) {
116
+ trySend(callbackToResult(liveUpdate, failStep, failMsg))
117
+ }
118
+
119
+ override fun onSyncComplete() {
120
+ close()
121
+ }
122
+ }
123
+ )
124
+
125
+ awaitClose { cancel() }
126
+ }
127
+
128
+ val syncResults = results.fold(SyncResults.empty()) { syncResults, result ->
129
+ when (result) {
130
+ is LiveUpdateSuccess -> syncResults.liveUpdates.add(result.liveUpdate)
131
+ is LiveUpdateError -> syncResults.errors.add(result)
132
+ }
133
+
134
+ return@fold syncResults
135
+ }
136
+
137
+ promise.resolve(syncResults.asReadableMap)
138
+ }
139
+ }
140
+ }
141
+
142
+ fun LiveUpdate.toReadableMap(): ReadableMap {
143
+ val map = WritableNativeMap()
144
+ map.putString("appId", appId)
145
+ map.putString("channel", channelName)
146
+ return map
147
+ }
148
+
149
+ private sealed class LiveUpdateResult
150
+
151
+ private data class LiveUpdateError(val appId: String, val failStep: String, val failMsg: String) :
152
+ LiveUpdateResult() {
153
+ val asReadableMap: ReadableMap
154
+ get() {
155
+ val map = WritableNativeMap()
156
+ map.putString("appId", appId)
157
+ map.putString("failStep", failStep)
158
+ map.putString("message", failMsg)
159
+ return map
160
+ }
161
+ }
162
+
163
+ private data class LiveUpdateSuccess(val liveUpdate: LiveUpdate) : LiveUpdateResult()
164
+
165
+ private data class SyncResults(
166
+ val liveUpdates: MutableList<LiveUpdate>,
167
+ val errors: MutableList<LiveUpdateError>
168
+ ) {
169
+ val asReadableMap: ReadableMap
170
+ get() {
171
+ val map = WritableNativeMap()
172
+
173
+ val liveUpdatesArray = WritableNativeArray()
174
+ liveUpdates.forEach { liveUpdatesArray.pushMap(it.toReadableMap()) }
175
+ map.putArray("liveUpdates", liveUpdatesArray)
176
+
177
+ val errorsArray = WritableNativeArray()
178
+ errors.forEach { errorsArray.pushMap(it.asReadableMap) }
179
+ map.putArray("errors", errorsArray)
180
+
181
+ return map
182
+ }
183
+
184
+ companion object {
185
+ fun empty() = SyncResults(mutableListOf(), mutableListOf())
186
+ }
187
+ }
@@ -1,5 +1,6 @@
1
1
  package io.ionic.portals.reactnative
2
2
 
3
+ import android.util.Log
3
4
  import android.view.Choreographer
4
5
  import android.view.View
5
6
  import android.view.ViewGroup
@@ -11,16 +12,16 @@ import com.facebook.react.uimanager.ThemedReactContext
11
12
  import com.facebook.react.uimanager.ViewGroupManager
12
13
  import com.facebook.react.uimanager.annotations.ReactProp
13
14
  import com.getcapacitor.JSObject
15
+ import com.getcapacitor.Plugin
16
+ import io.ionic.liveupdates.LiveUpdate
14
17
  import io.ionic.portals.*
15
18
  import org.json.JSONArray
16
19
  import org.json.JSONException
17
20
  import org.json.JSONObject
18
21
 
19
- class PortalManagerModule(reactContext: ReactApplicationContext) :
22
+ internal class PortalManagerModule(reactContext: ReactApplicationContext) :
20
23
  ReactContextBaseJavaModule(reactContext) {
21
- override fun getName(): String {
22
- return "IONPortalManager"
23
- }
24
+ override fun getName() = "IONPortalManager"
24
25
 
25
26
  @ReactMethod
26
27
  fun register(key: String) {
@@ -29,35 +30,51 @@ class PortalManagerModule(reactContext: ReactApplicationContext) :
29
30
 
30
31
  @ReactMethod
31
32
  fun addPortal(map: ReadableMap) {
32
- map.getString("name")?.let { name ->
33
- val startDir = map.getString("startDir")
34
- val initialContext = map.getMap("initialContext")?.toHashMap()
35
-
36
- val portalBuilder = PortalBuilder(name)
37
-
38
- if (startDir != null) {
39
- portalBuilder.setStartDir(startDir)
33
+ val name = map.getString("name") ?: return
34
+ val portalBuilder = PortalBuilder(name)
35
+
36
+ map.getString("startDir")
37
+ ?.let(portalBuilder::setStartDir)
38
+
39
+ map.getMap("initialContext")
40
+ ?.toHashMap()
41
+ ?.let(portalBuilder::setInitialContext)
42
+
43
+ map.getArray("androidPlugins")
44
+ ?.toArrayList()
45
+ ?.mapNotNull { it as? String }
46
+ ?.map {
47
+ Class.forName(it)
48
+ .asSubclass(Plugin::class.java)
40
49
  }
41
-
42
- if (initialContext != null) {
43
- portalBuilder.setInitialContext(initialContext)
50
+ ?.forEach(portalBuilder::addPlugin)
51
+
52
+ map.getMap("liveUpdate")
53
+ ?.let { readableMap ->
54
+ val appId = readableMap.getString("appId") ?: return@let null
55
+ val channel = readableMap.getString("channel") ?: return@let null
56
+ val syncOnAdd = readableMap.getBoolean("syncOnAdd")
57
+ Pair(LiveUpdate(appId, channel), syncOnAdd)
58
+ }
59
+ ?.let { pair ->
60
+ portalBuilder.setLiveUpdateConfig(
61
+ context = reactApplicationContext,
62
+ liveUpdateConfig = pair.first,
63
+ updateOnAppLoad = pair.second
64
+ )
44
65
  }
45
66
 
46
- // TODO: We need to figure out if we can register plugins from javascript
47
- val portal = portalBuilder
48
- .addPlugin(PortalsPlugin::class.java)
49
- .create()
67
+ val portal = portalBuilder
68
+ .addPlugin(PortalsPlugin::class.java)
69
+ .create()
50
70
 
51
- PortalManager.addPortal(portal)
52
- }
71
+ PortalManager.addPortal(portal)
53
72
  }
54
73
  }
55
74
 
56
- class PortalsPubSubModule(reactContext: ReactApplicationContext) :
75
+ internal class PortalsPubSubModule(reactContext: ReactApplicationContext) :
57
76
  ReactContextBaseJavaModule(reactContext) {
58
- override fun getName(): String {
59
- return "IONPortalsPubSub"
60
- }
77
+ override fun getName() = "IONPortalPubSub"
61
78
 
62
79
  @ReactMethod
63
80
  fun subscribe(topic: String, promise: Promise) {
@@ -91,7 +108,7 @@ class PortalsPubSubModule(reactContext: ReactApplicationContext) :
91
108
  }
92
109
  }
93
110
 
94
- fun JSONObject.toReactMap(): ReadableMap =
111
+ private fun JSONObject.toReactMap(): ReadableMap =
95
112
  keys().asSequence().fold(WritableNativeMap()) { map, key ->
96
113
  try {
97
114
  when (val value = get(key)) {
@@ -110,7 +127,7 @@ fun JSONObject.toReactMap(): ReadableMap =
110
127
  return@fold map
111
128
  }
112
129
 
113
- fun JSONArray.toReactArray(): ReadableArray =
130
+ private fun JSONArray.toReactArray(): ReadableArray =
114
131
  (0 until length()).fold(WritableNativeArray()) { array, index ->
115
132
  try {
116
133
  when (val value = get(index)) {
@@ -129,26 +146,44 @@ fun JSONArray.toReactArray(): ReadableArray =
129
146
  return@fold array
130
147
  }
131
148
 
132
- fun ReadableMap.toJSObject(): JSObject = JSObject.fromJSONObject(JSONObject(toHashMap()))
149
+ private fun ReadableMap.toJSObject(): JSObject = JSObject.fromJSONObject(JSONObject(toHashMap()))
150
+
151
+ private data class PortalViewState(
152
+ var fragment: PortalFragment?,
153
+ var portal: Portal?,
154
+ var initialContext: HashMap<String, Any>?
155
+ )
133
156
 
134
- class PortalViewManager(private val context: ReactApplicationContext) :
157
+ internal class PortalViewManager(private val context: ReactApplicationContext) :
135
158
  ViewGroupManager<FrameLayout>() {
136
159
  private val createId = 1
137
- private var portal: Portal? = null
160
+ private val fragmentMap = mutableMapOf<Int, PortalViewState>()
138
161
 
139
162
  @ReactProp(name = "name")
140
163
  fun setPortal(viewGroup: ViewGroup, portalName: String) {
141
- portal = PortalManager.getPortal(portalName)
164
+ when (val viewState = fragmentMap[viewGroup.id]) {
165
+ null -> fragmentMap[viewGroup.id] = PortalViewState(
166
+ fragment = null,
167
+ portal = PortalManager.getPortal(portalName),
168
+ initialContext = null
169
+ )
170
+ else -> viewState.portal = PortalManager.getPortal(portalName)
171
+ }
142
172
  }
143
173
 
144
174
  @ReactProp(name = "initialContext")
145
175
  fun setInitialContext(viewGroup: ViewGroup, initialContext: ReadableMap) {
146
- portal?.setInitialContext(initialContext.toHashMap())
176
+ when (val viewState = fragmentMap[viewGroup.id]) {
177
+ null -> fragmentMap[viewGroup.id] = PortalViewState(
178
+ fragment = null,
179
+ portal = null,
180
+ initialContext = initialContext.toHashMap()
181
+ )
182
+ else -> viewState.initialContext = initialContext.toHashMap()
183
+ }
147
184
  }
148
185
 
149
- override fun getName(): String {
150
- return "AndroidPortalView"
151
- }
186
+ override fun getName() = "AndroidPortalView"
152
187
 
153
188
  override fun createViewInstance(reactContext: ThemedReactContext): FrameLayout {
154
189
  return FrameLayout(reactContext)
@@ -161,6 +196,8 @@ class PortalViewManager(private val context: ReactApplicationContext) :
161
196
  override fun receiveCommand(root: FrameLayout, commandId: String?, args: ReadableArray?) {
162
197
  super.receiveCommand(root, commandId, args)
163
198
  val viewId = args?.getInt(0) ?: return
199
+
200
+ @Suppress("NAME_SHADOWING")
164
201
  val commandId = commandId?.toIntOrNull() ?: return
165
202
 
166
203
  when (commandId) {
@@ -169,11 +206,17 @@ class PortalViewManager(private val context: ReactApplicationContext) :
169
206
  }
170
207
 
171
208
  private fun createFragment(root: FrameLayout, viewId: Int) {
172
- val portal = portal ?: return
209
+ val viewState = fragmentMap[viewId] ?: return
210
+ val portal = viewState.portal ?: return
211
+
173
212
  val parentView = root.findViewById<ViewGroup>(viewId)
174
213
  setupLayout(parentView)
175
214
 
176
215
  val portalFragment = PortalFragment(portal)
216
+ viewState.initialContext?.let(portalFragment::setInitialContext)
217
+
218
+ viewState.fragment = portalFragment
219
+
177
220
  val fragmentActivity = context.currentActivity as? FragmentActivity ?: return
178
221
  fragmentActivity.supportFragmentManager
179
222
  .beginTransaction()
@@ -181,6 +224,23 @@ class PortalViewManager(private val context: ReactApplicationContext) :
181
224
  .commit()
182
225
  }
183
226
 
227
+ override fun onDropViewInstance(view: FrameLayout) {
228
+ super.onDropViewInstance(view)
229
+ val viewState = fragmentMap[view.id] ?: return
230
+
231
+ try {
232
+ viewState.fragment
233
+ ?.parentFragmentManager
234
+ ?.beginTransaction()
235
+ ?.remove(viewState.fragment!!)
236
+ ?.commit()
237
+ } catch (e: IllegalStateException) {
238
+ Log.i("io.ionic.portals.rn", "Parent fragment manager not available")
239
+ }
240
+
241
+ fragmentMap.remove(view.id)
242
+ }
243
+
184
244
  private fun setupLayout(view: ViewGroup) {
185
245
  Choreographer.getInstance().postFrameCallback {
186
246
  layoutChildren(view)
@@ -10,7 +10,8 @@ class ReactNativePortalsPackage : ReactPackage {
10
10
  override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
11
11
  return listOf(
12
12
  PortalManagerModule(reactContext),
13
- PortalsPubSubModule(reactContext)
13
+ PortalsPubSubModule(reactContext),
14
+ LiveUpdatesModule(reactContext)
14
15
  )
15
16
  }
16
17
 
@@ -0,0 +1,16 @@
1
+ //
2
+ // LiveUpdatesManager.m
3
+ // ReactNativePortals
4
+ //
5
+ // Created by Steven Sherry on 6/21/22.
6
+ // Copyright © 2022 Facebook. All rights reserved.
7
+ //
8
+
9
+ #import <React/RCTBridgeModule.h>
10
+
11
+ @interface RCT_EXTERN_MODULE(IONLiveUpdatesManager, NSObject)
12
+ RCT_EXTERN_METHOD(addLiveUpdate: (NSDictionary) liveUpdate)
13
+ RCT_EXTERN_METHOD(syncOne: (NSString *) appId resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
14
+ RCT_EXTERN_METHOD(syncSome: (NSArray) appIds resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
15
+ RCT_EXTERN_METHOD(syncAll: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
16
+ @end
package/ios/Podfile CHANGED
@@ -9,6 +9,6 @@ target 'ReactNativePortals' do
9
9
  use_frameworks!
10
10
  use_react_native!(:path => config["reactNativePath"])
11
11
  # Pods for ReactNativePortals
12
- pod 'IonicPortals', '~> 0.5.1'
12
+ pod 'IonicPortals', '~> 0.6.1'
13
13
  end
14
14
 
package/ios/Podfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PODS:
2
2
  - boost-for-react-native (1.63.0)
3
- - Capacitor (3.4.3):
3
+ - Capacitor (3.6.0):
4
4
  - CapacitorCordova
5
- - CapacitorCordova (3.4.3)
5
+ - CapacitorCordova (3.6.0)
6
6
  - DoubleConversion (1.1.6)
7
7
  - FBLazyVector (0.63.4)
8
8
  - FBReactNativeSpec (0.63.4):
@@ -22,11 +22,10 @@ PODS:
22
22
  - DoubleConversion
23
23
  - glog
24
24
  - glog (0.3.5)
25
- - IonicLiveUpdates (0.0.5):
26
- - ZIPFoundation
27
- - IonicPortals (0.5.1):
28
- - Capacitor
29
- - IonicLiveUpdates
25
+ - IonicLiveUpdates (0.1.1)
26
+ - IonicPortals (0.6.1):
27
+ - Capacitor (~> 3.5)
28
+ - IonicLiveUpdates (~> 0.1.0)
30
29
  - RCTRequired (0.63.4)
31
30
  - RCTTypeSafety (0.63.4):
32
31
  - FBLazyVector (= 0.63.4)
@@ -254,7 +253,6 @@ PODS:
254
253
  - React-cxxreact (= 0.63.4)
255
254
  - React-jsi (= 0.63.4)
256
255
  - Yoga (1.14.0)
257
- - ZIPFoundation (0.9.13)
258
256
 
259
257
  DEPENDENCIES:
260
258
  - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
@@ -262,7 +260,7 @@ DEPENDENCIES:
262
260
  - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
263
261
  - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
264
262
  - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
265
- - IonicPortals (~> 0.5.1)
263
+ - IonicPortals (~> 0.6.1)
266
264
  - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
267
265
  - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
268
266
  - React (from `../node_modules/react-native/`)
@@ -294,7 +292,6 @@ SPEC REPOS:
294
292
  - CapacitorCordova
295
293
  - IonicLiveUpdates
296
294
  - IonicPortals
297
- - ZIPFoundation
298
295
 
299
296
  EXTERNAL SOURCES:
300
297
  DoubleConversion:
@@ -352,15 +349,15 @@ EXTERNAL SOURCES:
352
349
 
353
350
  SPEC CHECKSUMS:
354
351
  boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
355
- Capacitor: df9b3339e2ccf9fcfa19f90073a83454b3113691
356
- CapacitorCordova: 7a09a302f17e14a308291bb3fa2b01ad2e4dfcaf
352
+ Capacitor: 28d6f7c3b02858b0696c98d27527ffb1ac8aba8f
353
+ CapacitorCordova: 23b4def1cd6a8c463074916376f511d7446d683e
357
354
  DoubleConversion: cde416483dac037923206447da6e1454df403714
358
355
  FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
359
356
  FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
360
357
  Folly: b73c3869541e86821df3c387eb0af5f65addfab4
361
358
  glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
362
- IonicLiveUpdates: f3e54dbb5a330eb820a823477c5a75cd4470b65d
363
- IonicPortals: 4f1621c0fc949119ef78d1f5c39c8de9ba3e12c7
359
+ IonicLiveUpdates: 5fb89c6faed266d083691e64f33710211edb3839
360
+ IonicPortals: 17b9ee9ae513fc3906b062bdd0b7492db94e38ce
364
361
  RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e
365
362
  RCTTypeSafety: 8c9c544ecbf20337d069e4ae7fd9a377aadf504b
366
363
  React: b0a957a2c44da4113b0c4c9853d8387f8e64e615
@@ -382,8 +379,7 @@ SPEC CHECKSUMS:
382
379
  React-RCTVibration: ae4f914cfe8de7d4de95ae1ea6cc8f6315d73d9d
383
380
  ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b
384
381
  Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
385
- ZIPFoundation: ae5b4b813d216d3bf0a148773267fff14bd51d37
386
382
 
387
- PODFILE CHECKSUM: 3d4e1ae438899ba8709c2e19e767a9a9cced011b
383
+ PODFILE CHECKSUM: 67d6b2cc79c25d2c4dcf32d6e3c6d6e6defffdb1
388
384
 
389
385
  COCOAPODS: 1.11.2
@@ -9,7 +9,7 @@
9
9
  #import <React/RCTBridgeModule.h>
10
10
  #import <React/RCTEventEmitter.h>
11
11
 
12
- @interface RCT_EXTERN_MODULE(IONPortalsPubSub, RCTEventEmitter)
12
+ @interface RCT_EXTERN_MODULE(IONPortalPubSub, RCTEventEmitter)
13
13
  RCT_EXTERN_METHOD(subscribe: (NSString *) topic resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
14
14
  RCT_EXTERN_METHOD(unsubscribe: (NSString *) topic subscriptionRef: (NSNumber _Nonnull) subscriptionRef)
15
15
  RCT_EXTERN_METHOD(publish: (NSString *) topic data: (id) data)
@@ -1,27 +1,37 @@
1
1
  import Foundation
2
2
  import IonicPortals
3
+ import IonicLiveUpdates
3
4
  import React
4
5
  import UIKit
6
+ import Capacitor
5
7
 
6
8
  @objc(IONPortalManager)
7
- class PortalManager: NSObject {
8
- private typealias IonPortalManager = IonicPortals.PortalManager
9
+ public class PortalManager: NSObject {
10
+ private static var portals: [String: Portal] = [:]
11
+
12
+ public static func register(_ key: String) {
13
+ PortalsRegistrationManager.shared.register(key: key)
14
+ }
15
+
16
+ public static func add(_ portal: Portal) {
17
+ portals[portal.name] = portal
18
+ }
19
+
20
+ static func getPortal(named name: String) -> Portal? { portals[name] }
9
21
 
10
22
  @objc func register(_ key: String) {
11
- IonPortalManager.register(key)
23
+ Self.register(key)
12
24
  }
13
25
 
14
26
  @objc func addPortal(_ portalDict: [String: Any]) {
15
- guard let name = portalDict["name"] as? String else { return }
16
- let portal = Portal(name, portalDict["startDir"] as? String)
17
- portal.initialContext = portalDict["initialContext"] as? [String: Any]
18
- IonPortalManager.addPortal(portal)
27
+ guard let portal = Portal(portalDict) else { return }
28
+ Self.add(portal)
19
29
  }
20
30
 
21
31
  @objc static func requiresMainQueueSetup() -> Bool { true }
22
32
  }
23
33
 
24
- @objc(IONPortalsPubSub)
34
+ @objc(IONPortalPubSub)
25
35
  class PortalsPubSub: RCTEventEmitter {
26
36
  private let eventName = "PortalsSubscription"
27
37
 
@@ -30,7 +40,7 @@ class PortalsPubSub: RCTEventEmitter {
30
40
  }
31
41
 
32
42
  @objc func subscribe(_ topic: String, resolver: RCTPromiseResolveBlock, rejector: RCTPromiseRejectBlock) {
33
- let subRef = PortalsPlugin.subscribe(topic) { [weak self] result in
43
+ let subRef = IonicPortals.PortalsPubSub.subscribe(topic) { [weak self] result in
34
44
  guard let self = self else { return }
35
45
  self.sendEvent(
36
46
  withName: self.eventName,
@@ -46,11 +56,11 @@ class PortalsPubSub: RCTEventEmitter {
46
56
  }
47
57
 
48
58
  @objc func unsubscribe(_ topic: String, subscriptionRef: NSNumber) {
49
- PortalsPlugin.unsubscribe(topic, subscriptionRef.intValue)
59
+ IonicPortals.PortalsPubSub.unsubscribe(from: topic, subscriptionRef: subscriptionRef.intValue)
50
60
  }
51
61
 
52
62
  @objc func publish(_ topic: String, data: Any) {
53
- PortalsPlugin.publish(topic, data)
63
+ IONPortalsPubSub.publish(message: data, topic: topic)
54
64
  }
55
65
 
56
66
  override class func requiresMainQueueSetup() -> Bool { true }
@@ -63,7 +73,7 @@ class PortalViewManager: RCTViewManager {
63
73
  }
64
74
 
65
75
  class PortalView: UIView {
66
- private var webView: PortalWebView?
76
+ private var webView: PortalUIView?
67
77
 
68
78
  @objc var name: String? {
69
79
  get {
@@ -73,7 +83,7 @@ class PortalView: UIView {
73
83
 
74
84
  set {
75
85
  guard let portalName = newValue else { return }
76
- _portal = try? IonicPortals.PortalManager.getPortal(portalName)
86
+ _portal = PortalManager.getPortal(named: portalName)
77
87
  }
78
88
  }
79
89
 
@@ -85,8 +95,8 @@ class PortalView: UIView {
85
95
 
86
96
  set {
87
97
  guard let name = name else { return }
88
- _portal = try? IonicPortals.PortalManager.getPortal(name)
89
- _portal?.initialContext = newValue
98
+ _portal = PortalManager.getPortal(named: name)
99
+ _portal?.initialContext = JSTypes.coerceDictionaryToJSObject(newValue) ?? [:]
90
100
  }
91
101
  }
92
102
 
@@ -96,7 +106,7 @@ class PortalView: UIView {
96
106
  DispatchQueue.main.async { [weak self] in
97
107
  guard let self = self else { return }
98
108
  self.webView?.removeFromSuperview()
99
- let webView = PortalWebView(portal: portal)
109
+ let webView = PortalUIView(portal: portal)
100
110
  webView.translatesAutoresizingMaskIntoConstraints = false
101
111
  self.addSubview(webView)
102
112
  NSLayoutConstraint.activate([
@@ -111,3 +121,142 @@ class PortalView: UIView {
111
121
  }
112
122
  }
113
123
 
124
+ extension Portal {
125
+ init?(_ dict: [String: Any]) {
126
+ guard let name = dict["name"] as? String else { return nil }
127
+ self.init(
128
+ name: name,
129
+ startDir: dict["startDir"] as? String,
130
+ initialContext: JSTypes.coerceDictionaryToJSObject(dict["initialContext"] as? [String: Any]) ?? [:],
131
+ liveUpdateConfig: (dict["liveUpdate"] as? [String: Any]).flatMap(LiveUpdate.init)
132
+ )
133
+ }
134
+ }
135
+
136
+ extension LiveUpdate {
137
+ init?(_ dict: [String: Any]) {
138
+ guard let appId = dict["appId"] as? String,
139
+ let channel = dict["channel"] as? String,
140
+ let syncOnAdd = dict["syncOnAdd"] as? Bool
141
+ else { return nil }
142
+
143
+ self.init(appId: appId, channel: channel, syncOnAdd: syncOnAdd)
144
+ }
145
+ }
146
+
147
+ extension LiveUpdate {
148
+ var dict: [String: Any] {
149
+ return [
150
+ "appId": appId,
151
+ "channel": channel,
152
+ "syncOnAdd": syncOnAdd
153
+ ]
154
+ }
155
+ }
156
+
157
+ extension LiveUpdateManager.Error {
158
+ var dict: [String: Any] {
159
+ return [
160
+ "appId": appId,
161
+ "failStep": failStep.rawValue.uppercased(),
162
+ "message": localizedDescription
163
+ ]
164
+ }
165
+ }
166
+
167
+ private struct SyncResults {
168
+ var liveUpdates: [LiveUpdate]
169
+ var errors: [LiveUpdateManager.Error]
170
+ }
171
+
172
+ extension SyncResults {
173
+ var dict: [String: Any] {
174
+ return [
175
+ "liveUpdates": liveUpdates.map(\.dict),
176
+ "errors": errors.map(\.dict)
177
+ ]
178
+ }
179
+ }
180
+
181
+ @objc(IONLiveUpdatesManager)
182
+ public class LiveUpdatesManager: NSObject {
183
+ private var lum = LiveUpdateManager.shared
184
+
185
+ @objc func addLiveUpdate(_ dict: [String: Any]) {
186
+ guard let liveUpdate = LiveUpdate(dict) else { return }
187
+ try? lum.add(liveUpdate)
188
+ }
189
+
190
+ @objc func syncOne(_ appId: String, resolver: @escaping RCTPromiseResolveBlock, rejector: @escaping RCTPromiseRejectBlock) {
191
+ lum.sync(appId: appId, isParallel: true) { result in
192
+ switch result {
193
+ case .success(let update):
194
+ resolver(update.dict)
195
+ case .failure(let error):
196
+ rejector(nil, nil, error)
197
+ }
198
+ }
199
+ }
200
+
201
+ @objc func syncSome(_ appIds: [String], resolver: @escaping RCTPromiseResolveBlock, rejector: RCTPromiseRejectBlock) {
202
+ Task {
203
+ let syncResult = await lum.syncSome(appIds)
204
+ resolver(syncResult.dict)
205
+ }
206
+ }
207
+
208
+ @objc func syncAll(_ resolver: @escaping RCTPromiseResolveBlock, rejector: RCTPromiseRejectBlock) {
209
+ Task {
210
+ let syncResult = await lum.syncAll()
211
+ resolver(syncResult.dict)
212
+ }
213
+ }
214
+
215
+ @objc static func requiresMainQueueSetup() -> Bool { true }
216
+ }
217
+
218
+ extension LiveUpdateManager {
219
+ fileprivate func syncSome(_ appIds: [String]) async -> SyncResults {
220
+ await _syncSome(appIds).syncResults
221
+ }
222
+
223
+ private func _syncSome(_ appIds: [String]) -> AsyncStream<Result<LiveUpdate, LiveUpdateManager.Error>> {
224
+ AsyncStream { continuation in
225
+ sync(appIds: appIds, isParallel: true) {
226
+ continuation.finish()
227
+ } appComplete: { result in
228
+ continuation.yield(result)
229
+ }
230
+ }
231
+ }
232
+
233
+ fileprivate func syncAll() async -> SyncResults {
234
+ await _syncAll().syncResults
235
+ }
236
+
237
+
238
+ private func _syncAll() -> AsyncStream<Result<LiveUpdate, LiveUpdateManager.Error>> {
239
+ AsyncStream { continuation in
240
+ sync(isParallel: true) {
241
+ continuation.finish()
242
+ } appComplete: { result in
243
+ continuation.yield(result)
244
+ }
245
+ }
246
+ }
247
+ }
248
+
249
+ extension AsyncStream where Element == Result<LiveUpdate, LiveUpdateManager.Error> {
250
+ fileprivate var syncResults: SyncResults {
251
+ get async {
252
+ await reduce(into: SyncResults(liveUpdates: [], errors: [])) { acc, next in
253
+ switch next {
254
+ case .success(let liveUpdate):
255
+ acc.liveUpdates.append(liveUpdate)
256
+ case .failure(let error):
257
+ acc.errors.append(error)
258
+ }
259
+ }
260
+ }
261
+ }
262
+ }
@@ -13,6 +13,7 @@
13
13
  A7128A0827F7A16200DADDF3 /* ReactNativePortals-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FF95D5245B92E700C19C63 /* ReactNativePortals-Bridging-Header.h */; };
14
14
  A7128A0927F7A16200DADDF3 /* PortalsPubSub.m in Sources */ = {isa = PBXBuildFile; fileRef = A71289F827F79D4000DADDF3 /* PortalsPubSub.m */; };
15
15
  A7128A0A27F7A16200DADDF3 /* PortalView.m in Sources */ = {isa = PBXBuildFile; fileRef = A71289F727F79CDC00DADDF3 /* PortalView.m */; };
16
+ A748ABFC28626EC300F26852 /* LiveUpdatesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A748ABFB28626EC300F26852 /* LiveUpdatesManager.m */; };
16
17
  /* End PBXBuildFile section */
17
18
 
18
19
  /* Begin PBXFileReference section */
@@ -21,6 +22,7 @@
21
22
  A71289F827F79D4000DADDF3 /* PortalsPubSub.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PortalsPubSub.m; sourceTree = "<group>"; };
22
23
  A71289F927F79EB200DADDF3 /* PortalManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PortalManager.m; sourceTree = "<group>"; };
23
24
  A71289FF27F7A14900DADDF3 /* ReactNativePortals.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReactNativePortals.framework; sourceTree = BUILT_PRODUCTS_DIR; };
25
+ A748ABFB28626EC300F26852 /* LiveUpdatesManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiveUpdatesManager.m; sourceTree = "<group>"; };
24
26
  CB9439A9444D2E97DA3B8149 /* Pods-ReactNativePortals.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativePortals.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativePortals/Pods-ReactNativePortals.debug.xcconfig"; sourceTree = "<group>"; };
25
27
  F4FF95D5245B92E700C19C63 /* ReactNativePortals-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ReactNativePortals-Bridging-Header.h"; sourceTree = "<group>"; };
26
28
  F4FF95D6245B92E800C19C63 /* ReactNativePortals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactNativePortals.swift; sourceTree = "<group>"; };
@@ -57,6 +59,7 @@
57
59
  58B511D21A9E6C8500147676 = {
58
60
  isa = PBXGroup;
59
61
  children = (
62
+ A748ABFB28626EC300F26852 /* LiveUpdatesManager.m */,
60
63
  F4FF95D6245B92E800C19C63 /* ReactNativePortals.swift */,
61
64
  A71289F727F79CDC00DADDF3 /* PortalView.m */,
62
65
  A71289F927F79EB200DADDF3 /* PortalManager.m */,
@@ -183,6 +186,7 @@
183
186
  isa = PBXSourcesBuildPhase;
184
187
  buildActionMask = 2147483647;
185
188
  files = (
189
+ A748ABFC28626EC300F26852 /* LiveUpdatesManager.m in Sources */,
186
190
  A7128A0A27F7A16200DADDF3 /* PortalView.m in Sources */,
187
191
  A7128A0927F7A16200DADDF3 /* PortalsPubSub.m in Sources */,
188
192
  A7128A0627F7A16200DADDF3 /* ReactNativePortals.swift in Sources */,
@@ -9,7 +9,7 @@ Object.defineProperty(exports, "PortalView", {
9
9
  return _PortalView.default;
10
10
  }
11
11
  });
12
- exports.unsubscribe = exports.subscribe = exports.register = exports.publish = exports.addPortal = void 0;
12
+ exports.unsubscribe = exports.syncSome = exports.syncOne = exports.syncAll = exports.subscribe = exports.register = exports.publish = exports.addPortal = void 0;
13
13
 
14
14
  var _reactNative = require("react-native");
15
15
 
@@ -18,14 +18,15 @@ var _PortalView = _interopRequireDefault(require("./PortalView"));
18
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
19
 
20
20
  const {
21
- IONPortalsPubSub,
22
- IONPortalManager
21
+ IONPortalPubSub,
22
+ IONPortalManager,
23
+ IONLiveUpdatesManager
23
24
  } = _reactNative.NativeModules;
24
- const PortalsPubSub = new _reactNative.NativeEventEmitter(IONPortalsPubSub);
25
+ const PortalsPubSub = new _reactNative.NativeEventEmitter(IONPortalPubSub);
25
26
  const subscriptionMap = new Map();
26
27
 
27
28
  const subscribe = async (topic, onMessageReceived) => {
28
- const subscriptionRef = await IONPortalsPubSub.subscribe(topic);
29
+ const subscriptionRef = await IONPortalPubSub.subscribe(topic);
29
30
  const subscriber = PortalsPubSub.addListener('PortalsSubscription', message => {
30
31
  if (message.subscriptionRef === subscriptionRef) {
31
32
  onMessageReceived(message);
@@ -38,7 +39,7 @@ const subscribe = async (topic, onMessageReceived) => {
38
39
  exports.subscribe = subscribe;
39
40
 
40
41
  const unsubscribe = (topic, subRef) => {
41
- IONPortalsPubSub.unsubscribe(topic, subRef);
42
+ IONPortalPubSub.unsubscribe(topic, subRef);
42
43
  const subscription = subscriptionMap.get(subRef);
43
44
 
44
45
  if (subscription !== undefined) {
@@ -53,7 +54,7 @@ const publish = (topic, data) => {
53
54
  const msg = {
54
55
  message: data
55
56
  };
56
- IONPortalsPubSub.publish(topic, msg);
57
+ IONPortalPubSub.publish(topic, msg);
57
58
  };
58
59
 
59
60
  exports.publish = publish;
@@ -69,4 +70,22 @@ const addPortal = portal => {
69
70
  };
70
71
 
71
72
  exports.addPortal = addPortal;
73
+
74
+ const syncOne = appId => {
75
+ return IONLiveUpdatesManager.syncOne(appId);
76
+ };
77
+
78
+ exports.syncOne = syncOne;
79
+
80
+ const syncSome = appIds => {
81
+ return IONLiveUpdatesManager.syncSome(appIds);
82
+ };
83
+
84
+ exports.syncSome = syncSome;
85
+
86
+ const syncAll = () => {
87
+ return IONLiveUpdatesManager.syncAll();
88
+ };
89
+
90
+ exports.syncAll = syncAll;
72
91
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["IONPortalsPubSub","IONPortalManager","NativeModules","PortalsPubSub","NativeEventEmitter","subscriptionMap","Map","subscribe","topic","onMessageReceived","subscriptionRef","subscriber","addListener","message","set","unsubscribe","subRef","subscription","get","undefined","remove","delete","publish","data","msg","register","key","addPortal","portal"],"sources":["index.ts"],"sourcesContent":["import {\n EmitterSubscription,\n NativeEventEmitter,\n NativeModules,\n ViewProps,\n} from 'react-native';\n\nconst { IONPortalsPubSub, IONPortalManager } = NativeModules;\n\nexport { default as PortalView } from './PortalView';\n\nexport interface Message {\n subscriptionRef: number;\n data: any;\n topic: string;\n}\n\nconst PortalsPubSub = new NativeEventEmitter(IONPortalsPubSub);\n\nconst subscriptionMap = new Map<number, EmitterSubscription>();\n\nexport const subscribe = async (\n topic: string,\n onMessageReceived: (message: Message) => void\n): Promise<number> => {\n const subscriptionRef = await IONPortalsPubSub.subscribe(topic);\n\n const subscriber = PortalsPubSub.addListener(\n 'PortalsSubscription',\n (message: Message) => {\n if (message.subscriptionRef === subscriptionRef) {\n onMessageReceived(message);\n }\n }\n );\n\n subscriptionMap.set(subscriptionRef, subscriber);\n\n return subscriptionRef;\n};\n\nexport const unsubscribe = (topic: string, subRef: number) => {\n IONPortalsPubSub.unsubscribe(topic, subRef);\n\n const subscription = subscriptionMap.get(subRef);\n if (subscription !== undefined) {\n subscription.remove();\n subscriptionMap.delete(subRef);\n }\n};\n\nexport const publish = (topic: string, data: any) => {\n const msg = { message: data };\n IONPortalsPubSub.publish(topic, msg);\n};\n\nexport const register = (key: string) => {\n IONPortalManager.register(key);\n};\n\nexport interface Portal {\n name: string;\n startDir?: string;\n initialContext?: any;\n}\n\nexport type PortalProps = Pick<Portal, 'name' | 'initialContext'> & ViewProps;\n\nexport const addPortal = (portal: Portal) => {\n IONPortalManager.addPortal(portal);\n};\n"],"mappings":";;;;;;;;;;;;;AAAA;;AASA;;;;AAFA,MAAM;EAAEA,gBAAF;EAAoBC;AAApB,IAAyCC,0BAA/C;AAUA,MAAMC,aAAa,GAAG,IAAIC,+BAAJ,CAAuBJ,gBAAvB,CAAtB;AAEA,MAAMK,eAAe,GAAG,IAAIC,GAAJ,EAAxB;;AAEO,MAAMC,SAAS,GAAG,OACvBC,KADuB,EAEvBC,iBAFuB,KAGH;EACpB,MAAMC,eAAe,GAAG,MAAMV,gBAAgB,CAACO,SAAjB,CAA2BC,KAA3B,CAA9B;EAEA,MAAMG,UAAU,GAAGR,aAAa,CAACS,WAAd,CACjB,qBADiB,EAEhBC,OAAD,IAAsB;IACpB,IAAIA,OAAO,CAACH,eAAR,KAA4BA,eAAhC,EAAiD;MAC/CD,iBAAiB,CAACI,OAAD,CAAjB;IACD;EACF,CANgB,CAAnB;EASAR,eAAe,CAACS,GAAhB,CAAoBJ,eAApB,EAAqCC,UAArC;EAEA,OAAOD,eAAP;AACD,CAlBM;;;;AAoBA,MAAMK,WAAW,GAAG,CAACP,KAAD,EAAgBQ,MAAhB,KAAmC;EAC5DhB,gBAAgB,CAACe,WAAjB,CAA6BP,KAA7B,EAAoCQ,MAApC;EAEA,MAAMC,YAAY,GAAGZ,eAAe,CAACa,GAAhB,CAAoBF,MAApB,CAArB;;EACA,IAAIC,YAAY,KAAKE,SAArB,EAAgC;IAC9BF,YAAY,CAACG,MAAb;IACAf,eAAe,CAACgB,MAAhB,CAAuBL,MAAvB;EACD;AACF,CARM;;;;AAUA,MAAMM,OAAO,GAAG,CAACd,KAAD,EAAgBe,IAAhB,KAA8B;EACnD,MAAMC,GAAG,GAAG;IAAEX,OAAO,EAAEU;EAAX,CAAZ;EACAvB,gBAAgB,CAACsB,OAAjB,CAAyBd,KAAzB,EAAgCgB,GAAhC;AACD,CAHM;;;;AAKA,MAAMC,QAAQ,GAAIC,GAAD,IAAiB;EACvCzB,gBAAgB,CAACwB,QAAjB,CAA0BC,GAA1B;AACD,CAFM;;;;AAYA,MAAMC,SAAS,GAAIC,MAAD,IAAoB;EAC3C3B,gBAAgB,CAAC0B,SAAjB,CAA2BC,MAA3B;AACD,CAFM"}
1
+ {"version":3,"names":["IONPortalPubSub","IONPortalManager","IONLiveUpdatesManager","NativeModules","PortalsPubSub","NativeEventEmitter","subscriptionMap","Map","subscribe","topic","onMessageReceived","subscriptionRef","subscriber","addListener","message","set","unsubscribe","subRef","subscription","get","undefined","remove","delete","publish","data","msg","register","key","addPortal","portal","syncOne","appId","syncSome","appIds","syncAll"],"sources":["index.ts"],"sourcesContent":["import {\n EmitterSubscription,\n NativeEventEmitter,\n NativeModules,\n ViewProps,\n} from 'react-native';\n\nconst { IONPortalPubSub, IONPortalManager, IONLiveUpdatesManager } =\n NativeModules;\n\nexport { default as PortalView } from './PortalView';\n\nexport interface Message {\n subscriptionRef: number;\n data: any;\n topic: string;\n}\n\nconst PortalsPubSub = new NativeEventEmitter(IONPortalPubSub);\n\nconst subscriptionMap = new Map<number, EmitterSubscription>();\n\nexport const subscribe = async (\n topic: string,\n onMessageReceived: (message: Message) => void\n): Promise<number> => {\n const subscriptionRef = await IONPortalPubSub.subscribe(topic);\n\n const subscriber = PortalsPubSub.addListener(\n 'PortalsSubscription',\n (message: Message) => {\n if (message.subscriptionRef === subscriptionRef) {\n onMessageReceived(message);\n }\n }\n );\n\n subscriptionMap.set(subscriptionRef, subscriber);\n\n return subscriptionRef;\n};\n\nexport const unsubscribe = (topic: string, subRef: number) => {\n IONPortalPubSub.unsubscribe(topic, subRef);\n\n const subscription = subscriptionMap.get(subRef);\n if (subscription !== undefined) {\n subscription.remove();\n subscriptionMap.delete(subRef);\n }\n};\n\nexport const publish = (topic: string, data: any) => {\n const msg = { message: data };\n IONPortalPubSub.publish(topic, msg);\n};\n\nexport const register = (key: string) => {\n IONPortalManager.register(key);\n};\n\nexport interface Portal {\n name: string;\n androidPlugins?: string[];\n startDir?: string;\n initialContext?: {\n [key: string]: any;\n };\n liveUpdate?: LiveUpdateConfig;\n}\n\nexport type PortalProps = Pick<Portal, 'name' | 'initialContext'> & ViewProps;\n\nexport const addPortal = (portal: Portal) => {\n IONPortalManager.addPortal(portal);\n};\n\nexport interface LiveUpdate {\n appId: string;\n channel: string;\n}\n\nexport type LiveUpdateConfig = LiveUpdate & { syncOnAdd: boolean };\n\nexport interface LiveUpdateError {\n appId: string;\n failStep: string;\n message: string;\n}\n\nexport interface SyncResults {\n liveUpdates: LiveUpdate[];\n errors: LiveUpdateError[];\n}\n\nexport const syncOne = (appId: string): Promise<LiveUpdate> => {\n return IONLiveUpdatesManager.syncOne(appId);\n};\n\nexport const syncSome = (appIds: string[]): Promise<SyncResults> => {\n return IONLiveUpdatesManager.syncSome(appIds);\n};\n\nexport const syncAll = (): Promise<SyncResults> => {\n return IONLiveUpdatesManager.syncAll();\n};\n"],"mappings":";;;;;;;;;;;;;AAAA;;AAUA;;;;AAHA,MAAM;EAAEA,eAAF;EAAmBC,gBAAnB;EAAqCC;AAArC,IACJC,0BADF;AAWA,MAAMC,aAAa,GAAG,IAAIC,+BAAJ,CAAuBL,eAAvB,CAAtB;AAEA,MAAMM,eAAe,GAAG,IAAIC,GAAJ,EAAxB;;AAEO,MAAMC,SAAS,GAAG,OACvBC,KADuB,EAEvBC,iBAFuB,KAGH;EACpB,MAAMC,eAAe,GAAG,MAAMX,eAAe,CAACQ,SAAhB,CAA0BC,KAA1B,CAA9B;EAEA,MAAMG,UAAU,GAAGR,aAAa,CAACS,WAAd,CACjB,qBADiB,EAEhBC,OAAD,IAAsB;IACpB,IAAIA,OAAO,CAACH,eAAR,KAA4BA,eAAhC,EAAiD;MAC/CD,iBAAiB,CAACI,OAAD,CAAjB;IACD;EACF,CANgB,CAAnB;EASAR,eAAe,CAACS,GAAhB,CAAoBJ,eAApB,EAAqCC,UAArC;EAEA,OAAOD,eAAP;AACD,CAlBM;;;;AAoBA,MAAMK,WAAW,GAAG,CAACP,KAAD,EAAgBQ,MAAhB,KAAmC;EAC5DjB,eAAe,CAACgB,WAAhB,CAA4BP,KAA5B,EAAmCQ,MAAnC;EAEA,MAAMC,YAAY,GAAGZ,eAAe,CAACa,GAAhB,CAAoBF,MAApB,CAArB;;EACA,IAAIC,YAAY,KAAKE,SAArB,EAAgC;IAC9BF,YAAY,CAACG,MAAb;IACAf,eAAe,CAACgB,MAAhB,CAAuBL,MAAvB;EACD;AACF,CARM;;;;AAUA,MAAMM,OAAO,GAAG,CAACd,KAAD,EAAgBe,IAAhB,KAA8B;EACnD,MAAMC,GAAG,GAAG;IAAEX,OAAO,EAAEU;EAAX,CAAZ;EACAxB,eAAe,CAACuB,OAAhB,CAAwBd,KAAxB,EAA+BgB,GAA/B;AACD,CAHM;;;;AAKA,MAAMC,QAAQ,GAAIC,GAAD,IAAiB;EACvC1B,gBAAgB,CAACyB,QAAjB,CAA0BC,GAA1B;AACD,CAFM;;;;AAgBA,MAAMC,SAAS,GAAIC,MAAD,IAAoB;EAC3C5B,gBAAgB,CAAC2B,SAAjB,CAA2BC,MAA3B;AACD,CAFM;;;;AAsBA,MAAMC,OAAO,GAAIC,KAAD,IAAwC;EAC7D,OAAO7B,qBAAqB,CAAC4B,OAAtB,CAA8BC,KAA9B,CAAP;AACD,CAFM;;;;AAIA,MAAMC,QAAQ,GAAIC,MAAD,IAA4C;EAClE,OAAO/B,qBAAqB,CAAC8B,QAAtB,CAA+BC,MAA/B,CAAP;AACD,CAFM;;;;AAIA,MAAMC,OAAO,GAAG,MAA4B;EACjD,OAAOhC,qBAAqB,CAACgC,OAAtB,EAAP;AACD,CAFM"}
@@ -1,13 +1,14 @@
1
1
  import { NativeEventEmitter, NativeModules } from 'react-native';
2
2
  const {
3
- IONPortalsPubSub,
4
- IONPortalManager
3
+ IONPortalPubSub,
4
+ IONPortalManager,
5
+ IONLiveUpdatesManager
5
6
  } = NativeModules;
6
7
  export { default as PortalView } from './PortalView';
7
- const PortalsPubSub = new NativeEventEmitter(IONPortalsPubSub);
8
+ const PortalsPubSub = new NativeEventEmitter(IONPortalPubSub);
8
9
  const subscriptionMap = new Map();
9
10
  export const subscribe = async (topic, onMessageReceived) => {
10
- const subscriptionRef = await IONPortalsPubSub.subscribe(topic);
11
+ const subscriptionRef = await IONPortalPubSub.subscribe(topic);
11
12
  const subscriber = PortalsPubSub.addListener('PortalsSubscription', message => {
12
13
  if (message.subscriptionRef === subscriptionRef) {
13
14
  onMessageReceived(message);
@@ -17,7 +18,7 @@ export const subscribe = async (topic, onMessageReceived) => {
17
18
  return subscriptionRef;
18
19
  };
19
20
  export const unsubscribe = (topic, subRef) => {
20
- IONPortalsPubSub.unsubscribe(topic, subRef);
21
+ IONPortalPubSub.unsubscribe(topic, subRef);
21
22
  const subscription = subscriptionMap.get(subRef);
22
23
 
23
24
  if (subscription !== undefined) {
@@ -29,7 +30,7 @@ export const publish = (topic, data) => {
29
30
  const msg = {
30
31
  message: data
31
32
  };
32
- IONPortalsPubSub.publish(topic, msg);
33
+ IONPortalPubSub.publish(topic, msg);
33
34
  };
34
35
  export const register = key => {
35
36
  IONPortalManager.register(key);
@@ -37,4 +38,13 @@ export const register = key => {
37
38
  export const addPortal = portal => {
38
39
  IONPortalManager.addPortal(portal);
39
40
  };
41
+ export const syncOne = appId => {
42
+ return IONLiveUpdatesManager.syncOne(appId);
43
+ };
44
+ export const syncSome = appIds => {
45
+ return IONLiveUpdatesManager.syncSome(appIds);
46
+ };
47
+ export const syncAll = () => {
48
+ return IONLiveUpdatesManager.syncAll();
49
+ };
40
50
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["NativeEventEmitter","NativeModules","IONPortalsPubSub","IONPortalManager","default","PortalView","PortalsPubSub","subscriptionMap","Map","subscribe","topic","onMessageReceived","subscriptionRef","subscriber","addListener","message","set","unsubscribe","subRef","subscription","get","undefined","remove","delete","publish","data","msg","register","key","addPortal","portal"],"sources":["index.ts"],"sourcesContent":["import {\n EmitterSubscription,\n NativeEventEmitter,\n NativeModules,\n ViewProps,\n} from 'react-native';\n\nconst { IONPortalsPubSub, IONPortalManager } = NativeModules;\n\nexport { default as PortalView } from './PortalView';\n\nexport interface Message {\n subscriptionRef: number;\n data: any;\n topic: string;\n}\n\nconst PortalsPubSub = new NativeEventEmitter(IONPortalsPubSub);\n\nconst subscriptionMap = new Map<number, EmitterSubscription>();\n\nexport const subscribe = async (\n topic: string,\n onMessageReceived: (message: Message) => void\n): Promise<number> => {\n const subscriptionRef = await IONPortalsPubSub.subscribe(topic);\n\n const subscriber = PortalsPubSub.addListener(\n 'PortalsSubscription',\n (message: Message) => {\n if (message.subscriptionRef === subscriptionRef) {\n onMessageReceived(message);\n }\n }\n );\n\n subscriptionMap.set(subscriptionRef, subscriber);\n\n return subscriptionRef;\n};\n\nexport const unsubscribe = (topic: string, subRef: number) => {\n IONPortalsPubSub.unsubscribe(topic, subRef);\n\n const subscription = subscriptionMap.get(subRef);\n if (subscription !== undefined) {\n subscription.remove();\n subscriptionMap.delete(subRef);\n }\n};\n\nexport const publish = (topic: string, data: any) => {\n const msg = { message: data };\n IONPortalsPubSub.publish(topic, msg);\n};\n\nexport const register = (key: string) => {\n IONPortalManager.register(key);\n};\n\nexport interface Portal {\n name: string;\n startDir?: string;\n initialContext?: any;\n}\n\nexport type PortalProps = Pick<Portal, 'name' | 'initialContext'> & ViewProps;\n\nexport const addPortal = (portal: Portal) => {\n IONPortalManager.addPortal(portal);\n};\n"],"mappings":"AAAA,SAEEA,kBAFF,EAGEC,aAHF,QAKO,cALP;AAOA,MAAM;EAAEC,gBAAF;EAAoBC;AAApB,IAAyCF,aAA/C;AAEA,SAASG,OAAO,IAAIC,UAApB,QAAsC,cAAtC;AAQA,MAAMC,aAAa,GAAG,IAAIN,kBAAJ,CAAuBE,gBAAvB,CAAtB;AAEA,MAAMK,eAAe,GAAG,IAAIC,GAAJ,EAAxB;AAEA,OAAO,MAAMC,SAAS,GAAG,OACvBC,KADuB,EAEvBC,iBAFuB,KAGH;EACpB,MAAMC,eAAe,GAAG,MAAMV,gBAAgB,CAACO,SAAjB,CAA2BC,KAA3B,CAA9B;EAEA,MAAMG,UAAU,GAAGP,aAAa,CAACQ,WAAd,CACjB,qBADiB,EAEhBC,OAAD,IAAsB;IACpB,IAAIA,OAAO,CAACH,eAAR,KAA4BA,eAAhC,EAAiD;MAC/CD,iBAAiB,CAACI,OAAD,CAAjB;IACD;EACF,CANgB,CAAnB;EASAR,eAAe,CAACS,GAAhB,CAAoBJ,eAApB,EAAqCC,UAArC;EAEA,OAAOD,eAAP;AACD,CAlBM;AAoBP,OAAO,MAAMK,WAAW,GAAG,CAACP,KAAD,EAAgBQ,MAAhB,KAAmC;EAC5DhB,gBAAgB,CAACe,WAAjB,CAA6BP,KAA7B,EAAoCQ,MAApC;EAEA,MAAMC,YAAY,GAAGZ,eAAe,CAACa,GAAhB,CAAoBF,MAApB,CAArB;;EACA,IAAIC,YAAY,KAAKE,SAArB,EAAgC;IAC9BF,YAAY,CAACG,MAAb;IACAf,eAAe,CAACgB,MAAhB,CAAuBL,MAAvB;EACD;AACF,CARM;AAUP,OAAO,MAAMM,OAAO,GAAG,CAACd,KAAD,EAAgBe,IAAhB,KAA8B;EACnD,MAAMC,GAAG,GAAG;IAAEX,OAAO,EAAEU;EAAX,CAAZ;EACAvB,gBAAgB,CAACsB,OAAjB,CAAyBd,KAAzB,EAAgCgB,GAAhC;AACD,CAHM;AAKP,OAAO,MAAMC,QAAQ,GAAIC,GAAD,IAAiB;EACvCzB,gBAAgB,CAACwB,QAAjB,CAA0BC,GAA1B;AACD,CAFM;AAYP,OAAO,MAAMC,SAAS,GAAIC,MAAD,IAAoB;EAC3C3B,gBAAgB,CAAC0B,SAAjB,CAA2BC,MAA3B;AACD,CAFM"}
1
+ {"version":3,"names":["NativeEventEmitter","NativeModules","IONPortalPubSub","IONPortalManager","IONLiveUpdatesManager","default","PortalView","PortalsPubSub","subscriptionMap","Map","subscribe","topic","onMessageReceived","subscriptionRef","subscriber","addListener","message","set","unsubscribe","subRef","subscription","get","undefined","remove","delete","publish","data","msg","register","key","addPortal","portal","syncOne","appId","syncSome","appIds","syncAll"],"sources":["index.ts"],"sourcesContent":["import {\n EmitterSubscription,\n NativeEventEmitter,\n NativeModules,\n ViewProps,\n} from 'react-native';\n\nconst { IONPortalPubSub, IONPortalManager, IONLiveUpdatesManager } =\n NativeModules;\n\nexport { default as PortalView } from './PortalView';\n\nexport interface Message {\n subscriptionRef: number;\n data: any;\n topic: string;\n}\n\nconst PortalsPubSub = new NativeEventEmitter(IONPortalPubSub);\n\nconst subscriptionMap = new Map<number, EmitterSubscription>();\n\nexport const subscribe = async (\n topic: string,\n onMessageReceived: (message: Message) => void\n): Promise<number> => {\n const subscriptionRef = await IONPortalPubSub.subscribe(topic);\n\n const subscriber = PortalsPubSub.addListener(\n 'PortalsSubscription',\n (message: Message) => {\n if (message.subscriptionRef === subscriptionRef) {\n onMessageReceived(message);\n }\n }\n );\n\n subscriptionMap.set(subscriptionRef, subscriber);\n\n return subscriptionRef;\n};\n\nexport const unsubscribe = (topic: string, subRef: number) => {\n IONPortalPubSub.unsubscribe(topic, subRef);\n\n const subscription = subscriptionMap.get(subRef);\n if (subscription !== undefined) {\n subscription.remove();\n subscriptionMap.delete(subRef);\n }\n};\n\nexport const publish = (topic: string, data: any) => {\n const msg = { message: data };\n IONPortalPubSub.publish(topic, msg);\n};\n\nexport const register = (key: string) => {\n IONPortalManager.register(key);\n};\n\nexport interface Portal {\n name: string;\n androidPlugins?: string[];\n startDir?: string;\n initialContext?: {\n [key: string]: any;\n };\n liveUpdate?: LiveUpdateConfig;\n}\n\nexport type PortalProps = Pick<Portal, 'name' | 'initialContext'> & ViewProps;\n\nexport const addPortal = (portal: Portal) => {\n IONPortalManager.addPortal(portal);\n};\n\nexport interface LiveUpdate {\n appId: string;\n channel: string;\n}\n\nexport type LiveUpdateConfig = LiveUpdate & { syncOnAdd: boolean };\n\nexport interface LiveUpdateError {\n appId: string;\n failStep: string;\n message: string;\n}\n\nexport interface SyncResults {\n liveUpdates: LiveUpdate[];\n errors: LiveUpdateError[];\n}\n\nexport const syncOne = (appId: string): Promise<LiveUpdate> => {\n return IONLiveUpdatesManager.syncOne(appId);\n};\n\nexport const syncSome = (appIds: string[]): Promise<SyncResults> => {\n return IONLiveUpdatesManager.syncSome(appIds);\n};\n\nexport const syncAll = (): Promise<SyncResults> => {\n return IONLiveUpdatesManager.syncAll();\n};\n"],"mappings":"AAAA,SAEEA,kBAFF,EAGEC,aAHF,QAKO,cALP;AAOA,MAAM;EAAEC,eAAF;EAAmBC,gBAAnB;EAAqCC;AAArC,IACJH,aADF;AAGA,SAASI,OAAO,IAAIC,UAApB,QAAsC,cAAtC;AAQA,MAAMC,aAAa,GAAG,IAAIP,kBAAJ,CAAuBE,eAAvB,CAAtB;AAEA,MAAMM,eAAe,GAAG,IAAIC,GAAJ,EAAxB;AAEA,OAAO,MAAMC,SAAS,GAAG,OACvBC,KADuB,EAEvBC,iBAFuB,KAGH;EACpB,MAAMC,eAAe,GAAG,MAAMX,eAAe,CAACQ,SAAhB,CAA0BC,KAA1B,CAA9B;EAEA,MAAMG,UAAU,GAAGP,aAAa,CAACQ,WAAd,CACjB,qBADiB,EAEhBC,OAAD,IAAsB;IACpB,IAAIA,OAAO,CAACH,eAAR,KAA4BA,eAAhC,EAAiD;MAC/CD,iBAAiB,CAACI,OAAD,CAAjB;IACD;EACF,CANgB,CAAnB;EASAR,eAAe,CAACS,GAAhB,CAAoBJ,eAApB,EAAqCC,UAArC;EAEA,OAAOD,eAAP;AACD,CAlBM;AAoBP,OAAO,MAAMK,WAAW,GAAG,CAACP,KAAD,EAAgBQ,MAAhB,KAAmC;EAC5DjB,eAAe,CAACgB,WAAhB,CAA4BP,KAA5B,EAAmCQ,MAAnC;EAEA,MAAMC,YAAY,GAAGZ,eAAe,CAACa,GAAhB,CAAoBF,MAApB,CAArB;;EACA,IAAIC,YAAY,KAAKE,SAArB,EAAgC;IAC9BF,YAAY,CAACG,MAAb;IACAf,eAAe,CAACgB,MAAhB,CAAuBL,MAAvB;EACD;AACF,CARM;AAUP,OAAO,MAAMM,OAAO,GAAG,CAACd,KAAD,EAAgBe,IAAhB,KAA8B;EACnD,MAAMC,GAAG,GAAG;IAAEX,OAAO,EAAEU;EAAX,CAAZ;EACAxB,eAAe,CAACuB,OAAhB,CAAwBd,KAAxB,EAA+BgB,GAA/B;AACD,CAHM;AAKP,OAAO,MAAMC,QAAQ,GAAIC,GAAD,IAAiB;EACvC1B,gBAAgB,CAACyB,QAAjB,CAA0BC,GAA1B;AACD,CAFM;AAgBP,OAAO,MAAMC,SAAS,GAAIC,MAAD,IAAoB;EAC3C5B,gBAAgB,CAAC2B,SAAjB,CAA2BC,MAA3B;AACD,CAFM;AAsBP,OAAO,MAAMC,OAAO,GAAIC,KAAD,IAAwC;EAC7D,OAAO7B,qBAAqB,CAAC4B,OAAtB,CAA8BC,KAA9B,CAAP;AACD,CAFM;AAIP,OAAO,MAAMC,QAAQ,GAAIC,MAAD,IAA4C;EAClE,OAAO/B,qBAAqB,CAAC8B,QAAtB,CAA+BC,MAA/B,CAAP;AACD,CAFM;AAIP,OAAO,MAAMC,OAAO,GAAG,MAA4B;EACjD,OAAOhC,qBAAqB,CAACgC,OAAtB,EAAP;AACD,CAFM"}
@@ -11,8 +11,31 @@ export declare const publish: (topic: string, data: any) => void;
11
11
  export declare const register: (key: string) => void;
12
12
  export interface Portal {
13
13
  name: string;
14
+ androidPlugins?: string[];
14
15
  startDir?: string;
15
- initialContext?: any;
16
+ initialContext?: {
17
+ [key: string]: any;
18
+ };
19
+ liveUpdate?: LiveUpdateConfig;
16
20
  }
17
21
  export declare type PortalProps = Pick<Portal, 'name' | 'initialContext'> & ViewProps;
18
22
  export declare const addPortal: (portal: Portal) => void;
23
+ export interface LiveUpdate {
24
+ appId: string;
25
+ channel: string;
26
+ }
27
+ export declare type LiveUpdateConfig = LiveUpdate & {
28
+ syncOnAdd: boolean;
29
+ };
30
+ export interface LiveUpdateError {
31
+ appId: string;
32
+ failStep: string;
33
+ message: string;
34
+ }
35
+ export interface SyncResults {
36
+ liveUpdates: LiveUpdate[];
37
+ errors: LiveUpdateError[];
38
+ }
39
+ export declare const syncOne: (appId: string) => Promise<LiveUpdate>;
40
+ export declare const syncSome: (appIds: string[]) => Promise<SyncResults>;
41
+ export declare const syncAll: () => Promise<SyncResults>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic/portals-react-native",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Ionic Portals for React Native",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
package/src/index.ts CHANGED
@@ -5,7 +5,8 @@ import {
5
5
  ViewProps,
6
6
  } from 'react-native';
7
7
 
8
- const { IONPortalsPubSub, IONPortalManager } = NativeModules;
8
+ const { IONPortalPubSub, IONPortalManager, IONLiveUpdatesManager } =
9
+ NativeModules;
9
10
 
10
11
  export { default as PortalView } from './PortalView';
11
12
 
@@ -15,7 +16,7 @@ export interface Message {
15
16
  topic: string;
16
17
  }
17
18
 
18
- const PortalsPubSub = new NativeEventEmitter(IONPortalsPubSub);
19
+ const PortalsPubSub = new NativeEventEmitter(IONPortalPubSub);
19
20
 
20
21
  const subscriptionMap = new Map<number, EmitterSubscription>();
21
22
 
@@ -23,7 +24,7 @@ export const subscribe = async (
23
24
  topic: string,
24
25
  onMessageReceived: (message: Message) => void
25
26
  ): Promise<number> => {
26
- const subscriptionRef = await IONPortalsPubSub.subscribe(topic);
27
+ const subscriptionRef = await IONPortalPubSub.subscribe(topic);
27
28
 
28
29
  const subscriber = PortalsPubSub.addListener(
29
30
  'PortalsSubscription',
@@ -40,7 +41,7 @@ export const subscribe = async (
40
41
  };
41
42
 
42
43
  export const unsubscribe = (topic: string, subRef: number) => {
43
- IONPortalsPubSub.unsubscribe(topic, subRef);
44
+ IONPortalPubSub.unsubscribe(topic, subRef);
44
45
 
45
46
  const subscription = subscriptionMap.get(subRef);
46
47
  if (subscription !== undefined) {
@@ -51,7 +52,7 @@ export const unsubscribe = (topic: string, subRef: number) => {
51
52
 
52
53
  export const publish = (topic: string, data: any) => {
53
54
  const msg = { message: data };
54
- IONPortalsPubSub.publish(topic, msg);
55
+ IONPortalPubSub.publish(topic, msg);
55
56
  };
56
57
 
57
58
  export const register = (key: string) => {
@@ -60,8 +61,12 @@ export const register = (key: string) => {
60
61
 
61
62
  export interface Portal {
62
63
  name: string;
64
+ androidPlugins?: string[];
63
65
  startDir?: string;
64
- initialContext?: any;
66
+ initialContext?: {
67
+ [key: string]: any;
68
+ };
69
+ liveUpdate?: LiveUpdateConfig;
65
70
  }
66
71
 
67
72
  export type PortalProps = Pick<Portal, 'name' | 'initialContext'> & ViewProps;
@@ -69,3 +74,33 @@ export type PortalProps = Pick<Portal, 'name' | 'initialContext'> & ViewProps;
69
74
  export const addPortal = (portal: Portal) => {
70
75
  IONPortalManager.addPortal(portal);
71
76
  };
77
+
78
+ export interface LiveUpdate {
79
+ appId: string;
80
+ channel: string;
81
+ }
82
+
83
+ export type LiveUpdateConfig = LiveUpdate & { syncOnAdd: boolean };
84
+
85
+ export interface LiveUpdateError {
86
+ appId: string;
87
+ failStep: string;
88
+ message: string;
89
+ }
90
+
91
+ export interface SyncResults {
92
+ liveUpdates: LiveUpdate[];
93
+ errors: LiveUpdateError[];
94
+ }
95
+
96
+ export const syncOne = (appId: string): Promise<LiveUpdate> => {
97
+ return IONLiveUpdatesManager.syncOne(appId);
98
+ };
99
+
100
+ export const syncSome = (appIds: string[]): Promise<SyncResults> => {
101
+ return IONLiveUpdatesManager.syncSome(appIds);
102
+ };
103
+
104
+ export const syncAll = (): Promise<SyncResults> => {
105
+ return IONLiveUpdatesManager.syncAll();
106
+ };