@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.
- package/dist/cjs/communication/http-client/index.js +5 -2
- package/dist/cjs/utils/micro-frontend/guest.js +19 -4
- package/dist/cjs/utils/micro-frontend/host.js +15 -5
- package/dist/cjs/utils/micro-frontend/scripting-objects/analytics.js +2 -2
- package/dist/cjs/utils/micro-frontend/ssf-host.js +44 -0
- package/dist/cjs/view/guest-microapp.js +59 -29
- package/dist/cjs/view/tests/__snapshots__/guest-microapp.test.tsx.snap +16 -0
- package/dist/cjs/view/tests/app.config.json +11 -0
- package/dist/cjs/view/tests/constants.js +2 -0
- package/dist/cjs/view/tests/serverHandlers.js +15 -0
- package/dist/cjs/view/tests/ssfapp/index.html +14 -0
- package/dist/cjs/view/tests/ssfapp/latest/index.js +16 -0
- package/dist/cjs/view/tests/ssfapp/latest/manifest.json +3 -0
- package/dist/esm/communication/http-client/index.js +5 -2
- package/dist/esm/utils/micro-frontend/guest.js +19 -4
- package/dist/esm/utils/micro-frontend/host.js +15 -5
- package/dist/esm/utils/micro-frontend/scripting-objects/analytics.js +2 -2
- package/dist/esm/utils/micro-frontend/ssf-host.js +24 -0
- package/dist/esm/view/guest-microapp.js +64 -31
- package/dist/esm/view/tests/__snapshots__/guest-microapp.test.tsx.snap +16 -0
- package/dist/esm/view/tests/app.config.json +11 -0
- package/dist/esm/view/tests/constants.js +2 -0
- package/dist/esm/view/tests/serverHandlers.js +15 -0
- package/dist/esm/view/tests/ssfapp/index.html +14 -0
- package/dist/esm/view/tests/ssfapp/latest/index.js +15 -0
- package/dist/esm/view/tests/ssfapp/latest/manifest.json +3 -0
- package/dist/types/lib/communication/http-client/index.d.ts +4 -2
- package/dist/types/lib/utils/micro-frontend/guest.d.ts +6 -3
- package/dist/types/lib/utils/micro-frontend/host.d.ts +1 -1
- package/dist/types/lib/utils/micro-frontend/ssf-host.d.ts +5 -0
- package/dist/types/lib/utils/micro-frontend/types.d.ts +4 -0
- package/dist/types/lib/view/tests/constants.d.ts +1 -0
- package/dist/types/lib/view/tests/ssfapp/latest/index.d.ts +2 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- 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 {
|
|
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
|
-
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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 (
|
|
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
|
+
});
|
|
@@ -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
|
-
*
|
|
77
|
-
* @param {
|
|
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";
|