@ionic/portals-react-native 0.5.2 → 0.7.0

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.
Files changed (49) hide show
  1. package/ReactNativePortals.podspec +39 -14
  2. package/android/build.gradle +78 -108
  3. package/android/gradle.properties +5 -3
  4. package/android/src/main/java/io/ionic/portals/reactnative/PortalView.kt +11 -8
  5. package/android/src/main/java/io/ionic/portals/reactnative/ReactNativePortalManager.kt +24 -24
  6. package/android/src/main/java/io/ionic/portals/reactnative/ReactNativePortalsModule.kt +0 -34
  7. package/android/src/main/java/io/ionic/portals/reactnative/ReactNativeWebVitalsModule.kt +0 -34
  8. package/ios/AssetMap+Codable.swift +33 -0
  9. package/ios/LiveUpdateManager+Async.swift +16 -46
  10. package/ios/Podfile +29 -4
  11. package/ios/Podfile.lock +478 -241
  12. package/ios/Portal.swift +50 -54
  13. package/ios/{PortalManager.m → PortalManager.mm} +0 -3
  14. package/ios/PortalView.swift +22 -12
  15. package/ios/{PortalWebVitals.m → PortalWebVitals.mm} +0 -1
  16. package/ios/PortalsConfig.swift +1 -88
  17. package/ios/PortalsReactNative-Bridging-Header.h +2 -0
  18. package/ios/PortalsReactNative.swift +17 -51
  19. package/ios/SyncResult+SyncError+Encodable.swift +55 -0
  20. package/ios/WebVitals.swift +17 -34
  21. package/package.json +62 -43
  22. package/src/{PortalView.android.tsx → BasePortalView.android.tsx} +2 -3
  23. package/src/{PortalView.tsx → BasePortalView.tsx} +2 -3
  24. package/src/{index.ts → index.tsx} +43 -96
  25. package/ios/AssetMap+Dict.swift +0 -28
  26. package/ios/LiveUpdate+Dict.swift +0 -30
  27. package/ios/LiveUpdateManagerError+Dict.swift +0 -19
  28. package/ios/ReactNativePortals.xcodeproj/project.pbxproj +0 -465
  29. package/ios/ReactNativePortals.xcodeproj/xcshareddata/xcschemes/ReactNativePortals.xcscheme +0 -67
  30. package/ios/ReactNativePortals.xcworkspace/contents.xcworkspacedata +0 -10
  31. package/ios/ReactNativePortals.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  32. package/ios/SyncResult+Dict.swift +0 -35
  33. package/lib/commonjs/PortalView.android.js +0 -28
  34. package/lib/commonjs/PortalView.android.js.map +0 -1
  35. package/lib/commonjs/PortalView.js +0 -15
  36. package/lib/commonjs/PortalView.js.map +0 -1
  37. package/lib/commonjs/index.js +0 -200
  38. package/lib/commonjs/index.js.map +0 -1
  39. package/lib/module/PortalView.android.js +0 -20
  40. package/lib/module/PortalView.android.js.map +0 -1
  41. package/lib/module/PortalView.js +0 -8
  42. package/lib/module/PortalView.js.map +0 -1
  43. package/lib/module/index.js +0 -176
  44. package/lib/module/index.js.map +0 -1
  45. package/lib/typescript/PortalView.android.d.ts +0 -4
  46. package/lib/typescript/PortalView.d.ts +0 -4
  47. package/lib/typescript/index.d.ts +0 -181
  48. /package/ios/{PortalView.m → PortalView.mm} +0 -0
  49. /package/ios/{PortalsPubSub.m → PortalsPubSub.mm} +0 -0
@@ -1,21 +1,46 @@
1
- require 'json'
1
+ require "json"
2
2
 
3
- package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+ folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
4
5
 
5
6
  Pod::Spec.new do |s|
6
- s.name = 'ReactNativePortals'
7
- s.version = package['version']
8
- s.summary = package['description']
9
- s.homepage = package['homepage']
10
- s.license = package['license']
11
- s.authors = package['author']
7
+ s.name = "ReactNativePortals"
8
+ s.version = package["version"]
9
+ s.summary = package["description"]
10
+ s.homepage = package["homepage"]
11
+ s.license = package["license"]
12
+ s.authors = package["author"]
12
13
 
13
- s.platforms = { ios: '13.0' }
14
- s.source = { git: 'https://github.com/ionic-team/react-native-ionic-portals.git', tag: "#{s.version}" }
14
+ s.platforms = { :ios => min_ios_version_supported }
15
+ s.source = { :git => "https://github.com/ionic-team/ionic-portals-react-native.git", :tag => "#{s.version}" }
15
16
 
16
- s.source_files = 'ios/**/*.{h,m,mm,swift}'
17
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
17
18
 
18
- s.dependency 'React-Core'
19
- s.dependency 'IonicPortals', '~> 0.8.0'
20
- s.dependency 'IonicLiveUpdates', '~> 0.4.0'
19
+ # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
20
+ # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
21
+ if respond_to?(:install_modules_dependencies, true)
22
+ s.dependency 'IonicPortals', '~> 0.11.0'
23
+ s.dependency 'IonicLiveUpdates', '~> 0.5.2'
24
+ install_modules_dependencies(s)
25
+
26
+ else
27
+ s.dependency "React-Core"
28
+ s.dependency 'IonicPortals', '~> 0.11.0'
29
+ s.dependency 'IonicLiveUpdates', '~> 0.5.2'
30
+
31
+ # Don't install the dependencies when we run `pod install` in the old architecture.
32
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
33
+ s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
34
+ s.pod_target_xcconfig = {
35
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
36
+ "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
37
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
38
+ }
39
+ s.dependency "React-Codegen"
40
+ s.dependency "RCT-Folly"
41
+ s.dependency "RCTRequired"
42
+ s.dependency "RCTTypeSafety"
43
+ s.dependency "ReactCommon/turbomodule/core"
44
+ end
45
+ end
21
46
  end
@@ -1,131 +1,101 @@
1
1
  buildscript {
2
- // Buildscript is evaluated before everything else so we can't use getExtOrDefault
3
- def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['ReactNativePortals_kotlinVersion']
2
+ // Buildscript is evaluated before everything else so we can't use getExtOrDefault
3
+ def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["PortalsReactNative_kotlinVersion"]
4
4
 
5
- repositories {
6
- google()
7
- mavenCentral()
8
- }
5
+ repositories {
6
+ google()
7
+ mavenCentral()
8
+ }
9
9
 
10
- dependencies {
11
- classpath 'com.android.tools.build:gradle:7.1.2'
12
- // noinspection DifferentKotlinGradleVersion
13
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14
- }
10
+ dependencies {
11
+ classpath "com.android.tools.build:gradle:7.2.1"
12
+ // noinspection DifferentKotlinGradleVersion
13
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14
+ }
15
15
  }
16
16
 
17
- apply plugin: 'com.android.library'
18
- apply plugin: 'kotlin-android'
17
+ def reactNativeArchitectures() {
18
+ def value = rootProject.getProperties().get("reactNativeArchitectures")
19
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
20
+ }
19
21
 
20
- def getExtOrIntegerDefault(name) {
21
- return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['ReactNativePortals_' + name]).toInteger()
22
+ def isNewArchitectureEnabled() {
23
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
22
24
  }
23
25
 
24
- android {
25
- compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
26
- defaultConfig {
27
- minSdkVersion 16
28
- targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
29
- versionCode 1
30
- versionName "1.0"
31
- }
26
+ apply plugin: "com.android.library"
27
+ apply plugin: "kotlin-android"
32
28
 
33
- buildTypes {
34
- release {
35
- minifyEnabled false
36
- }
37
- }
38
- lintOptions {
39
- disable 'GradleCompatible'
40
- }
29
+ if (isNewArchitectureEnabled()) {
30
+ apply plugin: "com.facebook.react"
41
31
  }
42
32
 
43
- tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
44
- sourceCompatibility = JavaVersion.VERSION_17
45
- targetCompatibility = JavaVersion.VERSION_17
33
+ def getExtOrDefault(name) {
34
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["PortalsReactNative_" + name]
35
+ }
46
36
 
47
- kotlinOptions {
48
- freeCompilerArgs += '-opt-in=kotlin.RequiresOptIn'
49
- }
37
+ def getExtOrIntegerDefault(name) {
38
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["PortalsReactNative_" + name]).toInteger()
50
39
  }
51
40
 
52
- repositories {
53
- mavenCentral()
54
- google()
41
+ def supportsNamespace() {
42
+ def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
43
+ def major = parsed[0].toInteger()
44
+ def minor = parsed[1].toInteger()
55
45
 
56
- def found = false
57
- def defaultDir = null
58
- def androidSourcesName = 'React Native sources'
59
-
60
- if (rootProject.ext.has('reactNativeAndroidRoot')) {
61
- defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
62
- } else {
63
- defaultDir = new File(
64
- projectDir,
65
- '/../../../node_modules/react-native/android'
66
- )
67
- }
46
+ // Namespace support was added in 7.3.0
47
+ return (major == 7 && minor >= 3) || major >= 8
48
+ }
49
+
50
+ android {
51
+ if (supportsNamespace()) {
52
+ namespace "com.ionic.portalsreactnative"
68
53
 
69
- if (defaultDir.exists()) {
70
- maven {
71
- url defaultDir.toString()
72
- name androidSourcesName
73
- }
74
-
75
- logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
76
- found = true
77
- } else {
78
- def parentDir = rootProject.projectDir
79
-
80
- 1.upto(5, {
81
- if (found) return true
82
- parentDir = parentDir.parentFile
83
-
84
- def androidSourcesDir = new File(
85
- parentDir,
86
- 'node_modules/react-native'
87
- )
88
-
89
- def androidPrebuiltBinaryDir = new File(
90
- parentDir,
91
- 'node_modules/react-native/android'
92
- )
93
-
94
- if (androidPrebuiltBinaryDir.exists()) {
95
- maven {
96
- url androidPrebuiltBinaryDir.toString()
97
- name androidSourcesName
98
- }
99
-
100
- logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
101
- found = true
102
- } else if (androidSourcesDir.exists()) {
103
- maven {
104
- url androidSourcesDir.toString()
105
- name androidSourcesName
106
- }
107
-
108
- logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
109
- found = true
110
- }
111
- })
54
+ sourceSets {
55
+ main {
56
+ manifest.srcFile "src/main/AndroidManifestNew.xml"
57
+ }
112
58
  }
59
+ }
60
+
61
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
62
+
63
+ defaultConfig {
64
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
65
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
66
+
67
+ }
113
68
 
114
- if (!found) {
115
- throw new GradleException(
116
- "${project.name}: unable to locate React Native android sources. " +
117
- "Ensure you have you installed React Native as a dependency in your project and try again."
118
- )
69
+ buildTypes {
70
+ release {
71
+ minifyEnabled false
119
72
  }
73
+ }
74
+
75
+ lintOptions {
76
+ disable "GradleCompatible"
77
+ }
78
+
79
+ compileOptions {
80
+ sourceCompatibility JavaVersion.VERSION_1_8
81
+ targetCompatibility JavaVersion.VERSION_1_8
82
+ }
120
83
  }
121
84
 
85
+ repositories {
86
+ mavenCentral()
87
+ google()
88
+ }
89
+
90
+ def kotlin_version = getExtOrDefault("kotlinVersion")
91
+
122
92
  dependencies {
123
- //noinspection GradleDynamicVersion
124
- api 'com.facebook.react:react-native:+'
125
- //noinspection GradleDynamicVersion
126
- api "io.ionic:portals:0.8.+"
127
- //noinspection GradleDynamicVersion
128
- api "io.ionic:liveupdates:0.4.+"
129
-
130
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.3"
93
+ // For < 0.71, this will be from the local maven repo
94
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
95
+ //noinspection GradleDynamicVersion
96
+ implementation "com.facebook.react:react-native:+"
97
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
98
+ implementation "io.ionic:portals:0.10.+"
99
+ implementation "io.ionic:liveupdates:0.5.+"
131
100
  }
101
+
@@ -1,4 +1,6 @@
1
- ReactNativePortals_kotlinVersion=1.8.0
2
- ReactNativePortals_compileSdkVersion=33
3
- ReactNativePortals_targetSdkVersion=33
1
+ PortalsReactNative_kotlinVersion=1.8.0
2
+ PortalsReactNative_minSdkVersion=21
3
+ PortalsReactNative_targetSdkVersion=33
4
+ PortalsReactNative_compileSdkVersion=33
5
+ PortalsReactNative_ndkversion=21.4.7075529
4
6
  android.useAndroidX=true
@@ -9,6 +9,7 @@ import androidx.fragment.app.FragmentActivity
9
9
  import com.facebook.react.bridge.ReactApplicationContext
10
10
  import com.facebook.react.bridge.ReadableArray
11
11
  import com.facebook.react.bridge.ReadableMap
12
+ import com.facebook.react.modules.core.DeviceEventManagerModule
12
13
  import com.facebook.react.uimanager.ThemedReactContext
13
14
  import com.facebook.react.uimanager.ViewGroupManager
14
15
  import com.facebook.react.uimanager.annotations.ReactProp
@@ -32,7 +33,7 @@ internal class PortalViewManager(private val context: ReactApplicationContext) :
32
33
  when (fragmentMap[viewGroup.id]) {
33
34
  null -> fragmentMap[viewGroup.id] = PortalViewState(
34
35
  fragment = null,
35
- portal = RNPortalManager.getPortal(name),
36
+ portal = RNPortalManager.createPortal(portal),
36
37
  initialContext = portal.getMap("initialContext")?.toHashMap()
37
38
  )
38
39
  }
@@ -68,13 +69,15 @@ internal class PortalViewManager(private val context: ReactApplicationContext) :
68
69
  setupLayout(parentView)
69
70
 
70
71
  val portal = rnPortal.builder.create()
71
-
72
- if (rnPortal.onFCP != null || rnPortal.onFID != null || rnPortal.onTTFB != null) {
73
- val vitalsPlugin = WebVitals { _, metric, duration ->
74
- when (metric) {
75
- WebVitals.Metric.FCP -> rnPortal.onFCP?.let { it(duration) }
76
- WebVitals.Metric.FID -> rnPortal.onFID?.let { it(duration) }
77
- WebVitals.Metric.TTFB -> rnPortal.onTTFB?.let { it(duration) }
72
+ val vitals: List<String>? = rnPortal.vitals
73
+
74
+ if (vitals != null) {
75
+ val vitalsPlugin = WebVitals { name, metric, duration ->
76
+ val stringMetric = metric.toString().lowercase()
77
+ if (vitals.contains(stringMetric)) {
78
+ context
79
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
80
+ .emit("vitals:$stringMetric", mapOf("duration" to duration, "portalName" to name).toReadableMap())
78
81
  }
79
82
  }
80
83
  portal.addPluginInstance(vitalsPlugin)
@@ -17,9 +17,7 @@ internal data class RNPortal(
17
17
  val builder: PortalBuilder,
18
18
  val index: String?,
19
19
  val plugins: List<PortalPlugin>,
20
- var onFCP: ((Long) -> Unit)? = null,
21
- var onTTFB: ((Long) -> Unit)? = null,
22
- var onFID: ((Long) -> Unit)? = null
20
+ var vitals: MutableList<String>? = null
23
21
  )
24
22
 
25
23
  internal data class PortalPlugin(val androidClassPath: String, val iosClassName: String) {
@@ -43,13 +41,12 @@ internal data class PortalPlugin(val androidClassPath: String, val iosClassName:
43
41
 
44
42
  internal object RNPortalManager {
45
43
  private val manager = PortalManager
46
- private val portals: ConcurrentHashMap<String, RNPortal> = ConcurrentHashMap()
47
44
  private lateinit var reactApplicationContext: ReactApplicationContext
48
45
  private var usesSecureLiveUpdates = false
49
46
 
50
47
  fun register(key: String) = manager.register(key)
51
48
 
52
- fun addPortal(map: ReadableMap): RNPortal? {
49
+ fun createPortal(map: ReadableMap): RNPortal? {
53
50
  val name = map.getString("name") ?: return null
54
51
  val portalBuilder = PortalBuilder(name)
55
52
 
@@ -60,13 +57,16 @@ internal object RNPortalManager {
60
57
  ?.toHashMap()
61
58
  ?.let(portalBuilder::setInitialContext)
62
59
 
60
+ if (map.hasKey("devMode")) {
61
+ map.getBoolean("devMode").let(portalBuilder::setDevMode)
62
+ }
63
63
 
64
64
  val plugins: List<PortalPlugin> = map.getArray("plugins")
65
65
  ?.let { rnArray ->
66
66
  val list = mutableListOf<PortalPlugin>()
67
67
  for (idx in 0 until rnArray.size()) {
68
68
  rnArray.getMap(idx)
69
- ?.let(PortalPlugin.Companion::fromReadableMap)
69
+ .let(PortalPlugin.Companion::fromReadableMap)
70
70
  ?.let(list::add)
71
71
  }
72
72
  return@let list
@@ -84,7 +84,7 @@ internal object RNPortalManager {
84
84
 
85
85
  for (idx in 0 until rnArray.size()) {
86
86
  rnArray.getMap(idx)
87
- ?.let assetMap@{ map ->
87
+ .let assetMap@{ map ->
88
88
  val name = map.getString("name") ?: return@assetMap null
89
89
  AssetMap(
90
90
  name = name,
@@ -105,11 +105,11 @@ internal object RNPortalManager {
105
105
  val appId = readableMap.getString("appId") ?: return@let null
106
106
  val channel = readableMap.getString("channel") ?: return@let null
107
107
  val syncOnAdd = readableMap.getBoolean("syncOnAdd")
108
- Pair(LiveUpdate(appId, channel, RNPortalManager.usesSecureLiveUpdates), syncOnAdd)
108
+ Pair(LiveUpdate(appId, channel, usesSecureLiveUpdates), syncOnAdd)
109
109
  }
110
110
  ?.let { (liveUpdate, updateOnAppLoad) ->
111
111
  portalBuilder.setLiveUpdateConfig(
112
- context = RNPortalManager.reactApplicationContext,
112
+ context = reactApplicationContext,
113
113
  liveUpdateConfig = liveUpdate,
114
114
  updateOnAppLoad = updateOnAppLoad
115
115
  )
@@ -118,19 +118,26 @@ internal object RNPortalManager {
118
118
  portalBuilder
119
119
  .addPlugin(PortalsPlugin::class.java)
120
120
 
121
- val rnPortal = RNPortal(
121
+ val vitals = map.getArray("webVitals")
122
+ val maybeList = if (vitals != null) {
123
+ val size = vitals.size()
124
+ (0 until size).fold(mutableListOf<String>()) { list, next ->
125
+ val vital = vitals.getString(next)
126
+ list.add(vital)
127
+ return@fold list
128
+ }
129
+ } else {
130
+ null
131
+ }
132
+
133
+ return RNPortal(
122
134
  builder = portalBuilder,
123
135
  index = map.getString("index"),
124
- plugins = plugins
136
+ plugins = plugins,
137
+ vitals = maybeList
125
138
  )
126
-
127
- portals[name] = rnPortal
128
- return rnPortal
129
139
  }
130
140
 
131
- fun getPortal(name: String): RNPortal = portals[name]
132
- ?: throw IllegalStateException("Portal with portalId $name not found in RNPortalManager")
133
-
134
141
  fun enableSecureLiveUpdates(keyPath: String) {
135
142
  LiveUpdateManager.secureLiveUpdatePEM = keyPath
136
143
  usesSecureLiveUpdates = true
@@ -162,13 +169,6 @@ internal object RNPortalManager {
162
169
  LiveUpdateManager.secureLiveUpdatePEM = it
163
170
  usesSecureLiveUpdates = true
164
171
  }
165
-
166
- val portalJsonArray = configJson.getJSONArray("portals")
167
-
168
- for (index in 0 until portalJsonArray.length()) {
169
- val portalJson = portalJsonArray.getJSONObject(index)
170
- addPortal(portalJson.toReactMap())
171
- }
172
172
  }
173
173
  }
174
174
 
@@ -1,7 +1,6 @@
1
1
  package io.ionic.portals.reactnative
2
2
 
3
3
  import com.facebook.react.bridge.*
4
- import io.ionic.portals.Portal
5
4
 
6
5
  internal class PortalManagerModule(reactContext: ReactApplicationContext) :
7
6
  ReactContextBaseJavaModule(reactContext) {
@@ -17,39 +16,6 @@ internal class PortalManagerModule(reactContext: ReactApplicationContext) :
17
16
  promise.resolve(null)
18
17
  }
19
18
 
20
- @ReactMethod
21
- fun addPortal(map: ReadableMap, promise: Promise) {
22
- val portal = RNPortalManager.addPortal(map)
23
- if (portal == null) {
24
- promise.reject(null, "Invalid Portal configuration.")
25
- } else {
26
- promise.resolve(portal.toReadableMap())
27
- }
28
- }
29
-
30
- @ReactMethod
31
- fun addPortals(array: ReadableArray, promise: Promise) {
32
- val portals = WritableNativeArray()
33
-
34
- for (i in 0 until array.size()) {
35
- val map = array.getMap(i) ?: continue
36
- val portal = RNPortalManager.addPortal(map) ?: continue
37
- portals.pushMap(portal.toReadableMap())
38
- }
39
-
40
- promise.resolve(portals)
41
- }
42
-
43
- @ReactMethod
44
- fun getPortal(name: String, promise: Promise) {
45
- try {
46
- val portal = RNPortalManager.getPortal(name)
47
- promise.resolve(portal.toReadableMap())
48
- } catch (e: IllegalStateException) {
49
- promise.reject(null, "Portal named $name not registered.")
50
- }
51
- }
52
-
53
19
  @ReactMethod
54
20
  fun enableSecureLiveUpdates(keyPath: String, promise: Promise) {
55
21
  RNPortalManager.enableSecureLiveUpdates(keyPath)
@@ -4,44 +4,10 @@ import com.facebook.react.bridge.Promise
4
4
  import com.facebook.react.bridge.ReactApplicationContext
5
5
  import com.facebook.react.bridge.ReactContextBaseJavaModule
6
6
  import com.facebook.react.bridge.ReactMethod
7
- import com.facebook.react.modules.core.DeviceEventManagerModule
8
7
 
9
8
  internal class PortalWebVitalsModule(reactContext: ReactApplicationContext): ReactContextBaseJavaModule(reactContext) {
10
9
  override fun getName() = "IONPortalsWebVitals"
11
10
 
12
- @ReactMethod
13
- fun registerOnFirstContentfulPaint(portalName: String, promise: Promise) {
14
- RNPortalManager.getPortal(portalName).onFCP = { duration ->
15
- reactApplicationContext
16
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
17
- .emit("vitals:fcp", mapOf("duration" to duration, "portalName" to portalName).toReadableMap())
18
- }
19
-
20
- promise.resolve(null)
21
- }
22
-
23
- @ReactMethod
24
- fun registerOnFirstInputDelay(portalName: String, promise: Promise) {
25
- RNPortalManager.getPortal(portalName).onFID = { duration ->
26
- reactApplicationContext
27
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
28
- .emit("vitals:fid", mapOf("duration" to duration, "portalName" to portalName).toReadableMap())
29
- }
30
-
31
- promise.resolve(null)
32
- }
33
-
34
- @ReactMethod
35
- fun registerOnTimeToFirstByte(portalName: String, promise: Promise) {
36
- RNPortalManager.getPortal(portalName).onTTFB = { duration ->
37
- reactApplicationContext
38
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
39
- .emit("vitals:ttfb", mapOf("duration" to duration, "portalName" to portalName).toReadableMap())
40
- }
41
-
42
- promise.resolve(null)
43
- }
44
-
45
11
  @ReactMethod
46
12
  fun addListener(eventName: String) {
47
13
  }
@@ -0,0 +1,33 @@
1
+ //
2
+ // IonicPortals+Codable.swift
3
+ // ReactNativePortals
4
+ //
5
+ // Created by Trevor Lambert on 6/5/24.
6
+ // Copyright © 2024 Facebook. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+ import IonicPortals
11
+
12
+ extension AssetMap: Encodable {
13
+ enum CodingKeys: String, CodingKey {
14
+ case startDir, virtualPath, name
15
+ }
16
+
17
+ public func encode(to encoder: Encoder) throws {
18
+ var container = encoder.container(keyedBy: CodingKeys.self)
19
+ try container.encode(startDir, forKey: .startDir)
20
+ try container.encode(virtualPath, forKey: .virtualPath)
21
+ try container.encode(name, forKey: .name)
22
+ }
23
+ }
24
+
25
+ extension AssetMap: Decodable {
26
+ public init(from decoder: Decoder) throws {
27
+ let container = try decoder.container(keyedBy: CodingKeys.self)
28
+ let name = try container.decode(String.self, forKey: .name)
29
+ let startDir = try container.decodeIfPresent(String.self, forKey: .startDir) ?? ""
30
+ let virtualPath = try container.decodeIfPresent(String.self, forKey: .virtualPath)
31
+ self.init(name: name, virtualPath: virtualPath, startDir: startDir)
32
+ }
33
+ }
@@ -7,63 +7,33 @@
7
7
  //
8
8
 
9
9
  import IonicLiveUpdates
10
+ import Capacitor
10
11
 
11
- struct SyncResults {
12
+ struct SyncResults: Encodable {
12
13
  var results: [LiveUpdateManager.SyncResult]
13
- var errors: [LiveUpdateManager.Error]
14
+ var errors: [LiveUpdateManager.SyncError]
14
15
  }
15
16
 
16
17
  extension SyncResults {
17
- var dict: [String: Any] {
18
- return [
19
- "results": results.map(\.dict),
20
- "errors": errors.map(\.dict)
21
- ]
18
+ init(_ results: ([LiveUpdateManager.SyncResult], [LiveUpdateManager.SyncError])) {
19
+ self.results = results.0
20
+ self.errors = results.1
21
+ }
22
+
23
+ var dict: JSValue {
24
+ get throws {
25
+ try JSValueEncoder(optionalEncodingStrategy: .undefined)
26
+ .encode(self)
27
+ }
22
28
  }
23
29
  }
24
30
 
25
31
  extension LiveUpdateManager {
26
32
  func syncSome(_ appIds: [String]) async -> SyncResults {
27
- await _syncSome(appIds).syncResults
28
- }
29
-
30
- private func _syncSome(_ appIds: [String]) -> AsyncStream<Result<LiveUpdateManager.SyncResult, LiveUpdateManager.Error>> {
31
- AsyncStream { continuation in
32
- sync(appIds: appIds, isParallel: true) {
33
- continuation.finish()
34
- } appComplete: { result in
35
- continuation.yield(result)
36
- }
37
- }
38
- }
39
-
40
- func syncAll() async -> SyncResults {
41
- await _syncAll().syncResults
42
- }
43
-
44
-
45
- private func _syncAll() -> AsyncStream<Result<LiveUpdateManager.SyncResult, LiveUpdateManager.Error>> {
46
- AsyncStream { continuation in
47
- sync(isParallel: true) {
48
- continuation.finish()
49
- } appComplete: { result in
50
- continuation.yield(result)
51
- }
52
- }
33
+ SyncResults(await sync(appIds: appIds))
53
34
  }
54
- }
55
35
 
56
- extension AsyncStream where Element == Result<LiveUpdateManager.SyncResult, LiveUpdateManager.Error> {
57
- var syncResults: SyncResults {
58
- get async {
59
- await reduce(into: SyncResults(results: [], errors: [])) { acc, next in
60
- switch next {
61
- case .success(let liveUpdate):
62
- acc.results.append(liveUpdate)
63
- case .failure(let error):
64
- acc.errors.append(error)
65
- }
66
- }
67
- }
36
+ func syncAll() async -> SyncResults {
37
+ SyncResults(await sync())
68
38
  }
69
39
  }