@monterosa/sdk-launcher-kit 2.0.0-rc.1 → 2.0.0-rc.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.
@@ -1,6 +1,5 @@
1
1
  import { Logger, Sdk, getSdk, LogLevel, configure } from '@monterosa/sdk-core';
2
- import { createError, getGlobal, Emitter, getErrorMessage, subscribe, delay, throttle } from '@monterosa/sdk-util';
3
- import { v4 } from 'uuid';
2
+ import { createError, getGlobal, Emitter, getErrorMessage, generateUUID, subscribe, delay, throttle } from '@monterosa/sdk-util';
4
3
  import { fetchListings } from '@monterosa/sdk-interact-interop';
5
4
 
6
5
  /**
@@ -77,6 +76,10 @@ var Action;
77
76
  * Notifies child Experience about the request to load more data
78
77
  */
79
78
  Action["OnMoreDataRequested"] = "onMoreDataRequested";
79
+ /**
80
+ * Notifies about a share request
81
+ */
82
+ Action["OnShare"] = "onShare";
80
83
  })(Action || (Action = {}));
81
84
  /**
82
85
  * @internal
@@ -106,13 +109,13 @@ var QueryParam;
106
109
  */
107
110
  QueryParam["Host"] = "h";
108
111
  /**
109
- * Represents the Project Id of the application. This parameter is added by
112
+ * Represents the Project ID of the application. This parameter is added by
110
113
  * Studio and the embed URL already contains it.
111
114
  */
112
115
  QueryParam["Project"] = "p";
113
116
  /**
114
- * Represents the Event Id of the application. This parameter is added to the
115
- * experience URL when the eventId is provided in the experience config.
117
+ * Represents the Event ID of the application. This parameter is added to the
118
+ * Experience URL when the eventId is provided in the Experience config.
116
119
  */
117
120
  QueryParam["Event"] = "e";
118
121
  /**
@@ -200,8 +203,9 @@ const Config = {
200
203
  requestTimeout: 20000,
201
204
  };
202
205
  /**
203
- * Sets a new timeout value for requests (default is 20_000 mseconds).
206
+ * Sets a new timeout value for requests (default is 20,000 ms).
204
207
  *
208
+ * @remarks
205
209
  * This function updates the request timeout in the application's configuration.
206
210
  * It ensures that the new timeout value is a positive number, and throws
207
211
  * an error if the value is non-positive.
@@ -332,7 +336,7 @@ const globals = getGlobal();
332
336
  * @internal
333
337
  */
334
338
  class BridgeImpl extends Emitter {
335
- constructor(id = v4()) {
339
+ constructor(id = generateUUID()) {
336
340
  super();
337
341
  this.id = id;
338
342
  this.recipientInitialised = false;
@@ -372,7 +376,7 @@ class BridgeImpl extends Emitter {
372
376
  }
373
377
  createMessage(action, payload, sourceName, respondingTo = null) {
374
378
  return {
375
- id: v4(),
379
+ id: generateUUID(),
376
380
  respondingTo,
377
381
  action,
378
382
  sourceName,
@@ -520,9 +524,7 @@ function sendSdkMessage(bridged, action, payload = {}) {
520
524
  return bridged.bridge.send(action, payload, Source.Sdk);
521
525
  }
522
526
  /**
523
- * This function allows to send a simple message with action name and payload to
524
- * a recipient which can be either parent application (from Experience to parent
525
- * application) or child Experience (from parent page to Experience).
527
+ * Sends a message with an action name and payload to a parent application or child Experience.
526
528
  *
527
529
  * @remarks
528
530
  * Usage example in parent application:
@@ -575,14 +577,13 @@ function sendSdkRequest(bridged, action, payload = {}, timeout = Config.requestT
575
577
  return bridged.bridge.request(action, payload, timeout, Source.Sdk);
576
578
  }
577
579
  /**
578
- * This function allows to send a request with action name and payload to
579
- * a recipient which can be either parent application (from Experience to parent
580
- * application) or child Experience (from parent page to Experience). It is similar
581
- * to {@link sendMessage} with only one difference is that it returns a Promise which
582
- * resolves if the recipient response with {@link respondToMessage}. Otherwise it
583
- * will rejects after a certain timeout.
580
+ * Sends a request and returns a Promise that resolves when the recipient responds.
584
581
  *
585
582
  * @remarks
583
+ * Similar to {@link sendMessage} but returns a Promise which
584
+ * resolves if the recipient responds with {@link respondToMessage}. Otherwise it
585
+ * rejects after a certain timeout.
586
+ *
586
587
  * Usage example in parent application:
587
588
  *
588
589
  * @example
@@ -663,6 +664,8 @@ function onSdkMessage(bridged, callback) {
663
664
  return onMessageFunc(bridged, Source.Sdk, callback);
664
665
  }
665
666
  /**
667
+ * @internal
668
+ *
666
669
  * Adds an observer for when user message is received
667
670
  *
668
671
  * @param bridged - Instance of either {@link ParentApplication} or {@link Experience}
@@ -689,7 +692,7 @@ class ExperienceImpl {
689
692
  constructor(sdk, config) {
690
693
  this.sdk = sdk;
691
694
  this._parameters = {};
692
- this.id = v4();
695
+ this.id = generateUUID();
693
696
  this.state = 'unmounted';
694
697
  this.customElement = null;
695
698
  this._config = config;
@@ -1061,7 +1064,7 @@ function unstashStyles(element) {
1061
1064
  element.removeAttribute('data-stash');
1062
1065
  }
1063
1066
 
1064
- var version = "2.0.0-rc.1";
1067
+ var version = "2.0.0-rc.2";
1065
1068
 
1066
1069
  /**
1067
1070
  * @license
@@ -1190,10 +1193,12 @@ async function experienceReady(experience) {
1190
1193
  return eitherTimeoutOrFullyLoaded;
1191
1194
  }
1192
1195
  /**
1193
- * Embeds web Experience app into iframe. There is only one app can be
1194
- * associated with Experience and it is configured in
1195
- * Monterosa / Interaction Cloud. Please refer the developer guide to get
1196
- * more information on what is app and how to configure it:
1196
+ * Embeds a web Experience app into an iframe.
1197
+ *
1198
+ * @remarks
1199
+ * There is only one app that can be associated with an Experience and it is
1200
+ * configured in Monterosa / Interaction Cloud. Please refer to the developer
1201
+ * guide for more information:
1197
1202
  * {@link https://products.monterosa.co/mic/developer-guides/whats-an-app}
1198
1203
  *
1199
1204
  * @example
@@ -1202,8 +1207,8 @@ async function experienceReady(experience) {
1202
1207
  *
1203
1208
  * embed(experience, 'container-id');
1204
1209
  * ```
1205
- * @param {Experience} - An instance of Experience
1206
- * @param {HTMLElement | string} containerOrId - HTML element instance or
1210
+ * @param experience - An instance of Experience
1211
+ * @param containerOrId - HTML element instance or
1207
1212
  * element id where iframe is embedded into.
1208
1213
  *
1209
1214
  * @public
@@ -1288,8 +1293,8 @@ async function embed(experience, containerOrId) {
1288
1293
  function unembed(experience) {
1289
1294
  const integration = getIntegration(experience);
1290
1295
  if (!integration) {
1291
- throw new Error('This experience is not currently embedded. ' +
1292
- 'Please ensure the experience is embedded before calling unembed().');
1296
+ throw new Error('This Experience is not currently embedded. ' +
1297
+ 'Please ensure the Experience is embedded before calling unembed().');
1293
1298
  }
1294
1299
  const { container } = integration;
1295
1300
  integration.controller.abort();
@@ -1327,8 +1332,8 @@ function unmount(containerOrId) {
1327
1332
  }
1328
1333
  const integration = getIntegration(container);
1329
1334
  if (!integration) {
1330
- throw new Error(`No experience found embedded in container "${containerOrId}". ` +
1331
- 'Please ensure the experience is embedded before calling unmount().');
1335
+ throw new Error(`No Experience found embedded in container "${containerOrId}". ` +
1336
+ 'Please ensure the Experience is embedded before calling unmount().');
1332
1337
  }
1333
1338
  integration.controller.abort();
1334
1339
  while (container.lastElementChild) {
@@ -1484,8 +1489,8 @@ if (!customElements.get(ELEMENT_NAME)) {
1484
1489
  *
1485
1490
  * More details on the license can be found at https://www.monterosa.co/sdk/license
1486
1491
  */
1487
- const unsubs = new Map();
1488
- function handleExperienceEmbedded(experience) {
1492
+ const unsubs$1 = new Map();
1493
+ function handleExperienceEmbedded$1(experience) {
1489
1494
  if (!experience.config.autoresizesHeight) {
1490
1495
  return;
1491
1496
  }
@@ -1504,21 +1509,21 @@ function handleExperienceEmbedded(experience) {
1504
1509
  container.style.height = `${payload.height}px`;
1505
1510
  }
1506
1511
  });
1507
- unsubs.set(experience.id, unsub);
1512
+ unsubs$1.set(experience.id, unsub);
1508
1513
  }
1509
- function handleExperienceUnmounted(experience) {
1510
- const unsub = unsubs.get(experience.id);
1514
+ function handleExperienceUnmounted$1(experience) {
1515
+ const unsub = unsubs$1.get(experience.id);
1511
1516
  if (unsub) {
1512
1517
  unsub();
1513
- unsubs.delete(experience.id);
1518
+ unsubs$1.delete(experience.id);
1514
1519
  }
1515
1520
  }
1516
1521
  onStateChanged((experience, state) => {
1517
1522
  if (state === 'mounted') {
1518
- handleExperienceEmbedded(experience);
1523
+ handleExperienceEmbedded$1(experience);
1519
1524
  }
1520
1525
  else if (state === 'unmounted') {
1521
- handleExperienceUnmounted(experience);
1526
+ handleExperienceUnmounted$1(experience);
1522
1527
  }
1523
1528
  });
1524
1529
 
@@ -1584,12 +1589,13 @@ function getUrlParam(param) {
1584
1589
  return urlParams.get(param);
1585
1590
  }
1586
1591
  /**
1592
+ * Returns whether the Experience should hide its header and footer.
1593
+ *
1594
+ * @remarks
1587
1595
  * The SDK on the parent application will by default request a child
1588
1596
  * Experience to hide its header and footer by setting a query parameter called
1589
1597
  * `micHideHeaderAndFooter` to `1`.
1590
1598
  *
1591
- * This function will return true if that is the case, and false otherwise.
1592
- *
1593
1599
  * When true, the developer of a child Experience is expected to hide it's headers
1594
1600
  * and footers as the parent application is actively providing them.
1595
1601
  *
@@ -1636,6 +1642,7 @@ function sendInitialised() {
1636
1642
  * Notifies the parent application that the Experience UI is fully loaded
1637
1643
  * and ready to be displayed. This triggers the `ready` lifecycle state.
1638
1644
  *
1645
+ * @remarks
1639
1646
  * Call this method when your UI has completed loading and you are ready to
1640
1647
  * display data to the user. This can be when your network calls have successfully
1641
1648
  * requested data and you have updated the DOM, or when an error has occurred and
@@ -1729,10 +1736,10 @@ const sendExperienceSizeThrottled = throttle((width, height) => {
1729
1736
  trailing: true,
1730
1737
  });
1731
1738
  /**
1732
- * Sends the experience size to the parent application.
1739
+ * Sends the Experience size to the parent page.
1733
1740
  *
1734
- * @param width - The width of the experience.
1735
- * @param height - The height of the experience.
1741
+ * @param width - The width of the Experience.
1742
+ * @param height - The height of the Experience.
1736
1743
  */
1737
1744
  function sendExperienceSize(width, height) {
1738
1745
  sendExperienceSizeThrottled(width, height);
@@ -1755,5 +1762,134 @@ function reportExperienceSizeChanges(element) {
1755
1762
  return () => observer.unobserve(element);
1756
1763
  }
1757
1764
 
1758
- export { Action, VERSION$1 as BRIDGE_VERSION, BridgeError, BridgeImpl, ExperienceImpl, ParentApplicationImpl, QueryParam, Source, VERSION, embed, enableLogging, getBridge, getExperience, getParentApplication, getParentBridge, isAutoresizesHeight, isInsideIframe, onMessage, onMoreDataRequested, onReady, onSdkMessage, onStateChanged, reportExperienceSizeChanges, requestMoreData, respondToMessage, respondToSdkMessage, sendExperienceSize, sendExperienceSizeThrottled, sendFinishedLoadingUI, sendInitialised, sendMessage, sendReady, sendRequest, sendSdkMessage, sendSdkRequest, setRequestTimeout, shouldHideHeaderAndFooter, stateEmitter, unembed, unmount, updateExperienceState };
1759
- //# sourceMappingURL=index.esm.js.map
1765
+ /**
1766
+ * @license
1767
+ * share.ts
1768
+ * launcher-kit
1769
+ *
1770
+ * Copyright © 2026 Monterosa Productions Limited. All rights reserved.
1771
+ *
1772
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1773
+ */
1774
+ /**
1775
+ * Share requests block on the native share tray which waits for user
1776
+ * interaction (composing a message, picking a target app, etc.). The default
1777
+ * bridge timeout of 20 seconds is too short for this. 5 minutes gives users
1778
+ * ample time while still acting as a safety net against lost messages.
1779
+ */
1780
+ const SHARE_REQUEST_TIMEOUT = 300000;
1781
+ var ShareError;
1782
+ (function (ShareError) {
1783
+ ShareError["ParentAppError"] = "parent_app_error";
1784
+ ShareError["ShareFailed"] = "share_failed";
1785
+ })(ShareError || (ShareError = {}));
1786
+ const ShareErrorMessages = {
1787
+ [ShareError.ParentAppError]: (error) => `Parent application error: ${error}`,
1788
+ [ShareError.ShareFailed]: (error) => `Share failed: ${error}`,
1789
+ };
1790
+ /**
1791
+ * Executes share using the Web Share API.
1792
+ *
1793
+ * @internal
1794
+ */
1795
+ async function executeShare(data) {
1796
+ try {
1797
+ await navigator.share({
1798
+ url: data.url,
1799
+ title: data.title,
1800
+ text: data.description,
1801
+ });
1802
+ return 'success';
1803
+ }
1804
+ catch (err) {
1805
+ if (err instanceof DOMException && err.name === 'AbortError') {
1806
+ return 'cancelled';
1807
+ }
1808
+ throw createError(ShareError.ShareFailed, ShareErrorMessages, getErrorMessage(err));
1809
+ }
1810
+ }
1811
+ /**
1812
+ * Initiates a share action. When running inside a parent application,
1813
+ * the share request is sent to the parent via the communication bridge.
1814
+ * When running standalone, `navigator.share()` is called directly.
1815
+ *
1816
+ * @param data - The data to share
1817
+ */
1818
+ async function share(data) {
1819
+ const parentApp = getParentApplication();
1820
+ if (parentApp !== null) {
1821
+ const response = await sendSdkRequest(parentApp, Action.OnShare, data, SHARE_REQUEST_TIMEOUT);
1822
+ if (response.payload.result === 'failure') {
1823
+ throw createError(ShareError.ParentAppError, ShareErrorMessages, response.payload.message);
1824
+ }
1825
+ // 'success' and 'cancelled' both resolve silently
1826
+ return;
1827
+ }
1828
+ await executeShare(data);
1829
+ }
1830
+ /**
1831
+ * Registers a callback to be called when a share request is received
1832
+ * from a child Experience.
1833
+ *
1834
+ * @param experience - The Experience instance to listen on
1835
+ * @param callback - Called with ShareData when a share request is received
1836
+ * @returns Unsubscribe function
1837
+ */
1838
+ function onShare(experience, callback) {
1839
+ return onSdkMessage(experience, (message) => {
1840
+ if (message.action === Action.OnShare) {
1841
+ callback(message.payload);
1842
+ }
1843
+ });
1844
+ }
1845
+ const unsubs = new Map();
1846
+ function handleExperienceEmbedded(experience) {
1847
+ const unsub = onSdkMessage(experience, async (message) => {
1848
+ if (message.action !== Action.OnShare) {
1849
+ return;
1850
+ }
1851
+ try {
1852
+ const parentApp = getParentApplication();
1853
+ let payload;
1854
+ if (parentApp !== null) {
1855
+ const response = await sendSdkRequest(parentApp, Action.OnShare, message.payload, SHARE_REQUEST_TIMEOUT);
1856
+ payload = response.payload;
1857
+ }
1858
+ else {
1859
+ const result = await executeShare(message.payload);
1860
+ payload = {
1861
+ result,
1862
+ message: result === 'success' ? 'Share successful' : 'Share cancelled',
1863
+ data: {},
1864
+ };
1865
+ }
1866
+ respondToSdkMessage(experience, message, payload);
1867
+ }
1868
+ catch (err) {
1869
+ respondToSdkMessage(experience, message, {
1870
+ result: 'failure',
1871
+ message: getErrorMessage(err),
1872
+ data: {},
1873
+ });
1874
+ }
1875
+ });
1876
+ unsubs.set(experience.id, unsub);
1877
+ }
1878
+ function handleExperienceUnmounted(experience) {
1879
+ const unsub = unsubs.get(experience.id);
1880
+ if (unsub) {
1881
+ unsub();
1882
+ unsubs.delete(experience.id);
1883
+ }
1884
+ }
1885
+ onStateChanged((experience, state) => {
1886
+ if (state === 'mounted') {
1887
+ handleExperienceEmbedded(experience);
1888
+ }
1889
+ else if (state === 'unmounted') {
1890
+ handleExperienceUnmounted(experience);
1891
+ }
1892
+ });
1893
+
1894
+ export { Action, VERSION$1 as BRIDGE_VERSION, BridgeError, BridgeImpl, ExperienceImpl, ParentApplicationImpl, QueryParam, ShareError, ShareErrorMessages, Source, VERSION, embed, enableLogging, executeShare, getBridge, getExperience, getParentApplication, getParentBridge, isAutoresizesHeight, isInsideIframe, onMessage, onMoreDataRequested, onReady, onSdkMessage, onShare, onStateChanged, reportExperienceSizeChanges, requestMoreData, respondToMessage, respondToSdkMessage, sendExperienceSize, sendExperienceSizeThrottled, sendFinishedLoadingUI, sendInitialised, sendMessage, sendReady, sendRequest, sendSdkMessage, sendSdkRequest, setRequestTimeout, share, shouldHideHeaderAndFooter, stateEmitter, unembed, unmount, updateExperienceState };
1895
+ //# sourceMappingURL=index.js.map