@elliemae/pui-app-sdk 5.30.4 → 5.31.0-beta.2

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 (40) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/utils/micro-frontend/guest.js +33 -16
  3. package/dist/cjs/utils/micro-frontend/host.js +15 -5
  4. package/dist/cjs/utils/micro-frontend/index.js +3 -2
  5. package/dist/cjs/utils/micro-frontend/scripting-objects/analytics.js +2 -2
  6. package/dist/cjs/utils/micro-frontend/ssf-host.js +44 -0
  7. package/dist/cjs/utils/micro-frontend/types.js +18 -0
  8. package/dist/cjs/view/guest-microapp.js +70 -30
  9. package/dist/cjs/view/tests/__snapshots__/guest-microapp.test.tsx.snap +16 -0
  10. package/dist/cjs/view/tests/app.config.json +5 -0
  11. package/dist/cjs/view/tests/constants.js +2 -0
  12. package/dist/cjs/view/tests/serverHandlers.js +15 -0
  13. package/dist/cjs/view/tests/ssfapp/index.html +14 -0
  14. package/dist/cjs/view/tests/ssfapp/latest/index.js +16 -0
  15. package/dist/cjs/view/tests/ssfapp/latest/manifest.json +3 -0
  16. package/dist/esm/utils/micro-frontend/guest.js +33 -16
  17. package/dist/esm/utils/micro-frontend/host.js +15 -5
  18. package/dist/esm/utils/micro-frontend/index.js +3 -2
  19. package/dist/esm/utils/micro-frontend/scripting-objects/analytics.js +2 -2
  20. package/dist/esm/utils/micro-frontend/ssf-host.js +24 -0
  21. package/dist/esm/utils/micro-frontend/types.js +14 -0
  22. package/dist/esm/view/guest-microapp.js +75 -32
  23. package/dist/esm/view/tests/__snapshots__/guest-microapp.test.tsx.snap +16 -0
  24. package/dist/esm/view/tests/app.config.json +5 -0
  25. package/dist/esm/view/tests/constants.js +2 -0
  26. package/dist/esm/view/tests/serverHandlers.js +15 -0
  27. package/dist/esm/view/tests/ssfapp/index.html +14 -0
  28. package/dist/esm/view/tests/ssfapp/latest/index.js +15 -0
  29. package/dist/esm/view/tests/ssfapp/latest/manifest.json +3 -0
  30. package/dist/types/lib/utils/micro-frontend/guest.d.ts +6 -3
  31. package/dist/types/lib/utils/micro-frontend/host.d.ts +1 -1
  32. package/dist/types/lib/utils/micro-frontend/ssf-host.d.ts +5 -0
  33. package/dist/types/lib/utils/micro-frontend/types.d.ts +68 -1
  34. package/dist/types/lib/view/guest-microapp.d.ts +49 -0
  35. package/dist/types/lib/view/tests/constants.d.ts +1 -0
  36. package/dist/types/lib/view/tests/ssfapp/latest/index.d.ts +2 -0
  37. package/dist/types/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +7 -7
  39. package/dist/cjs/utils/micro-frontend/tests/__snapshots__/guest.test.ts.snap +0 -242
  40. package/dist/esm/utils/micro-frontend/tests/__snapshots__/guest.test.ts.snap +0 -242
package/README.md CHANGED
@@ -8,7 +8,7 @@ Build: [![Build Status](https://jenkinsbuild.elliemae.cloud/job/UIPlatform/job/a
8
8
 
9
9
  [API Documentation](http://git.elliemae.io/pages/platform-ui/pui-app-sdk)
10
10
 
11
- [QA Environment](https://appsdk.pui.mortgagetech.d1.ice.com/)
11
+ [QA Environment](https://qa.appsdk.rd.elliemae.io)
12
12
 
13
13
  ## Major Version Changelog
14
14
 
@@ -46,6 +46,7 @@ var import_web_analytics = require("./scripting-objects/web-analytics.js");
46
46
  var import_logrocket = require("./scripting-objects/logrocket.js");
47
47
  var import_app_bridge = require("./app-bridge.js");
48
48
  var import_helpers = require("../helpers.js");
49
+ var import_ssf_host2 = require("./ssf-host.js");
49
50
  const isCrossDomain = () => {
50
51
  try {
51
52
  window.parent.document;
@@ -77,6 +78,10 @@ class CMicroAppGuest {
77
78
  * communication method used between microapps
78
79
  */
79
80
  #communicationMethod;
81
+ /**
82
+ * reference to SSFHost instance
83
+ */
84
+ #ssfHostRef;
80
85
  /**
81
86
  * AppBridge instance
82
87
  */
@@ -104,6 +109,8 @@ class CMicroAppGuest {
104
109
  (0, import_logger.setLogger)(this.logger);
105
110
  this.#logRocket = params?.logRocket ?? window.emui?.logRocket;
106
111
  (0, import_logrocket.setLogRocket)(this.#logRocket);
112
+ if (params?.ssfHostRef) (0, import_ssf_host2.setSSFHost)(params.ssfHostRef);
113
+ this.#ssfHostRef = (0, import_ssf_host2.getSSFHost)();
107
114
  this.onInit = params?.onInit;
108
115
  this.onMount = params?.onMount;
109
116
  this.onUnmount = params?.onUnmount;
@@ -243,18 +250,20 @@ class CMicroAppGuest {
243
250
  }
244
251
  async findHost() {
245
252
  let host = null;
246
- if (!isCrossDomain()) {
247
- host = window.parent?.emui?.MicroAppHost ?? null;
248
- }
249
- if (!host) {
250
- host = new import_ssf_guest.SSFGuest({ appLogger: this.logger });
251
- if (await (0, import_helpers.abortPromise)({
252
- promise: host.connect(),
253
- delay: 1e3,
254
- retValue: false
255
- })) {
256
- host = null;
257
- } else this.#communicationMethod = "ssf" /* SSF */;
253
+ if (window.parent !== window) {
254
+ if (!isCrossDomain()) {
255
+ host = window.parent?.emui?.MicroAppHost ?? null;
256
+ }
257
+ if (!host) {
258
+ host = new import_ssf_guest.SSFGuest({ appLogger: this.logger });
259
+ if (await (0, import_helpers.abortPromise)({
260
+ promise: host.connect(),
261
+ delay: 1e3,
262
+ retValue: false
263
+ })) {
264
+ host = null;
265
+ } else this.#communicationMethod = "ssf" /* SSF */;
266
+ }
258
267
  }
259
268
  return host;
260
269
  }
@@ -315,15 +324,22 @@ class CMicroAppGuest {
315
324
  if (this.#appBridge) {
316
325
  this.#appBridge.addScriptingObject(so, params);
317
326
  }
327
+ this.#ssfHostRef.addScriptingObject(so, params);
318
328
  }
319
329
  /**
320
- * dispatch event to child microapp
321
- * @param {DispatchEventParams<EventId, Params>} params - event parameters
330
+ * Dispatches an event to the child microapp.
331
+ * @param {DispatchEventParam<EventId, Params, Options>} params - Event parameters.
332
+ * @returns {Promise<any[]>} A promise that resolves with the combined results of dispatched events.
322
333
  */
323
334
  async dispatchEvent(params) {
324
- if (this.#appBridge) {
325
- await this.#appBridge.dispatchEvent(params);
335
+ const [appBridgeResult, ssfResult] = await Promise.all([
336
+ this.#appBridge ? this.#appBridge.dispatchEvent(params) : Promise.resolve(null),
337
+ this.#ssfHostRef.dispatchEvent(params)
338
+ ]);
339
+ if (Array.isArray(appBridgeResult) && Array.isArray(ssfResult)) {
340
+ return appBridgeResult.concat(ssfResult);
326
341
  }
342
+ return Promise.resolve();
327
343
  }
328
344
  /**
329
345
  * removes scripting object from child microapp use
@@ -333,5 +349,6 @@ class CMicroAppGuest {
333
349
  if (this.#appBridge) {
334
350
  this.#appBridge.removeScriptingObject(objectId);
335
351
  }
352
+ this.#ssfHostRef.removeScriptingObject(objectId);
336
353
  }
337
354
  }
@@ -40,6 +40,7 @@ var import_analytics = require("./scripting-objects/analytics.js");
40
40
  var import_web_analytics = require("./scripting-objects/web-analytics.js");
41
41
  var import_session = require("../session.js");
42
42
  var import_app_bridge = require("./app-bridge.js");
43
+ var import_ssf_host2 = require("./ssf-host.js");
43
44
  class CMicroAppHost {
44
45
  static instance;
45
46
  logger;
@@ -71,14 +72,16 @@ class CMicroAppHost {
71
72
  theme: params?.theme ?? (0, import_pui_theme.getDefaultTheme)()
72
73
  };
73
74
  this.activeGuests = {};
74
- this.#ssfHostRef = params?.ssfHostRef || null;
75
+ if (params?.ssfHostRef) (0, import_ssf_host2.setSSFHost)(params.ssfHostRef);
76
+ this.#ssfHostRef = (0, import_ssf_host2.getSSFHost)();
75
77
  const analyticsObj = params?.analytics ?? new import_analytics.Analytics({ logger: this.logger });
76
78
  this.scriptingObjects = {
77
79
  analytics: analyticsObj,
78
80
  ...params?.scriptingObjects ?? {}
79
81
  };
80
- this.#ssfHostRef?.publish?.(analyticsObj);
81
- this.#ssfHostRef?.addScriptingObject?.(analyticsObj);
82
+ this.#ssfHostRef.addScriptingObject(
83
+ analyticsObj
84
+ );
82
85
  this.getProps = this.getProps.bind(this);
83
86
  this.getLogger = this.getLogger.bind(this);
84
87
  this.getGuests = this.getGuests.bind(this);
@@ -213,15 +216,21 @@ class CMicroAppHost {
213
216
  if (this.#appBridge) {
214
217
  this.#appBridge.addScriptingObject(so, params);
215
218
  }
219
+ this.#ssfHostRef.addScriptingObject(so, params);
216
220
  }
217
221
  /**
218
222
  * dispatch event to child microapp
219
223
  * @param {DispatchEventParams<EventId, Params>} params - event parameters
220
224
  */
221
225
  async dispatchEvent(params) {
222
- if (this.#appBridge) {
223
- await this.#appBridge.dispatchEvent(params);
226
+ const [appBridgeResult, ssfResult] = await Promise.all([
227
+ this.#appBridge ? this.#appBridge.dispatchEvent(params) : Promise.resolve(null),
228
+ this.#ssfHostRef.dispatchEvent(params)
229
+ ]);
230
+ if (Array.isArray(appBridgeResult) && Array.isArray(ssfResult)) {
231
+ return appBridgeResult.concat(ssfResult);
224
232
  }
233
+ return Promise.resolve();
225
234
  }
226
235
  /**
227
236
  * removes scripting object from child microapp use
@@ -231,5 +240,6 @@ class CMicroAppHost {
231
240
  if (this.#appBridge) {
232
241
  this.#appBridge.removeScriptingObject(objectId);
233
242
  }
243
+ this.#ssfHostRef.removeScriptingObject(objectId);
234
244
  }
235
245
  }
@@ -40,13 +40,14 @@ var import_guest = require("./guest.js");
40
40
  var import_host = require("./host.js");
41
41
  var import_config = require("../app-config/config.js");
42
42
  var import_helpers = require("../helpers.js");
43
+ var import_types2 = require("./types.js");
43
44
  const isHost = () => import_host.CMicroAppHost.isInitialized();
44
45
  const isGuest = () => import_guest.CMicroAppGuest.isInitialized();
45
46
  const isStandAloneGuest = () => isGuest() && window.top === window.self;
46
47
  const getLogger = () => isHost() ? import_host.CMicroAppHost.getInstance().getLogger() : import_guest.CMicroAppGuest.getInstance().getLogger();
47
48
  const isProduction = (mode) => {
48
49
  if ((0, import_helpers.isCIBuild)()) return true;
49
- if (mode) return mode === "production";
50
+ if (mode) return mode === import_types2.LaunchMode.PRODUCTION;
50
51
  return true;
51
52
  };
52
53
  const getVersionedPath = (path) => {
@@ -65,7 +66,7 @@ const getMicroFrontEndAppConfig = (appInfo) => {
65
66
  throw new Error(
66
67
  `unable to locate application configuraiton for ${appInfo.id} under microFrontendApps section of app.config.json`
67
68
  );
68
- const { mode = "production" } = microFEAppConfig;
69
+ const { mode = import_types2.LaunchMode.PRODUCTION } = microFEAppConfig;
69
70
  const envConfig = isProduction(mode) ? microFEAppConfig.production : microFEAppConfig.development;
70
71
  if (microFEAppConfig.production) delete microFEAppConfig.production;
71
72
  if (microFEAppConfig.development) delete microFEAppConfig.development;
@@ -140,8 +140,8 @@ class Analytics extends import_ssf_host.ScriptingObject {
140
140
  throw new Error("parameter options is required");
141
141
  const startMark = performance.mark(name, { detail: options });
142
142
  return Promise.resolve({
143
- name: startMark.name,
144
- startTime: startMark.startTime
143
+ name: startMark?.name,
144
+ startTime: startMark?.startTime
145
145
  });
146
146
  };
147
147
  /**
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var ssf_host_exports = {};
20
+ __export(ssf_host_exports, {
21
+ getSSFHost: () => getSSFHost,
22
+ setSSFHost: () => setSSFHost
23
+ });
24
+ module.exports = __toCommonJS(ssf_host_exports);
25
+ var import_ssf_host = require("@elliemae/ssf-host");
26
+ var import_logger = require("../logger.js");
27
+ var import_config = require("../app-config/config.js");
28
+ var import_analytics = require("./scripting-objects/analytics.js");
29
+ let ssfHost = null;
30
+ const getSSFHost = () => {
31
+ if (!ssfHost) {
32
+ const logger = (0, import_logger.getLogger)();
33
+ ssfHost = new import_ssf_host.SSFHost((0, import_config.getAppConfigValue)("appId"), {
34
+ logger,
35
+ analyticsObj: new import_analytics.Analytics({ logger })
36
+ });
37
+ }
38
+ return ssfHost;
39
+ };
40
+ const setSSFHost = (host) => {
41
+ if (!ssfHost) {
42
+ ssfHost = host;
43
+ }
44
+ };
@@ -3,6 +3,10 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
6
10
  var __copyProps = (to, from, except, desc) => {
7
11
  if (from && typeof from === "object" || typeof from === "function") {
8
12
  for (let key of __getOwnPropNames(from))
@@ -13,4 +17,18 @@ var __copyProps = (to, from, except, desc) => {
13
17
  };
14
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
19
  var types_exports = {};
20
+ __export(types_exports, {
21
+ LaunchMode: () => LaunchMode,
22
+ MicroAppManager: () => MicroAppManager
23
+ });
16
24
  module.exports = __toCommonJS(types_exports);
25
+ var LaunchMode = /* @__PURE__ */ ((LaunchMode2) => {
26
+ LaunchMode2["DEVELOPMENT"] = "development";
27
+ LaunchMode2["PRODUCTION"] = "production";
28
+ return LaunchMode2;
29
+ })(LaunchMode || {});
30
+ var MicroAppManager = /* @__PURE__ */ ((MicroAppManager2) => {
31
+ MicroAppManager2["SSF"] = "ssf";
32
+ MicroAppManager2["APPSDK"] = "appsdk";
33
+ return MicroAppManager2;
34
+ })(MicroAppManager || {});
@@ -35,7 +35,9 @@ var import_jsx_runtime = require("react/jsx-runtime");
35
35
  var import_react = require("react");
36
36
  var import_styled_components = __toESM(require("styled-components"));
37
37
  var import_react_redux = require("react-redux");
38
+ var import_types = require("../utils/micro-frontend/types.js");
38
39
  var import_app_bridge = require("../utils/micro-frontend/app-bridge.js");
40
+ var import_ssf_host2 = require("../utils/micro-frontend/ssf-host.js");
39
41
  var import_actions = require("../data/wait-message/actions.js");
40
42
  var import_micro_frontend = require("../utils/micro-frontend/index.js");
41
43
  const Div = import_styled_components.default.div`
@@ -53,35 +55,67 @@ const useAppRenderer = (props) => {
53
55
  initialRoute,
54
56
  onLoadComplete,
55
57
  onUnloadComplete,
56
- containerId
58
+ containerId,
59
+ ssfAppOptions = {}
57
60
  } = props;
58
61
  const dispatch = (0, import_react_redux.useDispatch)();
62
+ const getConfig = (0, import_react.useCallback)(
63
+ () => (0, import_micro_frontend.getMicroFrontEndAppConfig)({
64
+ id
65
+ }),
66
+ [id]
67
+ );
59
68
  (0, import_react.useLayoutEffect)(() => {
60
69
  let isMounted = true;
61
70
  let appBridge = null;
71
+ let ssfHost = null;
62
72
  let unloadInProgress = Promise.resolve();
63
73
  let instanceId = null;
64
74
  (async () => {
65
75
  await unloadInProgress;
66
76
  dispatch(import_actions.waitMessage.open());
67
77
  try {
68
- appBridge = await (0, import_app_bridge.getAppBridge)();
69
- if (!appBridge)
70
- throw new Error(`Failed to load ${id}, AppBridge not initialized`);
71
- if (isMounted) {
72
- instanceId = await appBridge.openApp({
73
- id,
74
- frameOptions: { containerId },
75
- history,
76
- homeRoute,
77
- initialRoute
78
- });
79
- setTimeout(() => {
80
- try {
81
- onLoadComplete?.(instanceId);
82
- } catch (ex) {
83
- }
84
- }, 0);
78
+ const {
79
+ microappManager = import_types.MicroAppManager.APPSDK,
80
+ hostUrl,
81
+ name
82
+ } = getConfig();
83
+ if (microappManager === import_types.MicroAppManager.SSF) {
84
+ ssfHost = (0, import_ssf_host2.getSSFHost)();
85
+ if (!ssfHost)
86
+ throw new Error(`Failed to load ${id}, SSFHost not initialized`);
87
+ if (isMounted) {
88
+ const { searchParams, ...guestOptions } = ssfAppOptions;
89
+ const guest = ssfHost.loadGuest({
90
+ id,
91
+ url: hostUrl,
92
+ title: name,
93
+ targetElement: document.getElementById(containerId),
94
+ searchParams,
95
+ onLoad: onLoadComplete,
96
+ options: guestOptions
97
+ });
98
+ instanceId = guest.id;
99
+ }
100
+ } else {
101
+ appBridge = await (0, import_app_bridge.getAppBridge)();
102
+ if (!appBridge)
103
+ throw new Error(`Failed to load ${id}, AppBridge not initialized`);
104
+ if (isMounted) {
105
+ instanceId = await appBridge.openApp({
106
+ id,
107
+ frameOptions: { containerId },
108
+ history,
109
+ homeRoute,
110
+ initialRoute
111
+ });
112
+ setTimeout(() => {
113
+ try {
114
+ onLoadComplete?.(instanceId);
115
+ } catch (ex) {
116
+ }
117
+ }, 0);
118
+ }
85
119
  }
86
120
  } catch (ex) {
87
121
  (0, import_micro_frontend.getLogger)().error({
@@ -91,6 +125,8 @@ const useAppRenderer = (props) => {
91
125
  isMounted = false;
92
126
  if (appBridge && instanceId)
93
127
  unloadInProgress = appBridge.closeApp(instanceId);
128
+ if (ssfHost && instanceId)
129
+ unloadInProgress = Promise.resolve(ssfHost.unloadGuest(instanceId));
94
130
  throw ex;
95
131
  } finally {
96
132
  dispatch(import_actions.waitMessage.close());
@@ -98,19 +134,21 @@ const useAppRenderer = (props) => {
98
134
  })();
99
135
  return () => {
100
136
  isMounted = false;
101
- if (appBridge) {
137
+ if (ssfHost) {
138
+ unloadInProgress = Promise.resolve(ssfHost.unloadGuest(instanceId));
139
+ } else if (appBridge) {
102
140
  unloadInProgress = appBridge.closeApp(instanceId);
103
- unloadInProgress.then(() => {
104
- instanceId = null;
105
- setTimeout(() => {
106
- try {
107
- onUnloadComplete?.();
108
- } catch (ex) {
109
- }
110
- }, 0);
111
- }).catch(() => {
112
- });
113
141
  }
142
+ unloadInProgress.then(() => {
143
+ instanceId = null;
144
+ setTimeout(() => {
145
+ try {
146
+ onUnloadComplete?.();
147
+ } catch (ex) {
148
+ }
149
+ }, 0);
150
+ }).catch(() => {
151
+ });
114
152
  };
115
153
  }, [
116
154
  containerId,
@@ -120,7 +158,9 @@ const useAppRenderer = (props) => {
120
158
  initialRoute,
121
159
  id,
122
160
  onLoadComplete,
123
- onUnloadComplete
161
+ onUnloadComplete,
162
+ getConfig,
163
+ ssfAppOptions
124
164
  ]);
125
165
  };
126
166
  const GuestMicroApp = (0, import_react.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,11 @@
15
15
  "files": ["index.js"]
16
16
  }
17
17
  },
18
+ "ssfapp": {
19
+ "name": "SSF App",
20
+ "hostUrl": "./ssfapp",
21
+ "microappManager": "ssf"
22
+ },
18
23
  "taskapp": {
19
24
  "name": "Task",
20
25
  "hostUrl": "./task",
@@ -28,12 +28,14 @@ __export(constants_exports, {
28
28
  LOAN_SAVED_EVENT: () => LOAN_SAVED_EVENT,
29
29
  PRE_COMMIT_EVENT: () => PRE_COMMIT_EVENT,
30
30
  RELEASE_VERSION: () => RELEASE_VERSION,
31
+ SSF_APP_ID: () => SSF_APP_ID,
31
32
  TASK_APP_ID: () => TASK_APP_ID
32
33
  });
33
34
  module.exports = __toCommonJS(constants_exports);
34
35
  const LATEST_VERSION = "latest";
35
36
  const RELEASE_VERSION = "23.1.0";
36
37
  const LOAN_APP_ID = "loanapp";
38
+ const SSF_APP_ID = "ssfapp";
37
39
  const TASK_APP_ID = "taskapp";
38
40
  const FLIGHTS_APP_ID = "flights";
39
41
  const HOTELS_APP_ID = "hotels";
@@ -206,5 +206,20 @@ const serverHandlers = [
206
206
  "/loan/latest/manifest.json",
207
207
  (req, res, ctx) => res(ctx.json(import_manifest.default))
208
208
  ),
209
+ import_msw.rest.get("/ssfapp/", async (req, res, ctx) => {
210
+ const fileContent = await (0, import_promises.readFile)(
211
+ import_node_path.default.join(__dirname, "ssfapp/index.html"),
212
+ "utf-8"
213
+ );
214
+ return res(
215
+ ctx.status(200),
216
+ ctx.set("Content-Type", "text/html"),
217
+ ctx.body(fileContent)
218
+ );
219
+ }),
220
+ import_msw.rest.get("/ssfapp/latest/index.js", async (req, res, ctx) => {
221
+ const newRes = await sendJS(res, ctx, "./ssfapp/latest/index.js");
222
+ return newRes;
223
+ }),
209
224
  ...getServerHandlers()
210
225
  ];
@@ -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,16 @@
1
+ "use strict";
2
+ const appId = "ssfapp";
3
+ const output = document.getElementById("output");
4
+ output.textContent = `${appId} starting`;
5
+ window.addEventListener("beforeunload", () => {
6
+ if (output) {
7
+ output.textContent += `
8
+ ${appId} unloading`;
9
+ }
10
+ });
11
+ document.addEventListener("load", () => {
12
+ if (output) {
13
+ output.textContent += `
14
+ ${appId} loaded`;
15
+ }
16
+ });
@@ -0,0 +1,3 @@
1
+ {
2
+ "index.js": "latest/index.js"
3
+ }
@@ -13,6 +13,7 @@ import { updateBAEventParameters } from "./scripting-objects/web-analytics.js";
13
13
  import { setLogRocket } from "./scripting-objects/logrocket.js";
14
14
  import { getAppBridge } from "./app-bridge.js";
15
15
  import { abortPromise } from "../helpers.js";
16
+ import { getSSFHost, setSSFHost } from "./ssf-host.js";
16
17
  const isCrossDomain = () => {
17
18
  try {
18
19
  window.parent.document;
@@ -44,6 +45,10 @@ class CMicroAppGuest {
44
45
  * communication method used between microapps
45
46
  */
46
47
  #communicationMethod;
48
+ /**
49
+ * reference to SSFHost instance
50
+ */
51
+ #ssfHostRef;
47
52
  /**
48
53
  * AppBridge instance
49
54
  */
@@ -71,6 +76,8 @@ class CMicroAppGuest {
71
76
  setLogger(this.logger);
72
77
  this.#logRocket = params?.logRocket ?? window.emui?.logRocket;
73
78
  setLogRocket(this.#logRocket);
79
+ if (params?.ssfHostRef) setSSFHost(params.ssfHostRef);
80
+ this.#ssfHostRef = getSSFHost();
74
81
  this.onInit = params?.onInit;
75
82
  this.onMount = params?.onMount;
76
83
  this.onUnmount = params?.onUnmount;
@@ -210,18 +217,20 @@ class CMicroAppGuest {
210
217
  }
211
218
  async findHost() {
212
219
  let host = null;
213
- if (!isCrossDomain()) {
214
- host = window.parent?.emui?.MicroAppHost ?? null;
215
- }
216
- if (!host) {
217
- host = new SSFGuest({ appLogger: this.logger });
218
- if (await abortPromise({
219
- promise: host.connect(),
220
- delay: 1e3,
221
- retValue: false
222
- })) {
223
- host = null;
224
- } else this.#communicationMethod = "ssf" /* SSF */;
220
+ if (window.parent !== window) {
221
+ if (!isCrossDomain()) {
222
+ host = window.parent?.emui?.MicroAppHost ?? null;
223
+ }
224
+ if (!host) {
225
+ host = new SSFGuest({ appLogger: this.logger });
226
+ if (await abortPromise({
227
+ promise: host.connect(),
228
+ delay: 1e3,
229
+ retValue: false
230
+ })) {
231
+ host = null;
232
+ } else this.#communicationMethod = "ssf" /* SSF */;
233
+ }
225
234
  }
226
235
  return host;
227
236
  }
@@ -282,15 +291,22 @@ class CMicroAppGuest {
282
291
  if (this.#appBridge) {
283
292
  this.#appBridge.addScriptingObject(so, params);
284
293
  }
294
+ this.#ssfHostRef.addScriptingObject(so, params);
285
295
  }
286
296
  /**
287
- * dispatch event to child microapp
288
- * @param {DispatchEventParams<EventId, Params>} params - event parameters
297
+ * Dispatches an event to the child microapp.
298
+ * @param {DispatchEventParam<EventId, Params, Options>} params - Event parameters.
299
+ * @returns {Promise<any[]>} A promise that resolves with the combined results of dispatched events.
289
300
  */
290
301
  async dispatchEvent(params) {
291
- if (this.#appBridge) {
292
- await this.#appBridge.dispatchEvent(params);
302
+ const [appBridgeResult, ssfResult] = await Promise.all([
303
+ this.#appBridge ? this.#appBridge.dispatchEvent(params) : Promise.resolve(null),
304
+ this.#ssfHostRef.dispatchEvent(params)
305
+ ]);
306
+ if (Array.isArray(appBridgeResult) && Array.isArray(ssfResult)) {
307
+ return appBridgeResult.concat(ssfResult);
293
308
  }
309
+ return Promise.resolve();
294
310
  }
295
311
  /**
296
312
  * removes scripting object from child microapp use
@@ -300,6 +316,7 @@ class CMicroAppGuest {
300
316
  if (this.#appBridge) {
301
317
  this.#appBridge.removeScriptingObject(objectId);
302
318
  }
319
+ this.#ssfHostRef.removeScriptingObject(objectId);
303
320
  }
304
321
  }
305
322
  export {