@elliemae/pui-app-sdk 5.30.2 → 5.31.0-beta.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 (35) hide show
  1. package/dist/cjs/communication/http-client/index.js +5 -2
  2. package/dist/cjs/utils/micro-frontend/guest.js +19 -4
  3. package/dist/cjs/utils/micro-frontend/host.js +15 -5
  4. package/dist/cjs/utils/micro-frontend/scripting-objects/analytics.js +2 -2
  5. package/dist/cjs/utils/micro-frontend/ssf-host.js +44 -0
  6. package/dist/cjs/view/guest-microapp.js +59 -29
  7. package/dist/cjs/view/tests/__snapshots__/guest-microapp.test.tsx.snap +16 -0
  8. package/dist/cjs/view/tests/app.config.json +11 -0
  9. package/dist/cjs/view/tests/constants.js +2 -0
  10. package/dist/cjs/view/tests/serverHandlers.js +15 -0
  11. package/dist/cjs/view/tests/ssfapp/index.html +14 -0
  12. package/dist/cjs/view/tests/ssfapp/latest/index.js +16 -0
  13. package/dist/cjs/view/tests/ssfapp/latest/manifest.json +3 -0
  14. package/dist/esm/communication/http-client/index.js +5 -2
  15. package/dist/esm/utils/micro-frontend/guest.js +19 -4
  16. package/dist/esm/utils/micro-frontend/host.js +15 -5
  17. package/dist/esm/utils/micro-frontend/scripting-objects/analytics.js +2 -2
  18. package/dist/esm/utils/micro-frontend/ssf-host.js +24 -0
  19. package/dist/esm/view/guest-microapp.js +64 -31
  20. package/dist/esm/view/tests/__snapshots__/guest-microapp.test.tsx.snap +16 -0
  21. package/dist/esm/view/tests/app.config.json +11 -0
  22. package/dist/esm/view/tests/constants.js +2 -0
  23. package/dist/esm/view/tests/serverHandlers.js +15 -0
  24. package/dist/esm/view/tests/ssfapp/index.html +14 -0
  25. package/dist/esm/view/tests/ssfapp/latest/index.js +15 -0
  26. package/dist/esm/view/tests/ssfapp/latest/manifest.json +3 -0
  27. package/dist/types/lib/communication/http-client/index.d.ts +4 -2
  28. package/dist/types/lib/utils/micro-frontend/guest.d.ts +6 -3
  29. package/dist/types/lib/utils/micro-frontend/host.d.ts +1 -1
  30. package/dist/types/lib/utils/micro-frontend/ssf-host.d.ts +5 -0
  31. package/dist/types/lib/utils/micro-frontend/types.d.ts +4 -0
  32. package/dist/types/lib/view/tests/constants.d.ts +1 -0
  33. package/dist/types/lib/view/tests/ssfapp/latest/index.d.ts +2 -0
  34. package/dist/types/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +44 -44
@@ -1,10 +1,14 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { memo, useLayoutEffect, useRef } from "react";
2
+ import { memo, useLayoutEffect, useRef, useCallback } from "react";
3
3
  import styled from "styled-components";
4
4
  import { useDispatch } from "react-redux";
5
5
  import { getAppBridge } from "../utils/micro-frontend/app-bridge.js";
6
+ import { getSSFHost } from "../utils/micro-frontend/ssf-host.js";
6
7
  import { waitMessage } from "../data/wait-message/actions.js";
7
- import { getLogger } from "../utils/micro-frontend/index.js";
8
+ import {
9
+ getLogger,
10
+ getMicroFrontEndAppConfig
11
+ } from "../utils/micro-frontend/index.js";
8
12
  const Div = styled.div`
9
13
  display: flex;
10
14
  width: 100%;
@@ -23,32 +27,56 @@ const useAppRenderer = (props) => {
23
27
  containerId
24
28
  } = props;
25
29
  const dispatch = useDispatch();
30
+ const getConfig = useCallback(
31
+ () => getMicroFrontEndAppConfig({
32
+ id
33
+ }),
34
+ [id]
35
+ );
26
36
  useLayoutEffect(() => {
27
37
  let isMounted = true;
28
38
  let appBridge = null;
39
+ let ssfHost = null;
29
40
  let unloadInProgress = Promise.resolve();
30
41
  let instanceId = null;
31
42
  (async () => {
32
43
  await unloadInProgress;
33
44
  dispatch(waitMessage.open());
34
45
  try {
35
- appBridge = await getAppBridge();
36
- if (!appBridge)
37
- throw new Error(`Failed to load ${id}, AppBridge not initialized`);
38
- if (isMounted) {
39
- instanceId = await appBridge.openApp({
40
- id,
41
- frameOptions: { containerId },
42
- history,
43
- homeRoute,
44
- initialRoute
45
- });
46
- setTimeout(() => {
47
- try {
48
- onLoadComplete?.(instanceId);
49
- } catch (ex) {
50
- }
51
- }, 0);
46
+ const { ssfOnly, hostUrl, name } = getConfig();
47
+ if (ssfOnly) {
48
+ ssfHost = getSSFHost();
49
+ if (!ssfHost)
50
+ throw new Error(`Failed to load ${id}, SSFHost not initialized`);
51
+ if (isMounted) {
52
+ const guest = ssfHost.loadGuest({
53
+ id,
54
+ url: hostUrl,
55
+ title: name,
56
+ targetElement: document.getElementById(containerId),
57
+ onLoad: onLoadComplete
58
+ });
59
+ instanceId = guest.id;
60
+ }
61
+ } else {
62
+ appBridge = await getAppBridge();
63
+ if (!appBridge)
64
+ throw new Error(`Failed to load ${id}, AppBridge not initialized`);
65
+ if (isMounted) {
66
+ instanceId = await appBridge.openApp({
67
+ id,
68
+ frameOptions: { containerId },
69
+ history,
70
+ homeRoute,
71
+ initialRoute
72
+ });
73
+ setTimeout(() => {
74
+ try {
75
+ onLoadComplete?.(instanceId);
76
+ } catch (ex) {
77
+ }
78
+ }, 0);
79
+ }
52
80
  }
53
81
  } catch (ex) {
54
82
  getLogger().error({
@@ -58,6 +86,8 @@ const useAppRenderer = (props) => {
58
86
  isMounted = false;
59
87
  if (appBridge && instanceId)
60
88
  unloadInProgress = appBridge.closeApp(instanceId);
89
+ if (ssfHost && instanceId)
90
+ unloadInProgress = Promise.resolve(ssfHost.unloadGuest(instanceId));
61
91
  throw ex;
62
92
  } finally {
63
93
  dispatch(waitMessage.close());
@@ -65,19 +95,21 @@ const useAppRenderer = (props) => {
65
95
  })();
66
96
  return () => {
67
97
  isMounted = false;
68
- if (appBridge) {
98
+ if (ssfHost) {
99
+ unloadInProgress = Promise.resolve(ssfHost.unloadGuest(instanceId));
100
+ } else if (appBridge) {
69
101
  unloadInProgress = appBridge.closeApp(instanceId);
70
- unloadInProgress.then(() => {
71
- instanceId = null;
72
- setTimeout(() => {
73
- try {
74
- onUnloadComplete?.();
75
- } catch (ex) {
76
- }
77
- }, 0);
78
- }).catch(() => {
79
- });
80
102
  }
103
+ unloadInProgress.then(() => {
104
+ instanceId = null;
105
+ setTimeout(() => {
106
+ try {
107
+ onUnloadComplete?.();
108
+ } catch (ex) {
109
+ }
110
+ }, 0);
111
+ }).catch(() => {
112
+ });
81
113
  };
82
114
  }, [
83
115
  containerId,
@@ -87,7 +119,8 @@ const useAppRenderer = (props) => {
87
119
  initialRoute,
88
120
  id,
89
121
  onLoadComplete,
90
- onUnloadComplete
122
+ onUnloadComplete,
123
+ getConfig
91
124
  ]);
92
125
  };
93
126
  const GuestMicroApp = memo(
@@ -1,5 +1,21 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`GuestMicroApp with SSFHost should open ssfapp 1`] = `
4
+ "<html lang="en"><head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>SSFApp</title>
8
+ <!-- <script src="https://cdn.mortgagetech.q1.ice.com/ssf-guest"></script> -->
9
+ </head>
10
+ <body>
11
+ <h1>SSF App</h1>
12
+ <output id="output">ssfapp starting
13
+ ssfapp loaded</output>
14
+ <script src="./latest/index.js"></script>
15
+
16
+ </body></html>"
17
+ `;
18
+
3
19
  exports[`MicroAppV2 should open loanapp and call init and mount methods 1`] = `
4
20
  Document {
5
21
  "location": Location {
@@ -15,6 +15,17 @@
15
15
  "files": ["index.js"]
16
16
  }
17
17
  },
18
+ "ssfapp": {
19
+ "name": "SSF App",
20
+ "hostUrl": "./ssfapp",
21
+ "ssfOnly": true,
22
+ "development": {
23
+ "files": ["index.js"]
24
+ },
25
+ "production": {
26
+ "files": ["index.js"]
27
+ }
28
+ },
18
29
  "taskapp": {
19
30
  "name": "Task",
20
31
  "hostUrl": "./task",
@@ -1,6 +1,7 @@
1
1
  const LATEST_VERSION = "latest";
2
2
  const RELEASE_VERSION = "23.1.0";
3
3
  const LOAN_APP_ID = "loanapp";
4
+ const SSF_APP_ID = "ssfapp";
4
5
  const TASK_APP_ID = "taskapp";
5
6
  const FLIGHTS_APP_ID = "flights";
6
7
  const HOTELS_APP_ID = "hotels";
@@ -20,5 +21,6 @@ export {
20
21
  LOAN_SAVED_EVENT,
21
22
  PRE_COMMIT_EVENT,
22
23
  RELEASE_VERSION,
24
+ SSF_APP_ID,
23
25
  TASK_APP_ID
24
26
  };
@@ -172,6 +172,21 @@ const serverHandlers = [
172
172
  "/loan/latest/manifest.json",
173
173
  (req, res, ctx) => res(ctx.json(loanAppManifest))
174
174
  ),
175
+ rest.get("/ssfapp/", async (req, res, ctx) => {
176
+ const fileContent = await readFile(
177
+ path.join(__dirname, "ssfapp/index.html"),
178
+ "utf-8"
179
+ );
180
+ return res(
181
+ ctx.status(200),
182
+ ctx.set("Content-Type", "text/html"),
183
+ ctx.body(fileContent)
184
+ );
185
+ }),
186
+ rest.get("/ssfapp/latest/index.js", async (req, res, ctx) => {
187
+ const newRes = await sendJS(res, ctx, "./ssfapp/latest/index.js");
188
+ return newRes;
189
+ }),
175
190
  ...getServerHandlers()
176
191
  ];
177
192
  export {
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SSFApp</title>
7
+ <!-- <script src="https://cdn.mortgagetech.q1.ice.com/ssf-guest"></script> -->
8
+ </head>
9
+ <body>
10
+ <h1>SSF App</h1>
11
+ <output id="output"></output>
12
+ <script src="./latest/index.js"></script>
13
+ </body>
14
+ </html>
@@ -0,0 +1,15 @@
1
+ const appId = "ssfapp";
2
+ const output = document.getElementById("output");
3
+ output.textContent = `${appId} starting`;
4
+ window.addEventListener("beforeunload", () => {
5
+ if (output) {
6
+ output.textContent += `
7
+ ${appId} unloading`;
8
+ }
9
+ });
10
+ document.addEventListener("load", () => {
11
+ if (output) {
12
+ output.textContent += `
13
+ ${appId} loaded`;
14
+ }
15
+ });
@@ -0,0 +1,3 @@
1
+ {
2
+ "index.js": "latest/index.js"
3
+ }
@@ -5,12 +5,14 @@ export type RequestConfig = {
5
5
  Authorization?: string;
6
6
  } & AxiosRequestHeaders;
7
7
  export { getAuthorizationHeader };
8
- export declare const getHTTPClient: ({ baseURL, headers, }?: {
8
+ export declare const getHTTPClient: ({ baseURL, headers, sendLogRocketSessionHeader, }?: {
9
9
  baseURL?: string;
10
10
  headers?: RequestConfig;
11
+ sendLogRocketSessionHeader?: boolean;
11
12
  }) => AxiosInstance;
12
- export declare const getAuthHTTPClient: ({ baseURL, headers, ...rest }?: {
13
+ export declare const getAuthHTTPClient: ({ baseURL, headers, sendLogRocketSessionHeader, ...rest }?: {
13
14
  baseURL?: string;
14
15
  headers?: RequestConfig;
16
+ sendLogRocketSessionHeader?: boolean;
15
17
  rest?: any[];
16
18
  }) => AxiosInstance;
@@ -1,6 +1,7 @@
1
1
  import { DefaultTheme } from 'styled-components';
2
2
  import { History, To } from 'history';
3
3
  import type { IMicroAppGuest, IMicroAppHost, InitOptions, MountOptions } from '@elliemae/pui-micro-frontend-base';
4
+ import { SSFHost } from '@elliemae/ssf-host';
4
5
  import { ScriptingObjectTypes, Events } from '@elliemae/pui-scripting-object';
5
6
  import { IMicroFEHost } from '@elliemae/pui-app-bridge';
6
7
  import type { ScriptingObjects, EventListeners, SubscribeParam, UnsubscribeParam, DispatchEventParam, EventOptions, AddScriptingObjectParams } from '@elliemae/microfe-common';
@@ -24,6 +25,7 @@ interface ConstructorParams {
24
25
  onUnmount?: OnUnMountCallback;
25
26
  onGetRef?: OnGetRefCallback;
26
27
  history?: History;
28
+ ssfHostRef?: SSFHost<ScriptingObjectTypes, Events> | null;
27
29
  }
28
30
  export declare class CMicroAppGuest<AppObjects extends ScriptingObjects = Partial<ScriptingObjectTypes>, AppEvents extends EventListeners = Events> implements IMicroAppGuest<AppObjects, AppEvents> {
29
31
  #private;
@@ -73,10 +75,11 @@ export declare class CMicroAppGuest<AppObjects extends ScriptingObjects = Partia
73
75
  */
74
76
  addScriptingObject<SO extends AppObjects[keyof AppObjects]>(so: SO, params?: AddScriptingObjectParams): void;
75
77
  /**
76
- * dispatch event to child microapp
77
- * @param {DispatchEventParams<EventId, Params>} params - event parameters
78
+ * Dispatches an event to the child microapp.
79
+ * @param {DispatchEventParam<EventId, Params, Options>} params - Event parameters.
80
+ * @returns {Promise<any[]>} A promise that resolves with the combined results of dispatched events.
78
81
  */
79
- dispatchEvent<EventId extends Extract<keyof AppEvents, string>, Params extends Parameters<AppEvents[EventId]>[0]['eventParams'], Options extends EventOptions>(params: DispatchEventParam<EventId, Params, Options>): Promise<void>;
82
+ dispatchEvent<EventId extends Extract<keyof AppEvents, string>, Params extends Parameters<AppEvents[EventId]>[0]['eventParams'], Options extends EventOptions>(params: DispatchEventParam<EventId, Params, Options>): Promise<void | any[]>;
80
83
  /**
81
84
  * removes scripting object from child microapp use
82
85
  * @param objectId unique id of the scripting object
@@ -76,7 +76,7 @@ export declare class CMicroAppHost<AppObjects extends ScriptingObjects = Partial
76
76
  * dispatch event to child microapp
77
77
  * @param {DispatchEventParams<EventId, Params>} params - event parameters
78
78
  */
79
- dispatchEvent<EventId extends Extract<keyof AppEvents, string>, Params extends Parameters<AppEvents[EventId]>[0]['eventParams'], Options extends EventOptions>(params: DispatchEventParam<EventId, Params, Options>): Promise<void>;
79
+ dispatchEvent<EventId extends Extract<keyof AppEvents, string>, Params extends Parameters<AppEvents[EventId]>[0]['eventParams'], Options extends EventOptions>(params: DispatchEventParam<EventId, Params, Options>): Promise<void | any[]>;
80
80
  /**
81
81
  * removes scripting object from child microapp use
82
82
  * @param objectId unique id of the scripting object
@@ -0,0 +1,5 @@
1
+ import { SSFHost } from '@elliemae/ssf-host';
2
+ import { ScriptingObjectTypes, Events } from '@elliemae/pui-scripting-object';
3
+ import type { ScriptingObjects, EventListeners } from '@elliemae/microfe-common';
4
+ export declare const getSSFHost: <AppObjects extends ScriptingObjects = ScriptingObjectTypes, AppEvents extends EventListeners = Events>() => SSFHost<AppObjects, AppEvents>;
5
+ export declare const setSSFHost: (host: SSFHost<any, any>) => void;
@@ -11,6 +11,10 @@ export type MicroAppConfig = {
11
11
  manifestPath?: string;
12
12
  homeRoute: string;
13
13
  isJsModule?: boolean;
14
+ /**
15
+ * If true, application will only be loaded via SSFHost and not AppBridge.
16
+ */
17
+ ssfOnly?: boolean;
14
18
  files?: Array<string>;
15
19
  development?: EnvConfig;
16
20
  production?: EnvConfig;
@@ -1,6 +1,7 @@
1
1
  export declare const LATEST_VERSION = "latest";
2
2
  export declare const RELEASE_VERSION = "23.1.0";
3
3
  export declare const LOAN_APP_ID = "loanapp";
4
+ export declare const SSF_APP_ID = "ssfapp";
4
5
  export declare const TASK_APP_ID = "taskapp";
5
6
  export declare const FLIGHTS_APP_ID = "flights";
6
7
  export declare const HOTELS_APP_ID = "hotels";
@@ -0,0 +1,2 @@
1
+ declare const appId: "ssfapp";
2
+ declare const output: HTMLElement | null;