@elliemae/pui-app-sdk 5.40.5 → 5.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/demo/{1080.92f6b67a.iframe.bundle.js → 1080.519b1144.iframe.bundle.js} +1 -1
  2. package/demo/1080.519b1144.iframe.bundle.js.br +0 -0
  3. package/demo/{1080.92f6b67a.iframe.bundle.js.gz → 1080.519b1144.iframe.bundle.js.gz} +0 -0
  4. package/demo/docs/{1080.92f6b67a.iframe.bundle.js → 1080.519b1144.iframe.bundle.js} +1 -1
  5. package/demo/docs/1080.519b1144.iframe.bundle.js.br +0 -0
  6. package/demo/docs/{1080.92f6b67a.iframe.bundle.js.gz → 1080.519b1144.iframe.bundle.js.gz} +0 -0
  7. package/demo/docs/iframe.html +1 -1
  8. package/demo/docs/index.html +1 -1
  9. package/demo/docs/main.1bf7b965.iframe.bundle.js +5 -0
  10. package/demo/docs/main.1bf7b965.iframe.bundle.js.br +0 -0
  11. package/demo/docs/main.1bf7b965.iframe.bundle.js.gz +0 -0
  12. package/demo/docs/{main.cfd2e2085f77fe383f8d.manager.bundle.js → main.ba76a04bac90176acd00.manager.bundle.js} +1 -1
  13. package/demo/docs/{main.cfd2e2085f77fe383f8d.manager.bundle.js.br → main.ba76a04bac90176acd00.manager.bundle.js.br} +0 -0
  14. package/demo/docs/{main.cfd2e2085f77fe383f8d.manager.bundle.js.gz → main.ba76a04bac90176acd00.manager.bundle.js.gz} +0 -0
  15. package/demo/docs/project.json +1 -1
  16. package/demo/iframe.html +1 -1
  17. package/demo/index.html +1 -1
  18. package/demo/main.1bf7b965.iframe.bundle.js +5 -0
  19. package/demo/main.1bf7b965.iframe.bundle.js.br +0 -0
  20. package/demo/main.1bf7b965.iframe.bundle.js.gz +0 -0
  21. package/demo/{main.cfd2e2085f77fe383f8d.manager.bundle.js → main.ba76a04bac90176acd00.manager.bundle.js} +1 -1
  22. package/demo/{main.cfd2e2085f77fe383f8d.manager.bundle.js.br → main.ba76a04bac90176acd00.manager.bundle.js.br} +0 -0
  23. package/demo/{main.cfd2e2085f77fe383f8d.manager.bundle.js.gz → main.ba76a04bac90176acd00.manager.bundle.js.gz} +0 -0
  24. package/demo/project.json +1 -1
  25. package/dist/cjs/utils/micro-frontend/guest.js +48 -14
  26. package/dist/cjs/view/tests/scriptingObjects/loan.js +4 -0
  27. package/dist/esm/utils/micro-frontend/guest.js +48 -14
  28. package/dist/esm/view/tests/scriptingObjects/loan.js +4 -0
  29. package/dist/types/lib/utils/micro-frontend/guest.d.ts +6 -0
  30. package/dist/types/lib/view/tests/scriptingObjects/loan.d.ts +1 -0
  31. package/dist/types/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +1 -1
  33. package/demo/1080.92f6b67a.iframe.bundle.js.br +0 -0
  34. package/demo/docs/1080.92f6b67a.iframe.bundle.js.br +0 -0
  35. package/demo/docs/main.f92b110f.iframe.bundle.js +0 -5
  36. package/demo/docs/main.f92b110f.iframe.bundle.js.br +0 -0
  37. package/demo/docs/main.f92b110f.iframe.bundle.js.gz +0 -0
  38. package/demo/main.f92b110f.iframe.bundle.js +0 -5
  39. package/demo/main.f92b110f.iframe.bundle.js.br +0 -0
  40. package/demo/main.f92b110f.iframe.bundle.js.gz +0 -0
package/demo/project.json CHANGED
@@ -1 +1 @@
1
- {"generatedAt":1780087695087,"builder":{"name":"webpack5"},"hasCustomBabel":false,"hasCustomWebpack":true,"hasStaticDirs":false,"hasStorybookEslint":false,"refCount":0,"packageManager":{"type":"pnpm","version":"8.15.9"},"typescriptOptions":{"check":false,"checkOptions":{},"reactDocgen":false,"reactDocgenTypescriptOptions":{"shouldExtractLiteralValuesFromEnum":true,"compilerOptions":{"allowSyntheticDefaultImports":false,"esModuleInterop":false}}},"features":{"fastRefresh":true,"storyStoreV7":true},"language":"javascript","storybookPackages":{},"framework":{"options":{"fastRefresh":true,"strictMode":true,"legacyRootApi":true}},"addons":{"@storybook/addon-docs":{"options":{"sourceLoaderOptions":{"injectStoryParameters":false}},"version":"6.5.16"},"@storybook/addon-essentials":{"options":{"docs":false},"version":"6.5.16"},"@storybook/addon-storysource":{"version":"6.5.16"},"@storybook/addon-links":{"version":"6.5.16"},"@storybook/addon-events":{"version":"6.2.9"},"@storybook/addon-interactions":{"version":"6.5.16"},"@storybook/addon-a11y":{"version":"6.5.16"},"storybook-addon-turbo-build":{"options":{"optimizationLevel":2,"esbuildMinifyOptions":{"target":"es2022"}},"version":"1.1.0"}}}
1
+ {"generatedAt":1782148675244,"builder":{"name":"webpack5"},"hasCustomBabel":false,"hasCustomWebpack":true,"hasStaticDirs":false,"hasStorybookEslint":false,"refCount":0,"packageManager":{"type":"pnpm","version":"8.15.9"},"typescriptOptions":{"check":false,"checkOptions":{},"reactDocgen":false,"reactDocgenTypescriptOptions":{"shouldExtractLiteralValuesFromEnum":true,"compilerOptions":{"allowSyntheticDefaultImports":false,"esModuleInterop":false}}},"features":{"fastRefresh":true,"storyStoreV7":true},"language":"javascript","storybookPackages":{},"framework":{"options":{"fastRefresh":true,"strictMode":true,"legacyRootApi":true}},"addons":{"@storybook/addon-docs":{"options":{"sourceLoaderOptions":{"injectStoryParameters":false}},"version":"6.5.16"},"@storybook/addon-essentials":{"options":{"docs":false},"version":"6.5.16"},"@storybook/addon-storysource":{"version":"6.5.16"},"@storybook/addon-links":{"version":"6.5.16"},"@storybook/addon-events":{"version":"6.2.9"},"@storybook/addon-interactions":{"version":"6.5.16"},"@storybook/addon-a11y":{"version":"6.5.16"},"storybook-addon-turbo-build":{"options":{"optimizationLevel":2,"esbuildMinifyOptions":{"target":"es2022"}},"version":"1.1.0"}}}
@@ -83,6 +83,7 @@ class CMicroAppGuest {
83
83
  */
84
84
  #useV2Guest;
85
85
  #selfInitialize;
86
+ #embeddedWithoutHost;
86
87
  /**
87
88
  * AppBridge instance
88
89
  */
@@ -97,7 +98,7 @@ class CMicroAppGuest {
97
98
  onMount;
98
99
  onUnmount;
99
100
  onGetRef;
100
- // eslint-disable-next-line max-statements
101
+ // eslint-disable-next-line max-statements, complexity
101
102
  constructor(params) {
102
103
  window.emui.uuid = window.emui.uuid || (0, import_uuid.v4)();
103
104
  this.appId = window.emui?.appId || (0, import_config.getAppConfigValue)("appId");
@@ -118,10 +119,16 @@ class CMicroAppGuest {
118
119
  this.#ssfHostRef = (0, import_ssf_host2.getSSFHost)();
119
120
  this.#useV2Guest = params?.useV2Guest !== false;
120
121
  this.#selfInitialize = params?.selfInitialize ?? false;
122
+ this.#embeddedWithoutHost = params?.embeddedWithoutHost ?? false;
121
123
  this.onInit = params?.onInit;
122
124
  this.onMount = params?.onMount;
123
125
  this.onUnmount = params?.onUnmount;
124
126
  this.onGetRef = params?.onGetRef;
127
+ if (this.#embeddedWithoutHost && !this.#selfInitialize) {
128
+ this.logger.warn(
129
+ "embeddedWithoutHost requires selfInitialize: true \u2014 the flag only applies to initialize()"
130
+ );
131
+ }
125
132
  this.getHost = this.getHost.bind(this);
126
133
  this.getLogger = this.getLogger.bind(this);
127
134
  this.getProps = this.getProps.bind(this);
@@ -317,6 +324,10 @@ class CMicroAppGuest {
317
324
  if (window.emui?.__host) {
318
325
  return window.emui.__host;
319
326
  }
327
+ if (!isCrossDomain()) {
328
+ const legacyHost = window.parent?.emui?.MicroAppHost ?? null;
329
+ if (legacyHost) return legacyHost;
330
+ }
320
331
  if (this.#useV2Guest) {
321
332
  const ssfGuest = new import_ssf_guest.SSFGuest({ appLogger: this.logger });
322
333
  const failed = await (0, import_helpers.abortPromise)({
@@ -370,6 +381,33 @@ class CMicroAppGuest {
370
381
  const route = typeof params.initialRoute === "string" ? params.initialRoute : params.initialRoute.pathname;
371
382
  if (route) this.props.history.push(route);
372
383
  }
384
+ async #loadConfigAndBridge() {
385
+ await (0, import_app_config.loadAppConfig)();
386
+ await this.#initAppBridge();
387
+ }
388
+ #trackAnalyticsAndOnInit() {
389
+ const instanceId = this.getSessionStorageItem("instanceId") || "";
390
+ const userId = this.getSessionStorageItem("userId") || "";
391
+ (0, import_pui_analytics_so.updateBAEventParameters)({ appId: this.appId, instanceId, userId });
392
+ if (this.onInit) this.onInit(this.props);
393
+ }
394
+ #completeWithoutHost(mode) {
395
+ if (mode === "standalone") {
396
+ this.logger.info("Running in standalone mode \u2014 skipping host discovery");
397
+ this.#exposeGetHost();
398
+ this.#resolveHistory();
399
+ } else if (mode === "embeddedWithoutHost") {
400
+ this.logger.info("embeddedWithoutHost enabled \u2014 skipping host discovery");
401
+ this.#exposeGetHost();
402
+ } else {
403
+ this.logger.warn(
404
+ "Unable to discover host. Proceeding with app.config.json values. Host-provided parameters (history, theme, initialRoute) will not be available."
405
+ );
406
+ this.#exposeGetHost();
407
+ }
408
+ this.#trackAnalyticsAndOnInit();
409
+ return { moduleId: this.appId };
410
+ }
373
411
  /**
374
412
  * Guest-initiated lifecycle: discovers the host and applies module
375
413
  * parameters if available. After this resolves the guest is ready to render.
@@ -385,20 +423,19 @@ class CMicroAppGuest {
385
423
  (0, import_webpack_public_path.syncWebpackPublicPathFromAssetPath)();
386
424
  const isStandalone = window.top === window.self && !window.opener;
387
425
  if (isStandalone) {
388
- await (0, import_app_config.loadAppConfig)();
389
- await this.#initAppBridge();
390
- this.logger.info("Running in standalone mode \u2014 skipping host discovery");
391
- if (this.onInit) this.onInit(this.props);
392
- return { moduleId: this.appId };
426
+ await this.#loadConfigAndBridge();
427
+ return this.#completeWithoutHost("standalone");
428
+ }
429
+ if (this.#embeddedWithoutHost) {
430
+ await this.#loadConfigAndBridge();
431
+ return this.#completeWithoutHost("embeddedWithoutHost");
393
432
  }
394
433
  const [host] = await Promise.all([
395
434
  this.#discoverHost(),
396
- (0, import_app_config.loadAppConfig)().then(() => this.#initAppBridge())
435
+ this.#loadConfigAndBridge()
397
436
  ]);
398
437
  if (!host) {
399
- throw new Error(
400
- "Unable to discover host. Ensure the host uses an updated pui-app-sdk and pui-microfe, or use the host-initiated model (onInit/onMount)."
401
- );
438
+ return this.#completeWithoutHost("discoveryFallback");
402
439
  }
403
440
  this.props.host = host;
404
441
  this.#exposeGetHost();
@@ -418,10 +455,7 @@ class CMicroAppGuest {
418
455
  `Failed to retrieve module parameters for "${this.appId}". Proceeding without host-provided parameters.`
419
456
  );
420
457
  }
421
- const instanceId = this.getSessionStorageItem("instanceId") || "";
422
- const userId = this.getSessionStorageItem("userId") || "";
423
- (0, import_pui_analytics_so.updateBAEventParameters)({ appId: this.appId, instanceId, userId });
424
- if (this.onInit) this.onInit(this.props);
458
+ this.#trackAnalyticsAndOnInit();
425
459
  return params;
426
460
  }
427
461
  async init(options) {
@@ -61,6 +61,10 @@ class Loan extends import_pui_app_bridge.ScriptingObject {
61
61
  name: "editmodechange",
62
62
  objectId: "loan"
63
63
  });
64
+ ExternallyModified = new import_pui_app_bridge.Event({
65
+ name: "externallyModified",
66
+ objectId: "loan"
67
+ });
64
68
  FieldChangeSync = new import_pui_app_bridge.Event({
65
69
  name: "fieldChangeSync",
66
70
  objectId: "loan"
@@ -50,6 +50,7 @@ class CMicroAppGuest {
50
50
  */
51
51
  #useV2Guest;
52
52
  #selfInitialize;
53
+ #embeddedWithoutHost;
53
54
  /**
54
55
  * AppBridge instance
55
56
  */
@@ -64,7 +65,7 @@ class CMicroAppGuest {
64
65
  onMount;
65
66
  onUnmount;
66
67
  onGetRef;
67
- // eslint-disable-next-line max-statements
68
+ // eslint-disable-next-line max-statements, complexity
68
69
  constructor(params) {
69
70
  window.emui.uuid = window.emui.uuid || uuidv4();
70
71
  this.appId = window.emui?.appId || getAppConfigValue("appId");
@@ -85,10 +86,16 @@ class CMicroAppGuest {
85
86
  this.#ssfHostRef = getSSFHost();
86
87
  this.#useV2Guest = params?.useV2Guest !== false;
87
88
  this.#selfInitialize = params?.selfInitialize ?? false;
89
+ this.#embeddedWithoutHost = params?.embeddedWithoutHost ?? false;
88
90
  this.onInit = params?.onInit;
89
91
  this.onMount = params?.onMount;
90
92
  this.onUnmount = params?.onUnmount;
91
93
  this.onGetRef = params?.onGetRef;
94
+ if (this.#embeddedWithoutHost && !this.#selfInitialize) {
95
+ this.logger.warn(
96
+ "embeddedWithoutHost requires selfInitialize: true \u2014 the flag only applies to initialize()"
97
+ );
98
+ }
92
99
  this.getHost = this.getHost.bind(this);
93
100
  this.getLogger = this.getLogger.bind(this);
94
101
  this.getProps = this.getProps.bind(this);
@@ -284,6 +291,10 @@ class CMicroAppGuest {
284
291
  if (window.emui?.__host) {
285
292
  return window.emui.__host;
286
293
  }
294
+ if (!isCrossDomain()) {
295
+ const legacyHost = window.parent?.emui?.MicroAppHost ?? null;
296
+ if (legacyHost) return legacyHost;
297
+ }
287
298
  if (this.#useV2Guest) {
288
299
  const ssfGuest = new SSFGuest({ appLogger: this.logger });
289
300
  const failed = await abortPromise({
@@ -337,6 +348,33 @@ class CMicroAppGuest {
337
348
  const route = typeof params.initialRoute === "string" ? params.initialRoute : params.initialRoute.pathname;
338
349
  if (route) this.props.history.push(route);
339
350
  }
351
+ async #loadConfigAndBridge() {
352
+ await loadAppConfig();
353
+ await this.#initAppBridge();
354
+ }
355
+ #trackAnalyticsAndOnInit() {
356
+ const instanceId = this.getSessionStorageItem("instanceId") || "";
357
+ const userId = this.getSessionStorageItem("userId") || "";
358
+ updateBAEventParameters({ appId: this.appId, instanceId, userId });
359
+ if (this.onInit) this.onInit(this.props);
360
+ }
361
+ #completeWithoutHost(mode) {
362
+ if (mode === "standalone") {
363
+ this.logger.info("Running in standalone mode \u2014 skipping host discovery");
364
+ this.#exposeGetHost();
365
+ this.#resolveHistory();
366
+ } else if (mode === "embeddedWithoutHost") {
367
+ this.logger.info("embeddedWithoutHost enabled \u2014 skipping host discovery");
368
+ this.#exposeGetHost();
369
+ } else {
370
+ this.logger.warn(
371
+ "Unable to discover host. Proceeding with app.config.json values. Host-provided parameters (history, theme, initialRoute) will not be available."
372
+ );
373
+ this.#exposeGetHost();
374
+ }
375
+ this.#trackAnalyticsAndOnInit();
376
+ return { moduleId: this.appId };
377
+ }
340
378
  /**
341
379
  * Guest-initiated lifecycle: discovers the host and applies module
342
380
  * parameters if available. After this resolves the guest is ready to render.
@@ -352,20 +390,19 @@ class CMicroAppGuest {
352
390
  syncWebpackPublicPathFromAssetPath();
353
391
  const isStandalone = window.top === window.self && !window.opener;
354
392
  if (isStandalone) {
355
- await loadAppConfig();
356
- await this.#initAppBridge();
357
- this.logger.info("Running in standalone mode \u2014 skipping host discovery");
358
- if (this.onInit) this.onInit(this.props);
359
- return { moduleId: this.appId };
393
+ await this.#loadConfigAndBridge();
394
+ return this.#completeWithoutHost("standalone");
395
+ }
396
+ if (this.#embeddedWithoutHost) {
397
+ await this.#loadConfigAndBridge();
398
+ return this.#completeWithoutHost("embeddedWithoutHost");
360
399
  }
361
400
  const [host] = await Promise.all([
362
401
  this.#discoverHost(),
363
- loadAppConfig().then(() => this.#initAppBridge())
402
+ this.#loadConfigAndBridge()
364
403
  ]);
365
404
  if (!host) {
366
- throw new Error(
367
- "Unable to discover host. Ensure the host uses an updated pui-app-sdk and pui-microfe, or use the host-initiated model (onInit/onMount)."
368
- );
405
+ return this.#completeWithoutHost("discoveryFallback");
369
406
  }
370
407
  this.props.host = host;
371
408
  this.#exposeGetHost();
@@ -385,10 +422,7 @@ class CMicroAppGuest {
385
422
  `Failed to retrieve module parameters for "${this.appId}". Proceeding without host-provided parameters.`
386
423
  );
387
424
  }
388
- const instanceId = this.getSessionStorageItem("instanceId") || "";
389
- const userId = this.getSessionStorageItem("userId") || "";
390
- updateBAEventParameters({ appId: this.appId, instanceId, userId });
391
- if (this.onInit) this.onInit(this.props);
425
+ this.#trackAnalyticsAndOnInit();
392
426
  return params;
393
427
  }
394
428
  async init(options) {
@@ -38,6 +38,10 @@ class Loan extends ScriptingObject {
38
38
  name: "editmodechange",
39
39
  objectId: "loan"
40
40
  });
41
+ ExternallyModified = new Event({
42
+ name: "externallyModified",
43
+ objectId: "loan"
44
+ });
41
45
  FieldChangeSync = new Event({
42
46
  name: "fieldChangeSync",
43
47
  objectId: "loan"
@@ -40,6 +40,12 @@ interface ConstructorParams {
40
40
  * the bridge will not call these methods.
41
41
  */
42
42
  selfInitialize?: boolean;
43
+ /**
44
+ * When true, the guest is embedded in an iframe but not hosted by PUI app
45
+ * bridge or SSF. Skips host discovery and initializes from app.config.json
46
+ * with in-memory history. Ignored when running standalone (top-level window).
47
+ */
48
+ embeddedWithoutHost?: boolean;
43
49
  }
44
50
  /**
45
51
  * Micro-frontend guest application class (singleton).
@@ -8,6 +8,7 @@ export declare class Loan extends ScriptingObject implements ILoan {
8
8
  readonly Change: Event<Events>;
9
9
  readonly Committed: Event<Events>;
10
10
  readonly EditModeChange: Event<Events>;
11
+ readonly ExternallyModified: Event<Events>;
11
12
  readonly FieldChangeSync: Event<Events>;
12
13
  readonly MilestoneCompleted: Event<Events>;
13
14
  readonly Open: Event<Events>;