@ionic/portals-react-native 0.1.0 → 0.2.0-1

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 (32) hide show
  1. package/README.md +11 -159
  2. package/ReactNativePortals.podspec +2 -1
  3. package/android/build.gradle +1 -1
  4. package/android/src/main/java/io/ionic/portals/reactnative/PortalView.kt +132 -0
  5. package/android/src/main/java/io/ionic/portals/reactnative/ReactNativeLiveUpdatesModule.kt +10 -28
  6. package/android/src/main/java/io/ionic/portals/reactnative/ReactNativePortalManager.kt +149 -0
  7. package/android/src/main/java/io/ionic/portals/reactnative/ReactNativePortalsModule.kt +73 -232
  8. package/android/src/main/java/io/ionic/portals/reactnative/ReactNativePortalsPackage.kt +0 -1
  9. package/android/src/main/java/io/ionic/portals/reactnative/ReactNativePortalsPubSub.kt +45 -0
  10. package/ios/LiveUpdate+Dict.swift +30 -0
  11. package/ios/LiveUpdateManager+Async.swift +69 -0
  12. package/ios/LiveUpdateManagerError+Dict.swift +19 -0
  13. package/ios/Podfile +2 -1
  14. package/ios/Podfile.lock +8 -7
  15. package/ios/Portal+Dict.swift +35 -0
  16. package/ios/PortalManager.m +10 -4
  17. package/ios/PortalView.m +1 -1
  18. package/ios/PortalView.swift +67 -0
  19. package/ios/PortalsConfig.swift +92 -0
  20. package/ios/PortalsPubSub.m +3 -3
  21. package/ios/PortalsPubSub.swift +47 -0
  22. package/ios/PortalsReactNative.swift +104 -0
  23. package/ios/ReactNativePortals.xcodeproj/project.pbxproj +32 -8
  24. package/lib/commonjs/index.js +55 -13
  25. package/lib/commonjs/index.js.map +1 -1
  26. package/lib/module/index.js +45 -12
  27. package/lib/module/index.js.map +1 -1
  28. package/lib/typescript/index.d.ts +27 -2
  29. package/package.json +3 -1
  30. package/src/index.ts +47 -12
  31. package/ios/LiveUpdatesManager.m +0 -16
  32. package/ios/ReactNativePortals.swift +0 -262
@@ -1,8 +1,7 @@
1
1
  import { NativeEventEmitter, NativeModules } from 'react-native';
2
2
  const {
3
3
  IONPortalPubSub,
4
- IONPortalManager,
5
- IONLiveUpdatesManager
4
+ IONPortalsReactNative
6
5
  } = NativeModules;
7
6
  export { default as PortalView } from './PortalView';
8
7
  /**
@@ -61,10 +60,11 @@ export const publish = (topic, data) => {
61
60
  /**
62
61
  * Validates that a valid registration key has been procured from http://ionic.io/register-portals
63
62
  * @param key The registration key
63
+ * @returns Promise<void>
64
64
  */
65
65
 
66
- export const register = key => {
67
- IONPortalManager.register(key);
66
+ export const register = async key => {
67
+ return IONPortalsReactNative.register(key);
68
68
  };
69
69
  /**
70
70
  * The configuration of a web application to be embedded in a React Native application.
@@ -74,19 +74,52 @@ export const register = key => {
74
74
  * Adds a Portal to an internal registry. Must be called before attempting to render a {@link PortalView}.
75
75
  *
76
76
  * @param portal The portal to add to the internal registry.
77
+ * @returns Promise containing the Portal that was added to the registry.
77
78
  */
78
- export const addPortal = portal => {
79
- IONPortalManager.addPortal(portal);
79
+ export const addPortal = async portal => {
80
+ return IONPortalsReactNative.addPortal(portal);
80
81
  };
82
+ /**
83
+ * Adds all portals to an internal registry. This or {@link addPortal} must be called before attempting to render a {@link PortalView}
84
+ *
85
+ * @param portals The portals to add to the internal registry.
86
+ * @returns Promise containing the Portals that were added to the registry.
87
+ */
81
88
 
89
+ export const addPortals = async portals => {
90
+ return IONPortalsReactNative.addPortals(portals);
91
+ };
92
+ /**
93
+ * Gets a {@link Portal} previously registered via {@link addPortal} or {@link addPortals}.
94
+ *
95
+ * @param name The portal name to retrieve from the internal registry.
96
+ * @returns Promise containing the registered {@link Portal}. If the {@link Portal} was not registered, the Promise will fail.
97
+ */
98
+
99
+ export const getPortal = async name => {
100
+ return IONPortalsReactNative.getPortal(name);
101
+ };
102
+
103
+ /**
104
+ * Configures LiveUpdates to cyrptographically verify the contents of the downloaded bundles.
105
+ * This method must be called before any LiveUpdates are registered otherwise they will no longer be tracked.
106
+ *
107
+ * @param pathToKey The *relative* path to the public key for verification.
108
+ * This path should be the same relatibe to the main application bundle on iOS and the assets directory on Android.
109
+ * @returns Promise<void>
110
+ */
111
+ export const enableSecureLiveUpdates = async pathToKey => {
112
+ return IONPortalsReactNative.enableSecureLiveUpdates(pathToKey);
113
+ };
82
114
  /**
83
115
  * Syncs a single live update.
84
116
  *
85
117
  * @param appId The AppFlow application ID to sync.
86
118
  * @returns A Promise<LiveUpdate>. A failure should result in a {@link LiveUpdateError}.
87
119
  */
88
- export const syncOne = appId => {
89
- return IONLiveUpdatesManager.syncOne(appId);
120
+
121
+ export const syncOne = async appId => {
122
+ return IONPortalsReactNative.syncOne(appId);
90
123
  };
91
124
  /**
92
125
  * Syncs many live updates.
@@ -95,15 +128,15 @@ export const syncOne = appId => {
95
128
  * @returns Promise<SyncResults>
96
129
  */
97
130
 
98
- export const syncSome = appIds => {
99
- return IONLiveUpdatesManager.syncSome(appIds);
131
+ export const syncSome = async appIds => {
132
+ return IONPortalsReactNative.syncSome(appIds);
100
133
  };
101
134
  /**
102
135
  * Syncs all registered LiveUpdates
103
136
  * @returns Promise<SyncResults>
104
137
  */
105
138
 
106
- export const syncAll = () => {
107
- return IONLiveUpdatesManager.syncAll();
139
+ export const syncAll = async () => {
140
+ return IONPortalsReactNative.syncAll();
108
141
  };
109
142
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
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\n/**\n * The data that is received from a subscription event.\n */\nexport interface Message {\n /** The unique subscription reference received from {@link subscribe}*/\n subscriptionRef: number;\n data: any;\n /** The topic the message was sent from */\n topic: string;\n}\n\nconst PortalsPubSub = new NativeEventEmitter(IONPortalPubSub);\n\nconst subscriptionMap = new Map<number, EmitterSubscription>();\n\n/**\n * Subscribes to messages for a topic\n *\n * @param topic The topic to subscribe to\n * @param onMessageReceived The callback to invoke when a message is received\n * @returns A Promise<number> containing the unique subscription reference. This will need to be stored for calling {@link unsubscribe}.\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\n/**\n * Unsubscribes from events for the provided topic and subscription reference\n *\n * @param topic The topic to unsubscribe from\n * @param subRef The unique subscription reference received when initially calling {@link subscribe}\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\n/**\n * Publishes a message to the provided topic\n *\n * @param topic The topic to publish the message to\n * @param data The data to publish to subscribers\n */\nexport const publish = (topic: string, data: any) => {\n const msg = { message: data };\n IONPortalPubSub.publish(topic, msg);\n};\n\n/**\n * Validates that a valid registration key has been procured from http://ionic.io/register-portals\n * @param key The registration key\n */\nexport const register = (key: string) => {\n IONPortalManager.register(key);\n};\n\n/**\n * The configuration of a web application to be embedded in a React Native application.\n */\nexport interface Portal {\n /** The name of the Portal to be referenced. Must be **unique** */\n name: string;\n /** The classpath of all Capacitor plugins used in Android. (e.g. com.capacitorjs.plugins.camera.CameraPlugin) */\n androidPlugins?: string[];\n /**\n * The root directory of the web application relative to Bundle.main on iOS\n * and src/main/assets on Android. If omitted, `name` is used.\n */\n startDir?: string;\n /** The name of the initial file to load. If omitted, 'index.html' is used. */\n index?: string;\n /** Any data needed at initial render when a portal is loaded. */\n initialContext?: {\n [key: string]: any;\n };\n liveUpdate?: LiveUpdateConfig;\n}\n\n/**\n * A subset of {@link Portal} properties needed for rendering a Portal. `initialContext` can be used to override\n * any initialContext defined in the original {@link Portal} definition.\n */\nexport type PortalProp = {\n portal: Pick<Portal, 'name' | 'initialContext'>;\n};\n\n/**\n * Props needed for rendering a {@link Portal}\n */\nexport type PortalProps = PortalProp & ViewProps;\n\n/**\n * Adds a Portal to an internal registry. Must be called before attempting to render a {@link PortalView}.\n *\n * @param portal The portal to add to the internal registry.\n */\nexport const addPortal = (portal: Portal) => {\n IONPortalManager.addPortal(portal);\n};\n\nexport interface LiveUpdate {\n /** The AppFlow application ID */\n appId: string;\n /** The AppFlow distribution channel */\n channel: string;\n}\n\n/** Data needed to register a live update to be managed */\nexport type LiveUpdateConfig = LiveUpdate & { syncOnAdd: boolean };\n\nexport interface LiveUpdateError {\n /** The AppFlow application ID relating to the failure */\n appId: string;\n /** The step in the sync process the LiveUpdate failed on. (e.g. CHECK, UNPACK)*/\n failStep: string;\n /** A human readable error message */\n message: string;\n}\n\n/** Used for communicating sync results of multiple live updates */\nexport interface SyncResults {\n liveUpdates: LiveUpdate[];\n errors: LiveUpdateError[];\n}\n\n/**\n * Syncs a single live update.\n *\n * @param appId The AppFlow application ID to sync.\n * @returns A Promise<LiveUpdate>. A failure should result in a {@link LiveUpdateError}.\n */\nexport const syncOne = (appId: string): Promise<LiveUpdate> => {\n return IONLiveUpdatesManager.syncOne(appId);\n};\n\n/**\n * Syncs many live updates.\n *\n * @param appIds The AppFlow application IDs to sync.\n * @returns Promise<SyncResults>\n */\nexport const syncSome = (appIds: string[]): Promise<SyncResults> => {\n return IONLiveUpdatesManager.syncSome(appIds);\n};\n\n/**\n * Syncs all registered LiveUpdates\n * @returns Promise<SyncResults>\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;AAEA;AACA;AACA;;AASA,MAAMC,aAAa,GAAG,IAAIP,kBAAJ,CAAuBE,eAAvB,CAAtB;AAEA,MAAMM,eAAe,GAAG,IAAIC,GAAJ,EAAxB;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,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;AACA;AACA;AACA;AACA;AACA;;AACA,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;AACA;AACA;AACA;AACA;AACA;;AACA,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;AACA;AACA;AACA;;AACA,OAAO,MAAMC,QAAQ,GAAIC,GAAD,IAAiB;EACvC1B,gBAAgB,CAACyB,QAAjB,CAA0BC,GAA1B;AACD,CAFM;AAIP;AACA;AACA;;AAiCA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,SAAS,GAAIC,MAAD,IAAoB;EAC3C5B,gBAAgB,CAAC2B,SAAjB,CAA2BC,MAA3B;AACD,CAFM;;AA6BP;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,OAAO,GAAIC,KAAD,IAAwC;EAC7D,OAAO7B,qBAAqB,CAAC4B,OAAtB,CAA8BC,KAA9B,CAAP;AACD,CAFM;AAIP;AACA;AACA;AACA;AACA;AACA;;AACA,OAAO,MAAMC,QAAQ,GAAIC,MAAD,IAA4C;EAClE,OAAO/B,qBAAqB,CAAC8B,QAAtB,CAA+BC,MAA/B,CAAP;AACD,CAFM;AAIP;AACA;AACA;AACA;;AACA,OAAO,MAAMC,OAAO,GAAG,MAA4B;EACjD,OAAOhC,qBAAqB,CAACgC,OAAtB,EAAP;AACD,CAFM"}
1
+ {"version":3,"names":["NativeEventEmitter","NativeModules","IONPortalPubSub","IONPortalsReactNative","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","addPortals","portals","getPortal","name","enableSecureLiveUpdates","pathToKey","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, IONPortalsReactNative } = NativeModules;\n\nexport { default as PortalView } from './PortalView';\n\n/**\n * The data that is received from a subscription event.\n */\nexport interface Message {\n /** The unique subscription reference received from {@link subscribe}*/\n subscriptionRef: number;\n data: any;\n /** The topic the message was sent from */\n topic: string;\n}\n\nconst PortalsPubSub = new NativeEventEmitter(IONPortalPubSub);\n\nconst subscriptionMap = new Map<number, EmitterSubscription>();\n\n/**\n * Subscribes to messages for a topic\n *\n * @param topic The topic to subscribe to\n * @param onMessageReceived The callback to invoke when a message is received\n * @returns A Promise<number> containing the unique subscription reference. This will need to be stored for calling {@link unsubscribe}.\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\n/**\n * Unsubscribes from events for the provided topic and subscription reference\n *\n * @param topic The topic to unsubscribe from\n * @param subRef The unique subscription reference received when initially calling {@link subscribe}\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\n/**\n * Publishes a message to the provided topic\n *\n * @param topic The topic to publish the message to\n * @param data The data to publish to subscribers\n */\nexport const publish = (topic: string, data: any) => {\n const msg = { message: data };\n IONPortalPubSub.publish(topic, msg);\n};\n\n/**\n * Validates that a valid registration key has been procured from http://ionic.io/register-portals\n * @param key The registration key\n * @returns Promise<void>\n */\nexport const register = async (key: string): Promise<void> => {\n return IONPortalsReactNative.register(key);\n};\n\n/**\n * The configuration of a web application to be embedded in a React Native application.\n */\nexport interface Portal {\n /** The name of the Portal to be referenced. Must be **unique** */\n name: string;\n /** The classpath of all Capacitor plugins used in Android. (e.g. com.capacitorjs.plugins.camera.CameraPlugin) */\n androidPlugins?: string[];\n /**\n * The root directory of the web application relative to Bundle.main on iOS\n * and src/main/assets on Android. If omitted, `name` is used.\n */\n startDir?: string;\n /** The name of the initial file to load. If omitted, 'index.html' is used. */\n index?: string;\n /** Any data needed at initial render when a portal is loaded. */\n initialContext?: {\n [key: string]: any;\n };\n liveUpdate?: LiveUpdateConfig;\n}\n\n/**\n * A subset of {@link Portal} properties needed for rendering a Portal. `initialContext` can be used to override\n * any initialContext defined in the original {@link Portal} definition.\n */\nexport type PortalProp = {\n portal: Pick<Portal, 'name' | 'initialContext'>;\n};\n\n/**\n * Props needed for rendering a {@link Portal}\n */\nexport type PortalProps = PortalProp & ViewProps;\n\n/**\n * Adds a Portal to an internal registry. Must be called before attempting to render a {@link PortalView}.\n *\n * @param portal The portal to add to the internal registry.\n * @returns Promise containing the Portal that was added to the registry.\n */\nexport const addPortal = async (portal: Portal): Promise<Portal> => {\n return IONPortalsReactNative.addPortal(portal);\n};\n\n/**\n * Adds all portals to an internal registry. This or {@link addPortal} must be called before attempting to render a {@link PortalView}\n *\n * @param portals The portals to add to the internal registry.\n * @returns Promise containing the Portals that were added to the registry.\n */\nexport const addPortals = async (portals: Portal[]): Promise<Portal[]> => {\n return IONPortalsReactNative.addPortals(portals);\n};\n\n/**\n * Gets a {@link Portal} previously registered via {@link addPortal} or {@link addPortals}.\n *\n * @param name The portal name to retrieve from the internal registry.\n * @returns Promise containing the registered {@link Portal}. If the {@link Portal} was not registered, the Promise will fail.\n */\nexport const getPortal = async (name: string): Promise<Portal> => {\n return IONPortalsReactNative.getPortal(name);\n};\n\nexport interface LiveUpdate {\n /** The AppFlow application ID */\n appId: string;\n /** The AppFlow distribution channel */\n channel: string;\n}\n\n/** Data needed to register a live update to be managed */\nexport type LiveUpdateConfig = LiveUpdate & { syncOnAdd: boolean };\n\nexport interface LiveUpdateError {\n /** The AppFlow application ID relating to the failure */\n appId: string;\n /** The step in the sync process the LiveUpdate failed on. (e.g. CHECK, UNPACK)*/\n failStep: string;\n /** A human readable error message */\n message: string;\n}\n\n/** Used for communicating sync results of multiple live updates */\nexport interface SyncResults {\n liveUpdates: LiveUpdate[];\n errors: LiveUpdateError[];\n}\n\n/**\n * Configures LiveUpdates to cyrptographically verify the contents of the downloaded bundles.\n * This method must be called before any LiveUpdates are registered otherwise they will no longer be tracked.\n *\n * @param pathToKey The *relative* path to the public key for verification.\n * This path should be the same relatibe to the main application bundle on iOS and the assets directory on Android.\n * @returns Promise<void>\n */\nexport const enableSecureLiveUpdates = async (\n pathToKey: string\n): Promise<void> => {\n return IONPortalsReactNative.enableSecureLiveUpdates(pathToKey);\n};\n\n/**\n * Syncs a single live update.\n *\n * @param appId The AppFlow application ID to sync.\n * @returns A Promise<LiveUpdate>. A failure should result in a {@link LiveUpdateError}.\n */\nexport const syncOne = async (appId: string): Promise<LiveUpdate> => {\n return IONPortalsReactNative.syncOne(appId);\n};\n\n/**\n * Syncs many live updates.\n *\n * @param appIds The AppFlow application IDs to sync.\n * @returns Promise<SyncResults>\n */\nexport const syncSome = async (appIds: string[]): Promise<SyncResults> => {\n return IONPortalsReactNative.syncSome(appIds);\n};\n\n/**\n * Syncs all registered LiveUpdates\n * @returns Promise<SyncResults>\n */\nexport const syncAll = async (): Promise<SyncResults> => {\n return IONPortalsReactNative.syncAll();\n};\n"],"mappings":"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"}
@@ -35,8 +35,9 @@ export declare const publish: (topic: string, data: any) => void;
35
35
  /**
36
36
  * Validates that a valid registration key has been procured from http://ionic.io/register-portals
37
37
  * @param key The registration key
38
+ * @returns Promise<void>
38
39
  */
39
- export declare const register: (key: string) => void;
40
+ export declare const register: (key: string) => Promise<void>;
40
41
  /**
41
42
  * The configuration of a web application to be embedded in a React Native application.
42
43
  */
@@ -73,8 +74,23 @@ export declare type PortalProps = PortalProp & ViewProps;
73
74
  * Adds a Portal to an internal registry. Must be called before attempting to render a {@link PortalView}.
74
75
  *
75
76
  * @param portal The portal to add to the internal registry.
77
+ * @returns Promise containing the Portal that was added to the registry.
76
78
  */
77
- export declare const addPortal: (portal: Portal) => void;
79
+ export declare const addPortal: (portal: Portal) => Promise<Portal>;
80
+ /**
81
+ * Adds all portals to an internal registry. This or {@link addPortal} must be called before attempting to render a {@link PortalView}
82
+ *
83
+ * @param portals The portals to add to the internal registry.
84
+ * @returns Promise containing the Portals that were added to the registry.
85
+ */
86
+ export declare const addPortals: (portals: Portal[]) => Promise<Portal[]>;
87
+ /**
88
+ * Gets a {@link Portal} previously registered via {@link addPortal} or {@link addPortals}.
89
+ *
90
+ * @param name The portal name to retrieve from the internal registry.
91
+ * @returns Promise containing the registered {@link Portal}. If the {@link Portal} was not registered, the Promise will fail.
92
+ */
93
+ export declare const getPortal: (name: string) => Promise<Portal>;
78
94
  export interface LiveUpdate {
79
95
  /** The AppFlow application ID */
80
96
  appId: string;
@@ -98,6 +114,15 @@ export interface SyncResults {
98
114
  liveUpdates: LiveUpdate[];
99
115
  errors: LiveUpdateError[];
100
116
  }
117
+ /**
118
+ * Configures LiveUpdates to cyrptographically verify the contents of the downloaded bundles.
119
+ * This method must be called before any LiveUpdates are registered otherwise they will no longer be tracked.
120
+ *
121
+ * @param pathToKey The *relative* path to the public key for verification.
122
+ * This path should be the same relatibe to the main application bundle on iOS and the assets directory on Android.
123
+ * @returns Promise<void>
124
+ */
125
+ export declare const enableSecureLiveUpdates: (pathToKey: string) => Promise<void>;
101
126
  /**
102
127
  * Syncs a single live update.
103
128
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic/portals-react-native",
3
- "version": "0.1.0",
3
+ "version": "0.2.0-1",
4
4
  "description": "Ionic Portals for React Native",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -29,6 +29,7 @@
29
29
  "typescript": "tsc --noEmit",
30
30
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
31
31
  "lint:fix": "eslint \"**/*.{js,ts,tsx}\" --fix",
32
+ "docs": "typedoc --out ./docs/documentation ./src --tsconfig ./tsconfig.build.json",
32
33
  "prepare": "bob build",
33
34
  "release": "release-it",
34
35
  "example": "yarn --cwd example",
@@ -68,6 +69,7 @@
68
69
  "react": "16.13.1",
69
70
  "react-native": "0.63.4",
70
71
  "react-native-builder-bob": "^0.18.2",
72
+ "typedoc": "^0.23.16",
71
73
  "typescript": "^4.1.3"
72
74
  },
73
75
  "peerDependencies": {
package/src/index.ts CHANGED
@@ -5,8 +5,7 @@ import {
5
5
  ViewProps,
6
6
  } from 'react-native';
7
7
 
8
- const { IONPortalPubSub, IONPortalManager, IONLiveUpdatesManager } =
9
- NativeModules;
8
+ const { IONPortalPubSub, IONPortalsReactNative } = NativeModules;
10
9
 
11
10
  export { default as PortalView } from './PortalView';
12
11
 
@@ -82,9 +81,10 @@ export const publish = (topic: string, data: any) => {
82
81
  /**
83
82
  * Validates that a valid registration key has been procured from http://ionic.io/register-portals
84
83
  * @param key The registration key
84
+ * @returns Promise<void>
85
85
  */
86
- export const register = (key: string) => {
87
- IONPortalManager.register(key);
86
+ export const register = async (key: string): Promise<void> => {
87
+ return IONPortalsReactNative.register(key);
88
88
  };
89
89
 
90
90
  /**
@@ -126,9 +126,30 @@ export type PortalProps = PortalProp & ViewProps;
126
126
  * Adds a Portal to an internal registry. Must be called before attempting to render a {@link PortalView}.
127
127
  *
128
128
  * @param portal The portal to add to the internal registry.
129
+ * @returns Promise containing the Portal that was added to the registry.
129
130
  */
130
- export const addPortal = (portal: Portal) => {
131
- IONPortalManager.addPortal(portal);
131
+ export const addPortal = async (portal: Portal): Promise<Portal> => {
132
+ return IONPortalsReactNative.addPortal(portal);
133
+ };
134
+
135
+ /**
136
+ * Adds all portals to an internal registry. This or {@link addPortal} must be called before attempting to render a {@link PortalView}
137
+ *
138
+ * @param portals The portals to add to the internal registry.
139
+ * @returns Promise containing the Portals that were added to the registry.
140
+ */
141
+ export const addPortals = async (portals: Portal[]): Promise<Portal[]> => {
142
+ return IONPortalsReactNative.addPortals(portals);
143
+ };
144
+
145
+ /**
146
+ * Gets a {@link Portal} previously registered via {@link addPortal} or {@link addPortals}.
147
+ *
148
+ * @param name The portal name to retrieve from the internal registry.
149
+ * @returns Promise containing the registered {@link Portal}. If the {@link Portal} was not registered, the Promise will fail.
150
+ */
151
+ export const getPortal = async (name: string): Promise<Portal> => {
152
+ return IONPortalsReactNative.getPortal(name);
132
153
  };
133
154
 
134
155
  export interface LiveUpdate {
@@ -156,14 +177,28 @@ export interface SyncResults {
156
177
  errors: LiveUpdateError[];
157
178
  }
158
179
 
180
+ /**
181
+ * Configures LiveUpdates to cyrptographically verify the contents of the downloaded bundles.
182
+ * This method must be called before any LiveUpdates are registered otherwise they will no longer be tracked.
183
+ *
184
+ * @param pathToKey The *relative* path to the public key for verification.
185
+ * This path should be the same relatibe to the main application bundle on iOS and the assets directory on Android.
186
+ * @returns Promise<void>
187
+ */
188
+ export const enableSecureLiveUpdates = async (
189
+ pathToKey: string
190
+ ): Promise<void> => {
191
+ return IONPortalsReactNative.enableSecureLiveUpdates(pathToKey);
192
+ };
193
+
159
194
  /**
160
195
  * Syncs a single live update.
161
196
  *
162
197
  * @param appId The AppFlow application ID to sync.
163
198
  * @returns A Promise<LiveUpdate>. A failure should result in a {@link LiveUpdateError}.
164
199
  */
165
- export const syncOne = (appId: string): Promise<LiveUpdate> => {
166
- return IONLiveUpdatesManager.syncOne(appId);
200
+ export const syncOne = async (appId: string): Promise<LiveUpdate> => {
201
+ return IONPortalsReactNative.syncOne(appId);
167
202
  };
168
203
 
169
204
  /**
@@ -172,14 +207,14 @@ export const syncOne = (appId: string): Promise<LiveUpdate> => {
172
207
  * @param appIds The AppFlow application IDs to sync.
173
208
  * @returns Promise<SyncResults>
174
209
  */
175
- export const syncSome = (appIds: string[]): Promise<SyncResults> => {
176
- return IONLiveUpdatesManager.syncSome(appIds);
210
+ export const syncSome = async (appIds: string[]): Promise<SyncResults> => {
211
+ return IONPortalsReactNative.syncSome(appIds);
177
212
  };
178
213
 
179
214
  /**
180
215
  * Syncs all registered LiveUpdates
181
216
  * @returns Promise<SyncResults>
182
217
  */
183
- export const syncAll = (): Promise<SyncResults> => {
184
- return IONLiveUpdatesManager.syncAll();
218
+ export const syncAll = async (): Promise<SyncResults> => {
219
+ return IONPortalsReactNative.syncAll();
185
220
  };
@@ -1,16 +0,0 @@
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
@@ -1,262 +0,0 @@
1
- import Foundation
2
- import IonicPortals
3
- import IonicLiveUpdates
4
- import React
5
- import UIKit
6
- import Capacitor
7
-
8
- @objc(IONPortalManager)
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] }
21
-
22
- @objc func register(_ key: String) {
23
- Self.register(key)
24
- }
25
-
26
- @objc func addPortal(_ portalDict: [String: Any]) {
27
- guard let portal = Portal(portalDict) else { return }
28
- Self.add(portal)
29
- }
30
-
31
- @objc static func requiresMainQueueSetup() -> Bool { true }
32
- }
33
-
34
- @objc(IONPortalPubSub)
35
- class PortalsPubSub: RCTEventEmitter {
36
- private let eventName = "PortalsSubscription"
37
-
38
- override func supportedEvents() -> [String]! {
39
- [eventName]
40
- }
41
-
42
- @objc func subscribe(_ topic: String, resolver: RCTPromiseResolveBlock, rejector: RCTPromiseRejectBlock) {
43
- let subRef = IonicPortals.PortalsPubSub.subscribe(topic) { [weak self] result in
44
- guard let self = self else { return }
45
- self.sendEvent(
46
- withName: self.eventName,
47
- body: [
48
- "subscriptionRef": result.subscriptionRef,
49
- "topic": result.topic,
50
- "data": result.data
51
- ]
52
- )
53
- }
54
-
55
- resolver(subRef)
56
- }
57
-
58
- @objc func unsubscribe(_ topic: String, subscriptionRef: NSNumber) {
59
- IonicPortals.PortalsPubSub.unsubscribe(from: topic, subscriptionRef: subscriptionRef.intValue)
60
- }
61
-
62
- @objc func publish(_ topic: String, data: Any) {
63
- IONPortalsPubSub.publish(message: data, topic: topic)
64
- }
65
-
66
- override class func requiresMainQueueSetup() -> Bool { true }
67
- }
68
-
69
- @objc(IONPortalViewManager)
70
- class PortalViewManager: RCTViewManager {
71
- override class func requiresMainQueueSetup() -> Bool { true }
72
- override func view() -> UIView! { PortalView() }
73
- }
74
-
75
- class PortalView: UIView {
76
- private var webView: PortalUIView?
77
-
78
- @objc var portal: [String: Any]? {
79
- get {
80
- guard let _portal = _portal else { return nil }
81
- return [
82
- "name": _portal.name,
83
- "initialContext": _portal.initialContext
84
- ]
85
- }
86
-
87
- set {
88
- guard let portalDict = newValue,
89
- let name = portalDict["name"] as? String
90
- else { return }
91
-
92
- var portal = PortalManager.getPortal(named: name)
93
- if let initialContext = portalDict["initialContext"] as? [String: Any] {
94
- portal?.initialContext = JSTypes.coerceDictionaryToJSObject(initialContext) ?? [:]
95
- }
96
-
97
- _portal = portal
98
- }
99
- }
100
-
101
- private var _portal: Portal? {
102
- didSet {
103
- guard let portal = _portal else { return }
104
-
105
- DispatchQueue.main.async { [weak self] in
106
- guard let self = self else { return }
107
- self.webView?.removeFromSuperview()
108
- let webView = PortalUIView(portal: portal)
109
- webView.translatesAutoresizingMaskIntoConstraints = false
110
- self.addSubview(webView)
111
- NSLayoutConstraint.activate([
112
- webView.topAnchor.constraint(equalTo: self.topAnchor),
113
- webView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
114
- webView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
115
- webView.trailingAnchor.constraint(equalTo: self.trailingAnchor)
116
- ])
117
- self.webView = webView
118
- }
119
- }
120
- }
121
- }
122
-
123
- extension Portal {
124
- init?(_ dict: [String: Any]) {
125
- guard let name = dict["name"] as? String else { return nil }
126
- self.init(
127
- name: name,
128
- startDir: dict["startDir"] as? String,
129
- index: dict["index"] as? String ?? "index.html",
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
- }