@ionic/portals-react-native 0.6.0 → 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.
@@ -33,7 +33,7 @@ internal class PortalViewManager(private val context: ReactApplicationContext) :
33
33
  when (fragmentMap[viewGroup.id]) {
34
34
  null -> fragmentMap[viewGroup.id] = PortalViewState(
35
35
  fragment = null,
36
- portal = RNPortalManager.getPortal(name) ?: RNPortalManager.createPortal(portal),
36
+ portal = RNPortalManager.createPortal(portal),
37
37
  initialContext = portal.getMap("initialContext")?.toHashMap()
38
38
  )
39
39
  }
@@ -41,20 +41,11 @@ internal data class PortalPlugin(val androidClassPath: String, val iosClassName:
41
41
 
42
42
  internal object RNPortalManager {
43
43
  private val manager = PortalManager
44
- @Deprecated("Will be removed in the next release.")
45
- private val portals: ConcurrentHashMap<String, RNPortal> = ConcurrentHashMap()
46
44
  private lateinit var reactApplicationContext: ReactApplicationContext
47
45
  private var usesSecureLiveUpdates = false
48
46
 
49
47
  fun register(key: String) = manager.register(key)
50
48
 
51
- @Deprecated("Will be removed in the next release.")
52
- fun addPortal(map: ReadableMap): RNPortal? {
53
- val portal = createPortal(map) ?: return null
54
- portals[portal.builder.name] = portal
55
- return portal
56
- }
57
-
58
49
  fun createPortal(map: ReadableMap): RNPortal? {
59
50
  val name = map.getString("name") ?: return null
60
51
  val portalBuilder = PortalBuilder(name)
@@ -147,11 +138,6 @@ internal object RNPortalManager {
147
138
  )
148
139
  }
149
140
 
150
- @Deprecated("Will be removed in the next release.")
151
- fun getPortal(name: String): RNPortal? {
152
- return portals[name]
153
- }
154
-
155
141
  fun enableSecureLiveUpdates(keyPath: String) {
156
142
  LiveUpdateManager.secureLiveUpdatePEM = keyPath
157
143
  usesSecureLiveUpdates = true
@@ -183,13 +169,6 @@ internal object RNPortalManager {
183
169
  LiveUpdateManager.secureLiveUpdatePEM = it
184
170
  usesSecureLiveUpdates = true
185
171
  }
186
-
187
- val portalJsonArray = configJson.getJSONArray("portals")
188
-
189
- for (index in 0 until portalJsonArray.length()) {
190
- val portalJson = portalJsonArray.getJSONObject(index)
191
- addPortal(portalJson.toReactMap())
192
- }
193
172
  }
194
173
  }
195
174
 
@@ -16,39 +16,6 @@ internal class PortalManagerModule(reactContext: ReactApplicationContext) :
16
16
  promise.resolve(null)
17
17
  }
18
18
 
19
- @ReactMethod
20
- fun addPortal(map: ReadableMap, promise: Promise) {
21
- val portal = RNPortalManager.addPortal(map)
22
- if (portal == null) {
23
- promise.reject(null, "Invalid Portal configuration.")
24
- } else {
25
- promise.resolve(portal.toReadableMap())
26
- }
27
- }
28
-
29
- @ReactMethod
30
- fun addPortals(array: ReadableArray, promise: Promise) {
31
- val portals = WritableNativeArray()
32
-
33
- for (i in 0 until array.size()) {
34
- val map = array.getMap(i)
35
- val portal = RNPortalManager.addPortal(map) ?: continue
36
- portals.pushMap(portal.toReadableMap())
37
- }
38
-
39
- promise.resolve(portals)
40
- }
41
-
42
- @ReactMethod
43
- fun getPortal(name: String, promise: Promise) {
44
- try {
45
- val portal = RNPortalManager.getPortal(name)
46
- promise.resolve(portal?.toReadableMap())
47
- } catch (e: IllegalStateException) {
48
- promise.reject(null, "Portal named $name not registered.")
49
- }
50
- }
51
-
52
19
  @ReactMethod
53
20
  fun enableSecureLiveUpdates(keyPath: String, promise: Promise) {
54
21
  RNPortalManager.enableSecureLiveUpdates(keyPath)
@@ -8,32 +8,6 @@ import com.facebook.react.bridge.ReactMethod
8
8
  internal class PortalWebVitalsModule(reactContext: ReactApplicationContext): ReactContextBaseJavaModule(reactContext) {
9
9
  override fun getName() = "IONPortalsWebVitals"
10
10
 
11
- private fun registerVital(portalName: String, vitalName: String) {
12
- val portal = RNPortalManager.getPortal(portalName) ?: return
13
- if (portal.vitals == null) {
14
- portal.vitals = mutableListOf()
15
- }
16
- portal.vitals?.add(vitalName)
17
- }
18
-
19
- @ReactMethod
20
- fun registerOnFirstContentfulPaint(portalName: String, promise: Promise) {
21
- registerVital(portalName,"fcp")
22
- promise.resolve(null)
23
- }
24
-
25
- @ReactMethod
26
- fun registerOnFirstInputDelay(portalName: String, promise: Promise) {
27
- registerVital(portalName,"fid")
28
- promise.resolve(null)
29
- }
30
-
31
- @ReactMethod
32
- fun registerOnTimeToFirstByte(portalName: String, promise: Promise) {
33
- registerVital(portalName,"ttfb")
34
- promise.resolve(null)
35
- }
36
-
37
11
  @ReactMethod
38
12
  fun addListener(eventName: String) {
39
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
+ }
@@ -11,9 +11,6 @@
11
11
  @interface RCT_EXTERN_MODULE(IONPortalsReactNative, NSObject)
12
12
  RCT_EXTERN_METHOD(register: (NSString *) key resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
13
13
  RCT_EXTERN_METHOD(enableSecureLiveUpdates: (NSString *) publicKeyPath resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
14
- RCT_EXTERN_METHOD(addPortal: (NSDictionary) portal resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
15
- RCT_EXTERN_METHOD(addPortals: (NSArray) portals resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
16
- RCT_EXTERN_METHOD(getPortal: (NSString *) name resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
17
14
  RCT_EXTERN_METHOD(syncOne: (NSString *) appId resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
18
15
  RCT_EXTERN_METHOD(syncSome: (NSArray) appIds resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
19
16
  RCT_EXTERN_METHOD(syncAll: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
@@ -27,28 +27,20 @@ class PortalView: UIView {
27
27
  }
28
28
 
29
29
  set {
30
- guard let portalDict = newValue,
31
- let name = portalDict["name"] as? String
32
- else { return }
33
-
30
+ guard let portalDict = newValue else { return }
31
+
34
32
  var portal: Portal
35
33
 
36
- if var deprecatedPortal = PortalsReactNative.getPortal(named: name) {
37
- if let initialContext = portalDict["initialContext"] as? [String: Any] {
38
- deprecatedPortal.initialContext = JSTypes.coerceDictionaryToJSObject(initialContext) ?? [:]
39
- }
40
- portal = deprecatedPortal
41
- } else {
34
+ do {
42
35
  let jsObject = JSTypes.coerceDictionaryToJSObject(portalDict) ?? [:]
43
- do {
44
- portal = try Portal.decode(from: jsObject, with: JSValueDecoder())
45
- } catch {
46
- print(error.localizedDescription)
47
- return
48
- }
36
+ portal = try Portal.decode(from: jsObject, with: JSValueDecoder())
37
+ } catch {
38
+ print(error.localizedDescription)
39
+ return
49
40
  }
41
+
50
42
  if portal.usesWebVitals {
51
- var vitalsPlugin = WebVitalsPlugin { portalName, duration in
43
+ let vitalsPlugin = WebVitalsPlugin { portalName, duration in
52
44
  IonicPortals.PortalsPubSub
53
45
  .shared
54
46
  .publish(
@@ -10,6 +10,5 @@
10
10
  #import <React/RCTEventEmitter.h>
11
11
 
12
12
  @interface RCT_EXTERN_MODULE(IONPortalsWebVitals, RCTEventEmitter)
13
- RCT_EXTERN_METHOD(registerOnFirstContentfulPaint: (NSString *) portalName resolver: (RCTPromiseResolveBlock) resolver rejector: (RCTPromiseRejectBlock) rejector)
14
13
  @end
15
14
 
@@ -7,8 +7,6 @@ import React
7
7
  @objc(IONPortalsReactNative)
8
8
  public class PortalsReactNative: NSObject {
9
9
  internal private(set) static var lum: LiveUpdateManager = .shared
10
- @available(*, deprecated, message: "This will be removed in the next release")
11
- internal static var portals = ConcurrentDictionary<String, Portal>(label: "com.portals.reactnative", dict: [:])
12
10
  let encoder = JSValueEncoder(optionalEncodingStrategy: .undefined)
13
11
  let decoder = JSValueDecoder()
14
12
 
@@ -41,44 +39,7 @@ public class PortalsReactNative: NSObject {
41
39
  Self.lum = SecureLiveUpdateManager(named: "secure-updates", publicKeyUrl: publicKeyUrl)
42
40
  resolver(())
43
41
  }
44
-
45
- @available(*, deprecated, message: "This will be removed in the next release")
46
- @objc func addPortal(_ portalDict: [String: Any], resolver: RCTPromiseResolveBlock, rejector: RCTPromiseRejectBlock) {
47
- do {
48
- let portal = try Portal.decode(from: JSTypes.coerceDictionaryToJSObject(portalDict) ?? [:], with: decoder)
49
- Self.portals[portal.name] = portal
50
- resolver(try encoder.encode(portal))
51
- } catch {
52
- rejector(nil, "Invalid Portal configuration", error)
53
- }
54
- }
55
-
56
- @available(*, deprecated, message: "This will be removed in the next release")
57
- @objc func addPortals(_ portalsArray: [[String: Any]], resolver: RCTPromiseResolveBlock, rejector: RCTPromiseRejectBlock) {
58
- do {
59
- let portals = try decoder.decode([Portal].self, from: JSTypes.coerceArrayToJSArray(portalsArray) ?? [])
60
- for portal in portals {
61
- Self.portals[portal.name] = portal
62
- }
63
- resolver(try encoder.encode(portals))
64
- } catch {
65
- rejector(nil, "Invalid Portal configuration", error)
66
- }
67
- }
68
-
69
- @available(*, deprecated, message: "This will be removed in the next release")
70
- static func getPortal(named name: String) -> Portal? { portals[name] }
71
-
72
- @available(*, deprecated, message: "This will be removed in the next release")
73
- @objc func getPortal(_ name: String, resolver: RCTPromiseResolveBlock, rejector: RCTPromiseRejectBlock) {
74
- guard let portal = Self.getPortal(named: name) else { return rejector(nil, "Portal named \(name) not registered", nil) }
75
- do {
76
- resolver(try encoder.encode(portal))
77
- } catch {
78
- rejector(nil, "Invalid Portal configuration", error)
79
- }
80
- }
81
-
42
+
82
43
  @objc func syncOne(_ appId: String, resolver: @escaping RCTPromiseResolveBlock, rejector: @escaping RCTPromiseRejectBlock) {
83
44
  Task {
84
45
  do {
@@ -33,16 +33,6 @@ class WebVitals: RCTEventEmitter {
33
33
  override func supportedEvents() -> [String] {
34
34
  [fcp]
35
35
  }
36
-
37
- @objc func registerOnFirstContentfulPaint(_ portalName: String, resolver: @escaping RCTPromiseResolveBlock, rejector: RCTPromiseRejectBlock) {
38
- guard var portal = PortalsReactNative.portals[portalName] else {
39
- return resolver(())
40
- }
41
-
42
- portal.usesWebVitals = true
43
- PortalsReactNative.portals[portalName] = portal
44
- resolver(())
45
- }
46
-
36
+
47
37
  override class func requiresMainQueueSetup() -> Bool { true }
48
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic/portals-react-native",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Portals for React Native",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
package/src/index.tsx CHANGED
@@ -53,8 +53,6 @@ export interface Message {
53
53
 
54
54
  const PortalsPubSub = new NativeEventEmitter(IONPortalPubSub);
55
55
 
56
- // const subscriptionMap = new Map<number, EmitterSubscription>();
57
-
58
56
  /**
59
57
  * Subscribes to messages for a topic
60
58
  *
@@ -111,57 +109,6 @@ const registerVital = (
111
109
  webVitalsMap.set(`${portalName}-vitals:${vital}`, listener);
112
110
  };
113
111
 
114
- /**
115
- * @deprecated Use {@link WebVitals} prop on {@link PortalView} instead. This will be removed in the next release.
116
- */
117
- export const onFirstContentfulPaint = async (
118
- portalName: string,
119
- callback: (duration: number) => void
120
- ): Promise<void> => {
121
- registerVital(portalName, 'fcp', callback);
122
- await IONPortalsWebVitals.registerOnFirstContentfulPaint(portalName);
123
- };
124
-
125
- /**
126
- * @deprecated Use {@link WebVitals} prop on {@link PortalView} instead. This will be removed in the next release.
127
- */
128
- export const onFirstInputDelay = async (
129
- portalName: string,
130
- callback: (duration: number) => void
131
- ) => {
132
- if (Platform.OS === 'android') {
133
- registerVital(portalName, 'fid', callback);
134
- await IONPortalsWebVitals.registerOnFirstInputDelay(portalName);
135
- }
136
- };
137
-
138
- /**
139
- * @deprecated Use {@link WebVitals} prop on {@link PortalView} instead. This will be removed in the next release.
140
- */
141
- export const onTimeToFirstByte = async (
142
- portalName: string,
143
- callback: (duration: number) => void
144
- ) => {
145
- if (Platform.OS === 'android') {
146
- registerVital(portalName, 'ttfb', callback);
147
- await IONPortalsWebVitals.registerOnTimeToFirstByte(portalName);
148
- }
149
- };
150
-
151
- /**
152
- * @deprecated Use {@link WebVitals} prop on {@link PortalView} instead. This will be removed in the next release.
153
- */
154
- export const registerWebVitals = async (
155
- portalName: string,
156
- firstContentfulPaint: (duration: number) => void,
157
- firstInputDelay: (duration: number) => void,
158
- timeToFirstByte: (duration: number) => void
159
- ) => {
160
- onFirstContentfulPaint(portalName, firstContentfulPaint);
161
- onFirstInputDelay(portalName, firstInputDelay);
162
- onTimeToFirstByte(portalName, timeToFirstByte);
163
- };
164
-
165
112
  export type WebVitals = {
166
113
  firstContentfulPaint?: (duration: number) => void;
167
114
  firstInputDelay?: (duration: number) => void;
@@ -227,44 +174,6 @@ export interface AssetMap {
227
174
  */
228
175
  export type PortalProps = { portal: Portal; webVitals?: WebVitals } & ViewProps;
229
176
 
230
- /**
231
- * @deprecated Portals are no longer centrally managed natively.
232
- * Pass a {@link Portal} directly to {@link PortalView} instead.
233
- * This will be removed in the next release.
234
- *
235
- * Adds a Portal to an internal registry.
236
- *
237
- * @param portal The portal to add to the internal registry.
238
- * @returns Promise containing the Portal that was added to the registry.
239
- */
240
- export const addPortal = async (portal: Portal): Promise<Portal> => {
241
- return IONPortalsReactNative.addPortal(portal);
242
- };
243
-
244
- /**
245
- * @deprecated Portals are no longer centrally managed natively.
246
- * Pass a {@link Portal} directly to {@link PortalView} instead.
247
- * This will be removed in the next release.
248
- *
249
- * @param portals The portals to add to the internal registry.
250
- * @returns Promise containing the Portals that were added to the registry.
251
- */
252
- export const addPortals = async (portals: Portal[]): Promise<Portal[]> => {
253
- return IONPortalsReactNative.addPortals(portals);
254
- };
255
-
256
- /**
257
- * @deprecated Portals are no longer centrally managed natively.
258
- * Pass a {@link Portal} directly to {@link PortalView} instead.
259
- * This will be removed in the next release.
260
- *
261
- * @param name The portal name to retrieve from the internal registry.
262
- * @returns Promise containing the registered {@link Portal}. If the {@link Portal} was not registered, the Promise will fail.
263
- */
264
- export const getPortal = async (name: string): Promise<Portal> => {
265
- return IONPortalsReactNative.getPortal(name);
266
- };
267
-
268
177
  export interface LiveUpdate {
269
178
  /** The AppFlow application ID */
270
179
  appId: string;
@@ -1,28 +0,0 @@
1
- //
2
- // AssetMap+Dict.swift
3
- // ReactNativePortals
4
- //
5
- // Created by Steven Sherry on 3/29/23.
6
- // Copyright © 2023 Facebook. All rights reserved.
7
- //
8
-
9
- import IonicPortals
10
-
11
- extension AssetMap {
12
- init?(_ dict: [String: Any]) {
13
- guard let name = dict["name"] as? String else { return nil }
14
- self.init(
15
- name: name,
16
- virtualPath: dict["virtualPath"] as? String,
17
- startDir: dict["startDir"] as? String ?? ""
18
- )
19
- }
20
-
21
- var dict: [String: Any] {
22
- return [
23
- "name": name,
24
- "virtualPath": virtualPath,
25
- "startDir": startDir
26
- ]
27
- }
28
- }
@@ -1,77 +0,0 @@
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
- }
34
-
35
- //export interface Portal {
36
- // /** The name of the Portal to be referenced. Must be **unique** */
37
- // name: string;
38
- // /** Any Capacitor plugins to be made available to the Portal */
39
- // plugins?: CapacitorPlugin[];
40
- // /**
41
- // * The root directory of the web application relative to Bundle.main on iOS
42
- // * and src/main/assets on Android. If omitted, `name` is used.
43
- // */
44
- // startDir?: string;
45
- // /** The name of the initial file to load. If omitted, 'index.html' is used. */
46
- // index?: string;
47
- // /** Any data needed at initial render when a portal is loaded. */
48
- // initialContext?: {
49
- // [key: string]: any;
50
- // };
51
- // assetMaps?: AssetMap[];
52
- // liveUpdate?: LiveUpdateConfig;
53
- //}
54
-
55
- //export interface LiveUpdate {
56
- // /** The AppFlow application ID */
57
- // appId: string;
58
- // /** The AppFlow distribution channel */
59
- // channel: string;
60
- //}
61
- //
62
- ///** Data needed to register a live update to be managed */
63
- //export type LiveUpdateConfig = LiveUpdate & { syncOnAdd: boolean };
64
-
65
- //export interface AssetMap {
66
- // /** The name to index the asset map by */
67
- // name: string;
68
- // /** Any path to match via the web. If omitted, {@link AssetMap#name} will be used. */
69
- // virtualPath?: string;
70
- // /** The root directory of the assets relative to Bundle.main on iOS
71
- // * and src/main/assets on Android. If omitted, the root of Bundle.main
72
- // * and src/main/assets will be used.
73
- // */
74
- // startDir?: string;
75
- //}
76
-
77
-