@monterosa/sdk-launcher-kit 2.0.0-rc.2 → 2.0.0-rc.4

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/index.cjs ADDED
@@ -0,0 +1,1945 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var sdkCore = require('@monterosa/sdk-core');
6
+ var sdkUtil = require('@monterosa/sdk-util');
7
+ var sdkInteractInterop = require('@monterosa/sdk-interact-interop');
8
+
9
+ /**
10
+ * @license
11
+ * @monterosa/sdk-launcher-kit
12
+ *
13
+ * Copyright © 2022 Monterosa Productions Limited. All rights reserved.
14
+ *
15
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
16
+ */
17
+ const RESIZE_THROTTLE_TIMEOUT = 25;
18
+ /**
19
+ * Duration of the loader fade IN/OUT animation
20
+ */
21
+ const LOADER_ANIMATION_DURATION = 750;
22
+ /**
23
+ * Final cut off timeout for the loader after which it will be hidden even
24
+ * though Experience UI may ne not yet ready
25
+ */
26
+ const LOADER_TIMEOUT = 5000;
27
+ /**
28
+ * Bumper timeout during which the loader still visible even though Experience
29
+ * UI may be ready
30
+ *
31
+ * (!) At the moment its value is 0 as loader has a fade in effect what already
32
+ * adds a small bumper delay before Experience is injected on the page
33
+ */
34
+ const LOADER_BUMPER_TIMEOUT = 0;
35
+ const DEFAULT_HEIGHT = 250;
36
+
37
+ /**
38
+ * @license
39
+ * @monterosa/sdk-launcher-kit
40
+ *
41
+ * Copyright © 2023 Monterosa Productions Limited. All rights reserved.
42
+ *
43
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
44
+ */
45
+ const logger = new sdkCore.Logger('@monterosa/sdk-launcher-kit');
46
+
47
+ /**
48
+ * @license
49
+ * @monterosa/sdk-launcher-kit
50
+ *
51
+ * Copyright © 2022-2026 Monterosa Productions Limited. All rights reserved.
52
+ *
53
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
54
+ */
55
+ /**
56
+ * A list of possible actions in communications between
57
+ * parent application and child Experience
58
+ *
59
+ * @internal
60
+ */
61
+ exports.Action = void 0;
62
+ (function (Action) {
63
+ /**
64
+ * Notifies that the communication bridge transport is ready.
65
+ * Auto-sent when the child bridge is created — no developer action needed.
66
+ */
67
+ Action["OnBridgeInitialised"] = "onBridgeInitialised";
68
+ /**
69
+ * Notifies that the Experience has initialised and is ready to receive messages.
70
+ * Sent explicitly by the developer via `sendInitialised()`.
71
+ * This triggers the `initialised` lifecycle state.
72
+ */
73
+ Action["OnExperienceInitialised"] = "onExperienceInitialised";
74
+ /**
75
+ * Notifies that UI of child Experience is loaded and ready to be visible.
76
+ * When this action is fired the loader will be hidden and
77
+ * the `ready` lifecycle state is triggered.
78
+ */
79
+ Action["OnReady"] = "onReady";
80
+ /**
81
+ * Notifies that intrinsic size of child Experience has changed
82
+ */
83
+ Action["OnResize"] = "onIntrinsicSizeChanged";
84
+ /**
85
+ * Notifies child Experience about the request to load more data
86
+ */
87
+ Action["OnMoreDataRequested"] = "onMoreDataRequested";
88
+ /**
89
+ * Notifies about a share request
90
+ */
91
+ Action["OnShare"] = "onShare";
92
+ })(exports.Action || (exports.Action = {}));
93
+ /**
94
+ * @internal
95
+ */
96
+ exports.Source = void 0;
97
+ (function (Source) {
98
+ Source["Sdk"] = "sdk";
99
+ Source["User"] = "user";
100
+ })(exports.Source || (exports.Source = {}));
101
+
102
+ /**
103
+ * @license
104
+ * @monterosa/sdk-launcher-kit
105
+ *
106
+ * Copyright © 2022-2026 Monterosa Productions Limited. All rights reserved.
107
+ *
108
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
109
+ */
110
+ /**
111
+ * Reserved query parameter names for controlling the behaviour of Experience.
112
+ */
113
+ exports.QueryParam = void 0;
114
+ (function (QueryParam) {
115
+ /**
116
+ * Represents the host of the application. This parameter is added by Studio
117
+ * and the embed URL already contains it.
118
+ */
119
+ QueryParam["Host"] = "h";
120
+ /**
121
+ * Represents the Project ID of the application. This parameter is added by
122
+ * Studio and the embed URL already contains it.
123
+ */
124
+ QueryParam["Project"] = "p";
125
+ /**
126
+ * Represents the Event ID of the application. This parameter is added to the
127
+ * Experience URL when the eventId is provided in the Experience config.
128
+ */
129
+ QueryParam["Event"] = "e";
130
+ /**
131
+ * Used to identify the unique ID of the communication bridge between
132
+ * the parent application and the child experience.
133
+ */
134
+ QueryParam["BridgeId"] = "micBridgeId";
135
+ /**
136
+ * Determines whether the header and footer views of the application should be
137
+ * hidden. This parameter can be used to control the visibility of the
138
+ * application's header and footer components.
139
+ */
140
+ QueryParam["HideHeaderAndFooter"] = "micHideHeaderAndFooter";
141
+ /**
142
+ * Determines whether autoresize is enabled for the application. When autoresize
143
+ * is enabled, the application's height will adjust automatically based on its
144
+ * content.
145
+ */
146
+ QueryParam["AutoresizesHeight"] = "micAutoresizesHeight";
147
+ })(exports.QueryParam || (exports.QueryParam = {}));
148
+
149
+ /**
150
+ * @license
151
+ * @monterosa/sdk-launcher-kit
152
+ *
153
+ * Copyright © 2024 Monterosa Productions Limited. All rights reserved.
154
+ *
155
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
156
+ */
157
+ /**
158
+ * Defines a set of error codes that may be encountered when using the
159
+ * Launcher Kit bridge
160
+ *
161
+ * @example
162
+ * ```javascript
163
+ * try {
164
+ * // some code that uses the LauncherKit's bridge
165
+ * } catch (err) {
166
+ * if (err.code === BridgeError.InvalidRequestTimeoutError) {
167
+ * // handle invalid request timeout error
168
+ * } else {
169
+ * // handle other error types
170
+ * }
171
+ * }
172
+ * ```
173
+ *
174
+ * @remarks
175
+ * - The `BridgeError` enum provides a convenient way to handle errors
176
+ * encountered when using the `LauncherKit` module. By checking the code
177
+ * property of the caught error against the values of the enum, the error
178
+ * type can be determined and appropriate action taken.
179
+ *
180
+ * - The `BridgeError` enum is not intended to be instantiated or extended.
181
+ */
182
+ exports.BridgeError = void 0;
183
+ (function (BridgeError) {
184
+ /**
185
+ * Indicates an error occurred due to an invalid timeout value being provided.
186
+ * This error is thrown when the specified timeout is not a positive number.
187
+ */
188
+ BridgeError["InvalidRequestTimeoutError"] = "invalid_request_timeout_error";
189
+ /**
190
+ * Indicates a request timed out waiting for a response.
191
+ * This error is thrown when a bridge request exceeds the specified timeout duration.
192
+ */
193
+ BridgeError["RequestTimeoutError"] = "request_timeout_error";
194
+ })(exports.BridgeError || (exports.BridgeError = {}));
195
+ const BridgeErrorMessages = {
196
+ [exports.BridgeError.InvalidRequestTimeoutError]: () => 'Request timeout must be greater than 0',
197
+ [exports.BridgeError.RequestTimeoutError]: (action, timeout) => `Request timeout: action "${action}" did not receive a response within ${timeout}ms`,
198
+ };
199
+
200
+ /**
201
+ * @license
202
+ * @monterosa/sdk-launcher-kit
203
+ *
204
+ * Copyright © 2024 Monterosa Productions Limited. All rights reserved.
205
+ *
206
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
207
+ */
208
+ /**
209
+ * @internal
210
+ */
211
+ const Config = {
212
+ requestTimeout: 20000,
213
+ };
214
+ /**
215
+ * Sets a new timeout value for requests (default is 20,000 ms).
216
+ *
217
+ * @remarks
218
+ * This function updates the request timeout in the application's configuration.
219
+ * It ensures that the new timeout value is a positive number, and throws
220
+ * an error if the value is non-positive.
221
+ *
222
+ * @param newTimeout - The new timeout value in milliseconds. Must be
223
+ * a positive number.
224
+ *
225
+ * @throws
226
+ * Throws {@link BridgeError | BridgeError.InvalidRequestTimeoutError}
227
+ * if `newTimeout` is less than or equal to 0.
228
+ *
229
+ * @example
230
+ * ```javascript
231
+ * // Set the request timeout to 3000 milliseconds
232
+ * setRequestTimeout(3000);
233
+ * ```
234
+ */
235
+ function setRequestTimeout(newTimeout) {
236
+ if (newTimeout <= 0) {
237
+ throw sdkUtil.createError(exports.BridgeError.InvalidRequestTimeoutError, BridgeErrorMessages);
238
+ }
239
+ Config.requestTimeout = newTimeout;
240
+ }
241
+
242
+ /**
243
+ * @license
244
+ * @monterosa/sdk-launcher-kit
245
+ *
246
+ * Copyright © 2022 Monterosa Productions Limited. All rights reserved.
247
+ *
248
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
249
+ */
250
+ function isMessage(message) {
251
+ return (message instanceof Object &&
252
+ Object.prototype.hasOwnProperty.call(message, 'bridgeId'));
253
+ }
254
+
255
+ /**
256
+ * @license
257
+ * @monterosa/sdk-launcher-kit
258
+ *
259
+ * Copyright © 2022 Monterosa Productions Limited. All rights reserved.
260
+ *
261
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
262
+ */
263
+ var _a$1, _b$1, _c$1, _d$1;
264
+ var _e, _f, _g;
265
+ const globals$2 = sdkUtil.getGlobal();
266
+ const receiveMessage = (message) => {
267
+ if (!isMessage(message)) {
268
+ // data does not match message format
269
+ return;
270
+ }
271
+ globals$2.monterosaSdk.emitter.emit('message', message);
272
+ };
273
+ function handleWindowMessage({ data }) {
274
+ try {
275
+ if (typeof data !== 'string') {
276
+ // ignore non string data
277
+ return;
278
+ }
279
+ const message = JSON.parse(data);
280
+ receiveMessage(message);
281
+ }
282
+ catch (err) {
283
+ console.error(sdkUtil.getErrorMessage(err));
284
+ }
285
+ }
286
+ /**
287
+ * Since this code operates as a side effect while updating the global space,
288
+ * we must be very careful because it may run twice, for example, when two apps
289
+ * using the SDK run on the same page. Additionally, the global namespace may
290
+ * already be updated by the Android or iOS SDKs.
291
+ */
292
+ // The Monterosa SDK namespace may already exist, either because it was created
293
+ // by a native SDK or by another web app using the JS SDK from the same scope.
294
+ (_a$1 = globals$2.monterosaSdk) !== null && _a$1 !== void 0 ? _a$1 : (globals$2.monterosaSdk = {
295
+ initialised: false,
296
+ emitter: new sdkUtil.Emitter(),
297
+ receiveMessage,
298
+ });
299
+ // Each of nullish coalescing assignments will only be applied when
300
+ // the Monterosa SDK namespace exists at that moment and one of its properties
301
+ // is not defined.
302
+ (_b$1 = (_e = globals$2.monterosaSdk).initialised) !== null && _b$1 !== void 0 ? _b$1 : (_e.initialised = false);
303
+ (_c$1 = (_f = globals$2.monterosaSdk).emitter) !== null && _c$1 !== void 0 ? _c$1 : (_f.emitter = new sdkUtil.Emitter());
304
+ (_d$1 = (_g = globals$2.monterosaSdk).receiveMessage) !== null && _d$1 !== void 0 ? _d$1 : (_g.receiveMessage = receiveMessage);
305
+ if (!globals$2.monterosaSdk.initialised) {
306
+ // Subscribe to the message only once for each app that uses the SDK on this page.
307
+ if (typeof globals$2.addEventListener !== 'undefined') {
308
+ globals$2.addEventListener('message', handleWindowMessage);
309
+ }
310
+ globals$2.monterosaSdk.initialised = true;
311
+ }
312
+
313
+ /**
314
+ * @license
315
+ * @monterosa/sdk-launcher-kit
316
+ *
317
+ * Copyright © 2022 Monterosa Productions Limited. All rights reserved.
318
+ *
319
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
320
+ */
321
+ var _a, _b, _c, _d;
322
+ const globals$1 = sdkUtil.getGlobal();
323
+ /**
324
+ * @internal
325
+ */
326
+ const IFRAME_ID_PREFIX = 'micBridge';
327
+ const IS_IOS = !!((_c = (_b = (_a = globals$1.webkit) === null || _a === void 0 ? void 0 : _a.messageHandlers) === null || _b === void 0 ? void 0 : _b.monterosaSdk) === null || _c === void 0 ? void 0 : _c.postMessage);
328
+ const IS_ANDROID = !!((_d = globals$1.monterosaSdk) === null || _d === void 0 ? void 0 : _d.postMessage);
329
+ const IS_WEB = globals$1.self !== globals$1.parent;
330
+ /**
331
+ * @internal
332
+ */
333
+ const VERSION$1 = '1.0.0';
334
+
335
+ /**
336
+ * @license
337
+ * @monterosa/sdk-launcher-kit
338
+ *
339
+ * Copyright © 2022-2026 Monterosa Productions Limited. All rights reserved.
340
+ *
341
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
342
+ */
343
+ const globals = sdkUtil.getGlobal();
344
+ /**
345
+ * @internal
346
+ */
347
+ class BridgeImpl extends sdkUtil.Emitter {
348
+ constructor(id = sdkUtil.generateUUID()) {
349
+ super();
350
+ this.id = id;
351
+ this.recipientInitialised = false;
352
+ this.messagesQueue = [];
353
+ globals.monterosaSdk.emitter.on('message', this.handleMessage.bind(this));
354
+ }
355
+ static isMessage(message) {
356
+ return (message instanceof Object &&
357
+ Object.prototype.hasOwnProperty.call(message, 'bridgeId') &&
358
+ Object.prototype.hasOwnProperty.call(message, 'action'));
359
+ }
360
+ get iFrameId() {
361
+ return `${IFRAME_ID_PREFIX}-${this.id}`;
362
+ }
363
+ get iFrameSelector() {
364
+ return `iframe#${this.iFrameId}`;
365
+ }
366
+ get childIFrame() {
367
+ return document.querySelector(this.iFrameSelector);
368
+ }
369
+ handleMessage(message) {
370
+ const { id, bridgeId, action, respondingTo } = message;
371
+ if (bridgeId !== this.id) {
372
+ return;
373
+ }
374
+ logger.log(`Received a ${respondingTo === null ? 'message' : 'response'}`, message);
375
+ if (action === exports.Action.OnBridgeInitialised) {
376
+ this.recipientInitialised = true;
377
+ if (respondingTo === null) {
378
+ this.send(exports.Action.OnBridgeInitialised, {}, exports.Source.Sdk, id);
379
+ }
380
+ while (this.messagesQueue.length > 0) {
381
+ this.postMessage(this.messagesQueue.shift());
382
+ }
383
+ return;
384
+ }
385
+ this.emit('message', message);
386
+ }
387
+ createMessage(action, payload, sourceName, respondingTo = null) {
388
+ return {
389
+ id: sdkUtil.generateUUID(),
390
+ respondingTo,
391
+ action,
392
+ sourceName,
393
+ bridgeId: this.id,
394
+ payload,
395
+ version: VERSION$1,
396
+ timestamp: Date.now(),
397
+ };
398
+ }
399
+ postMessage(message) {
400
+ var _a, _b, _c, _d;
401
+ if (!this.recipientInitialised &&
402
+ message.action !== exports.Action.OnBridgeInitialised) {
403
+ this.messagesQueue.push(message);
404
+ return;
405
+ }
406
+ const json = JSON.stringify(message);
407
+ if (IS_IOS) {
408
+ (_b = (_a = globals.webkit) === null || _a === void 0 ? void 0 : _a.messageHandlers) === null || _b === void 0 ? void 0 : _b.monterosaSdk.postMessage(json);
409
+ }
410
+ if (IS_ANDROID) {
411
+ if ((_c = globals.monterosaSdk) === null || _c === void 0 ? void 0 : _c.postMessage) {
412
+ globals.monterosaSdk.postMessage(json);
413
+ }
414
+ }
415
+ if (IS_WEB) {
416
+ globals.parent.postMessage(json, '*');
417
+ }
418
+ if (this.childIFrame) {
419
+ (_d = this.childIFrame.contentWindow) === null || _d === void 0 ? void 0 : _d.postMessage(json, '*');
420
+ }
421
+ }
422
+ send(action, payload = {}, sourceName = exports.Source.Sdk, respondingTo) {
423
+ const message = this.createMessage(action, payload, sourceName, respondingTo);
424
+ logger.log(`Sending a ${message.respondingTo === null ? 'message' : 'response'}`, message);
425
+ this.postMessage(message);
426
+ return message;
427
+ }
428
+ async request(action, payload = {}, timeout = Config.requestTimeout, sourceName = exports.Source.Sdk) {
429
+ let timeoutRef;
430
+ let handler;
431
+ const message = this.createMessage(action, payload, sourceName);
432
+ logger.log('Sending a request', message);
433
+ /**
434
+ * Start the timeout, when it finishes it should reject Promise.race below
435
+ */
436
+ const countdown = new Promise((_, reject) => {
437
+ timeoutRef = setTimeout(() => {
438
+ reject(sdkUtil.createError(exports.BridgeError.RequestTimeoutError, BridgeErrorMessages, action, timeout));
439
+ }, timeout);
440
+ });
441
+ /**
442
+ * Start the request and wait for the message with the respondingTo
443
+ * equal to message id we sent
444
+ */
445
+ const request = new Promise((resolve) => {
446
+ handler = (responseMessage) => {
447
+ if (responseMessage.respondingTo === message.id) {
448
+ resolve(responseMessage);
449
+ }
450
+ };
451
+ globals.monterosaSdk.emitter.on('message', handler);
452
+ this.postMessage(message);
453
+ });
454
+ /**
455
+ * Start race between timeout and request
456
+ * - if timeout wins the promise will be rejected
457
+ * - if request wins then Message will be resolved
458
+ */
459
+ return (Promise.race([countdown, request])
460
+ /**
461
+ * As the matter of clean up we need to clear timeout id
462
+ * and unsubscribe from the message event
463
+ */
464
+ .finally(() => {
465
+ clearTimeout(timeoutRef);
466
+ globals.monterosaSdk.emitter.off('message', handler);
467
+ }));
468
+ }
469
+ }
470
+
471
+ /**
472
+ * @license
473
+ * @monterosa/sdk-launcher-kit
474
+ *
475
+ * Copyright © 2022-2026 Monterosa Productions Limited. All rights reserved.
476
+ *
477
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
478
+ */
479
+ let parentBridge;
480
+ const bridges = new Map();
481
+ /**
482
+ * @internal
483
+ */
484
+ function getBridge(id) {
485
+ if (bridges.has(id)) {
486
+ return bridges.get(id);
487
+ }
488
+ const bridge = new BridgeImpl(id);
489
+ bridges.set(id, bridge);
490
+ return bridge;
491
+ }
492
+ /**
493
+ * Returns true if the page is inside an iframe.
494
+ *
495
+ * @internal
496
+ */
497
+ function isInsideIframe() {
498
+ if (typeof window === 'undefined') {
499
+ return false;
500
+ }
501
+ try {
502
+ return window.self !== window.top;
503
+ }
504
+ catch (_a) {
505
+ // SecurityError is thrown when accessing window.top in a cross-origin iframe.
506
+ // If we can't access it, we're definitely in an iframe.
507
+ return true;
508
+ }
509
+ }
510
+ /**
511
+ * @internal
512
+ */
513
+ function getParentBridge() {
514
+ if (typeof window === 'undefined') {
515
+ return null;
516
+ }
517
+ if (parentBridge !== undefined) {
518
+ return parentBridge;
519
+ }
520
+ if (!isInsideIframe()) {
521
+ return null;
522
+ }
523
+ const url = new URL(window.location.href);
524
+ const bridgeId = url.searchParams.get(exports.QueryParam.BridgeId);
525
+ if (bridgeId === null) {
526
+ return null;
527
+ }
528
+ parentBridge = new BridgeImpl(bridgeId);
529
+ parentBridge.send(exports.Action.OnBridgeInitialised, {}, exports.Source.Sdk);
530
+ return parentBridge;
531
+ }
532
+ /**
533
+ * @internal
534
+ */
535
+ function sendSdkMessage(bridged, action, payload = {}) {
536
+ return bridged.bridge.send(action, payload, exports.Source.Sdk);
537
+ }
538
+ /**
539
+ * Sends a message with an action name and payload to a parent application or child Experience.
540
+ *
541
+ * @remarks
542
+ * Usage example in parent application:
543
+ *
544
+ * @example
545
+ * ```typescript
546
+ * const experience = getExperience();
547
+ *
548
+ * // message to Experience can be sent only when its initialised
549
+ * onStateChanged(experience, (state) => {
550
+ * if (state === 'initialised') {
551
+ * sendMessage(
552
+ * experience,
553
+ * 'my_action',
554
+ * { key: 'value' }
555
+ * );
556
+ * }
557
+ * });
558
+ *
559
+ * embed(experience);
560
+ * ```
561
+ *
562
+ * Usage example in child Experience:
563
+ *
564
+ * @example
565
+ * ```typescript
566
+ * const parentApp = getParentApplication();
567
+ *
568
+ * if (parentApp !== null) {
569
+ * sendMessage(
570
+ * parentApp,
571
+ * 'my_action',
572
+ * { key: 'value' }
573
+ * );
574
+ * }
575
+ * ```
576
+ *
577
+ * @param bridged - Instance of either {@link ParentApplication} or {@link Experience}
578
+ * @param action - Arbitrary action name that defines purpose of the message
579
+ * @param payload - A key-value object that is sent in a message
580
+ * @returns Returns {@link Message | message}
581
+ */
582
+ function sendMessage(bridged, action, payload = {}) {
583
+ return bridged.bridge.send(action, payload, exports.Source.User);
584
+ }
585
+ /**
586
+ * @internal
587
+ */
588
+ function sendSdkRequest(bridged, action, payload = {}, timeout = Config.requestTimeout) {
589
+ return bridged.bridge.request(action, payload, timeout, exports.Source.Sdk);
590
+ }
591
+ /**
592
+ * Sends a request and returns a Promise that resolves when the recipient responds.
593
+ *
594
+ * @remarks
595
+ * Similar to {@link sendMessage} but returns a Promise which
596
+ * resolves if the recipient responds with {@link respondToMessage}. Otherwise it
597
+ * rejects after a certain timeout.
598
+ *
599
+ * Usage example in parent application:
600
+ *
601
+ * @example
602
+ * ```typescript
603
+ * const experience = getExperience();
604
+ *
605
+ * // request to Experience can be sent only when its initialised
606
+ * onStateChanged(experience, async (state) => {
607
+ * if (state === 'initialised') {
608
+ * const response = await sendRequest(
609
+ * experience,
610
+ * 'my_action',
611
+ * { key: 'value' }
612
+ * );
613
+ *
614
+ * console.log(response);
615
+ * }
616
+ * });
617
+ *
618
+ * embed(experience);
619
+ * ```
620
+ *
621
+ * Usage example in child Experience:
622
+ *
623
+ * @example
624
+ * ```typescript
625
+ * const parentApp = getParentApplication();
626
+ *
627
+ * // parent application can be null if Experience is running stand alone
628
+ * if (parentApp !== null) {
629
+ * const response = await sendRequest(
630
+ * parentApp,
631
+ * 'my_action',
632
+ * { key: 'value' }
633
+ * );
634
+ *
635
+ * console.log(response);
636
+ * }
637
+ * ```
638
+ *
639
+ * @param bridged - Instance of either {@link ParentApplication} or {@link Experience}
640
+ * @param action - Arbitrary action name that defines purpose of the message
641
+ * @param payload - A key-value object that is sent as in request
642
+ * @param timeout - Configurable request timeout, if there is no response by
643
+ * the end of this timeout then returned Promise will be rejected.
644
+ */
645
+ function sendRequest(bridged, action, payload = {}, timeout = Config.requestTimeout) {
646
+ return bridged.bridge.request(action, payload, timeout, exports.Source.User);
647
+ }
648
+ /**
649
+ * @internal
650
+ */
651
+ function respondToSdkMessage(bridged, message, payload = {}) {
652
+ bridged.bridge.send(message.action, payload, exports.Source.Sdk, message.id);
653
+ }
654
+ /**
655
+ * Respond to a received message. It is used to reply to a
656
+ * {@link sendRequest | user request}.
657
+ *
658
+ * @param bridged - Instance of either {@link ParentApplication} or {@link Experience}
659
+ * @param message - {@link Message | Message} to respond to
660
+ * @param payload - A key-value object that is sent as in response
661
+ */
662
+ function respondToMessage(bridged, message, payload = {}) {
663
+ bridged.bridge.send(message.action, payload, exports.Source.User, message.id);
664
+ }
665
+ function onMessageFunc(bridged, source, callback) {
666
+ return sdkUtil.subscribe(bridged.bridge, 'message', (message) => {
667
+ if (message.sourceName === source) {
668
+ callback(message);
669
+ }
670
+ });
671
+ }
672
+ /**
673
+ * @internal
674
+ */
675
+ function onSdkMessage(bridged, callback) {
676
+ return onMessageFunc(bridged, exports.Source.Sdk, callback);
677
+ }
678
+ /**
679
+ * @internal
680
+ *
681
+ * Adds an observer for when user message is received
682
+ *
683
+ * @param bridged - Instance of either {@link ParentApplication} or {@link Experience}
684
+ * @param callback - The callback that is triggered when user message is received
685
+ * @returns The unsubscribe function. When it's called,
686
+ * the observer will be removed and user messages will no longer be received
687
+ */
688
+ function onMessage(bridged, callback) {
689
+ return onMessageFunc(bridged, exports.Source.User, callback);
690
+ }
691
+
692
+ /**
693
+ * @license
694
+ * @monterosa/sdk-launcher-kit
695
+ *
696
+ * Copyright © 2022-2026 Monterosa Productions Limited. All rights reserved.
697
+ *
698
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
699
+ */
700
+ /**
701
+ * @internal
702
+ */
703
+ class ExperienceImpl {
704
+ constructor(sdk, config) {
705
+ this.sdk = sdk;
706
+ this._parameters = {};
707
+ this.id = sdkUtil.generateUUID();
708
+ this.state = 'unmounted';
709
+ this.customElement = null;
710
+ this._config = config;
711
+ this.bridge = getBridge(this.id);
712
+ if (config.parameters !== undefined) {
713
+ const reserved = Object.values(exports.QueryParam);
714
+ const ignored = [];
715
+ Object.entries(config.parameters).forEach(([key, value]) => {
716
+ if (reserved.includes(key)) {
717
+ ignored.push(key);
718
+ }
719
+ else {
720
+ this._parameters[key] = value;
721
+ }
722
+ });
723
+ if (ignored.length === 1) {
724
+ console.warn(`Parameter "${ignored[0]}" ignored as it matches reserved words`);
725
+ }
726
+ if (ignored.length > 1) {
727
+ console.warn(`Parameters "${ignored.join('", "')}" ignored as they match reserved words`);
728
+ }
729
+ }
730
+ }
731
+ get config() {
732
+ var _a, _b, _c, _d;
733
+ return Object.assign(this._config, {
734
+ autoresizesHeight: (_a = this._config.autoresizesHeight) !== null && _a !== void 0 ? _a : false,
735
+ hidesHeadersAndFooters: (_b = this._config.hidesHeadersAndFooters) !== null && _b !== void 0 ? _b : true,
736
+ supportsLoadingState: (_c = this._config.supportsLoadingState) !== null && _c !== void 0 ? _c : true,
737
+ experienceUrl: (_d = this._config.experienceUrl) !== null && _d !== void 0 ? _d : null,
738
+ });
739
+ }
740
+ async getEmbedUrl() {
741
+ if (this.embedUrl) {
742
+ return Promise.resolve(this.embedUrl);
743
+ }
744
+ const { options: { host, projectId }, } = this.sdk;
745
+ const listings = await sdkInteractInterop.fetchListings(host, projectId);
746
+ this.embedUrl = listings.project.embed;
747
+ return this.embedUrl;
748
+ }
749
+ async getUrl() {
750
+ const embedUrl = await this.getEmbedUrl();
751
+ // sanitise and create an object from an url
752
+ let url = new URL(ExperienceImpl.sanitiseUrl(embedUrl));
753
+ // override host and project with those that are set in SDK instance
754
+ url.searchParams.set(exports.QueryParam.Host, this.sdk.options.host);
755
+ url.searchParams.set(exports.QueryParam.Project, this.sdk.options.projectId);
756
+ // if custom experienceUrl is set:
757
+ // * take experienceUrl as the base
758
+ // * search params from experienceUrl have priority
759
+ if (this.config.experienceUrl !== null) {
760
+ // sanitise and create an object from a custom url
761
+ const customUrl = new URL(ExperienceImpl.sanitiseUrl(this.config.experienceUrl));
762
+ // apply embedUrl query parameters if they don't exist in experienceUrl
763
+ Array.from(url.searchParams.entries())
764
+ .filter(([key]) => !customUrl.searchParams.has(key))
765
+ .forEach(([key, value]) => customUrl.searchParams.set(key, value));
766
+ url = customUrl;
767
+ }
768
+ // Prepare a final list of query parameters
769
+ const queryParameters = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (this.config.host !== undefined && {
770
+ [exports.QueryParam.Host]: this.config.host,
771
+ })), (this.config.projectId !== undefined && {
772
+ [exports.QueryParam.Project]: this.config.projectId,
773
+ })), (this.config.eventId !== undefined && {
774
+ [exports.QueryParam.Event]: this.config.eventId,
775
+ })), { [exports.QueryParam.BridgeId]: this.bridge.id, [exports.QueryParam.HideHeaderAndFooter]: this.config.hidesHeadersAndFooters
776
+ ? '1'
777
+ : '0', [exports.QueryParam.AutoresizesHeight]: this.config.autoresizesHeight ? '1' : '0' }), this._parameters);
778
+ Object.entries(queryParameters).forEach(([key, value]) => {
779
+ url.searchParams.set(key, value);
780
+ });
781
+ return url.href;
782
+ }
783
+ static sanitiseUrl(url, options) {
784
+ const stripReservedParameters = (options === null || options === void 0 ? void 0 : options.stripReservedParameters) || 'mic';
785
+ // Ensure the URL includes a protocol.
786
+ if (/^http/.test(url) === false) {
787
+ // If none are found, use the same as the document.
788
+ url = `${document.location.protocol}${url}`;
789
+ }
790
+ const urlObj = new URL(url);
791
+ Object.values(exports.QueryParam)
792
+ .filter((key) => {
793
+ if (stripReservedParameters === 'mic') {
794
+ return key.startsWith('mic');
795
+ }
796
+ return key;
797
+ })
798
+ .forEach((key) => urlObj.searchParams.delete(key));
799
+ return urlObj.href;
800
+ }
801
+ }
802
+
803
+ /**
804
+ * @license
805
+ * @monterosa/sdk-launcher-kit
806
+ *
807
+ * Copyright © 2025-2026 Monterosa Productions Limited. All rights reserved.
808
+ *
809
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
810
+ */
811
+ const integrations = new Map();
812
+ function addIntegration(container, integration) {
813
+ integrations.set(container, integration);
814
+ }
815
+ function getIntegration(containerOrExperience) {
816
+ if (containerOrExperience instanceof HTMLElement) {
817
+ return integrations.get(containerOrExperience);
818
+ }
819
+ return Array.from(integrations.values()).find((integration) => integration.experience === containerOrExperience);
820
+ }
821
+ function deleteIntegration(container) {
822
+ integrations.delete(container);
823
+ }
824
+ function hasIntegration(containerOrExperience) {
825
+ if (containerOrExperience instanceof HTMLElement) {
826
+ return integrations.has(containerOrExperience);
827
+ }
828
+ return Array.from(integrations.values()).some((integration) => integration.experience === containerOrExperience);
829
+ }
830
+
831
+ /**
832
+ * @license
833
+ * @monterosa/sdk-launcher-kit
834
+ *
835
+ * Copyright © 2026 Monterosa Productions Limited. All rights reserved.
836
+ *
837
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
838
+ */
839
+ /**
840
+ * Event emitter for Experience state changes.
841
+ *
842
+ * @internal
843
+ */
844
+ const stateEmitter = new sdkUtil.Emitter();
845
+ /**
846
+ * Updates the Experience state and emits a state change event.
847
+ *
848
+ * @param experience - The Experience instance to update
849
+ * @param newState - The target state to transition to
850
+ *
851
+ * @internal
852
+ */
853
+ function updateExperienceState(experience, newState) {
854
+ const currentState = experience.state;
855
+ // No-op if already in the target state
856
+ if (currentState === newState) {
857
+ return;
858
+ }
859
+ // Cast to ExperienceImpl to access the mutable state property
860
+ experience.state = newState;
861
+ stateEmitter.emit('stateChanged', experience, newState);
862
+ }
863
+ function onStateChanged(experienceOrCallback, callback) {
864
+ if (typeof experienceOrCallback === 'function') {
865
+ // Global handler: onStateChanged(callback)
866
+ const globalCallback = experienceOrCallback;
867
+ stateEmitter.on('stateChanged', globalCallback);
868
+ return () => {
869
+ stateEmitter.off('stateChanged', globalCallback);
870
+ };
871
+ }
872
+ // Instance handler: onStateChanged(experience, callback)
873
+ const experience = experienceOrCallback;
874
+ const instanceCallback = callback;
875
+ const wrappedCallback = (exp, state) => {
876
+ if (exp === experience) {
877
+ instanceCallback(state);
878
+ }
879
+ };
880
+ stateEmitter.on('stateChanged', wrappedCallback);
881
+ return () => {
882
+ stateEmitter.off('stateChanged', wrappedCallback);
883
+ };
884
+ }
885
+
886
+ /**
887
+ * @license
888
+ * @monterosa/sdk-launcher-kit
889
+ *
890
+ * Copyright © 2022 Monterosa Productions Limited. All rights reserved.
891
+ *
892
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
893
+ */
894
+ /* eslint-enable */
895
+ function getLoadingTemplate() {
896
+ return `
897
+ <div>
898
+ <style type="text/css">
899
+ .__mic-loader {
900
+ position: absolute;
901
+ width: 100%;
902
+ height: 100%;
903
+ z-index: 9;
904
+ box-sizing: border-box;
905
+ text-align: center;
906
+ background: #fff;
907
+ }
908
+
909
+ .__mic-loader__container {
910
+ padding: 20px 0;
911
+ gap: 20px;
912
+ min-height: ${DEFAULT_HEIGHT}px;
913
+ display: flex;
914
+ flex-direction: column;
915
+ justify-content: center;
916
+ align-items: center;
917
+ }
918
+
919
+ .__mic-loader__spinner {
920
+ position: relative;
921
+ width: 10px;
922
+ height: 10px;
923
+ border-radius: 5px;
924
+ background-color: #0b0f1c;
925
+ color: #0b0f1c;
926
+ animation: mic-loader__animation 1s infinite linear alternate;
927
+ animation-delay: 0.5s;
928
+ }
929
+
930
+ .__mic-loader__spinner::before,
931
+ .__mic-loader__spinner::after {
932
+ content: "";
933
+ display: inline-block;
934
+ position: absolute;
935
+ top: 0;
936
+ }
937
+
938
+ .__mic-loader__spinner::before {
939
+ left: -15px;
940
+ width: 10px;
941
+ height: 10px;
942
+ border-radius: 5px;
943
+ background-color: #0b0f1c;
944
+ color: #0b0f1c;
945
+ animation: mic-loader__animation 1s infinite alternate;
946
+ animation-delay: 0s;
947
+ }
948
+
949
+ .__mic-loader__spinner::after {
950
+ left: 15px;
951
+ width: 10px;
952
+ height: 10px;
953
+ border-radius: 5px;
954
+ background-color: #0b0f1c;
955
+ color: #0b0f1c;
956
+ animation: mic-loader__animation 1s infinite alternate;
957
+ animation-delay: 1s;
958
+ }
959
+
960
+ @keyframes mic-loader__animation {
961
+ 0% {
962
+ background-color: #0b0f1c;
963
+ }
964
+ 50%, 100% {
965
+ background-color: rgba(11, 15, 28, 0.2);
966
+ }
967
+ }
968
+ </style>
969
+ <div class="__mic-loader">
970
+ <div class="__mic-loader__container">
971
+ <div class="__mic-loader__spinner"></div>
972
+ </div>
973
+ </div>
974
+ </div>
975
+ `;
976
+ }
977
+ function embed$1(container, loadingTemplate = getLoadingTemplate) {
978
+ /**
979
+ * Return existing element if it exists
980
+ */
981
+ let loaderElement = container.querySelector('[data-role=loader]');
982
+ if (loaderElement !== null) {
983
+ return loaderElement;
984
+ }
985
+ /**
986
+ * Stash and apply some custom styles to container element
987
+ */
988
+ stashStyles(container, ['minHeight', 'position']);
989
+ container.style.minHeight = `${DEFAULT_HEIGHT}px`;
990
+ /**
991
+ * Inject loader element built from the html markup template
992
+ */
993
+ const templateElement = document.createElement('template');
994
+ templateElement.innerHTML = loadingTemplate().trim();
995
+ loaderElement = container.appendChild(templateElement.content.firstElementChild);
996
+ /**
997
+ * Setting custom data attribute to be able to distinguish element along
998
+ * other injected html elements if any
999
+ */
1000
+ loaderElement.setAttribute('data-role', 'loader');
1001
+ return loaderElement;
1002
+ }
1003
+ function unmount$1(container) {
1004
+ var _a;
1005
+ const loaderElement = container.querySelector('[data-role=loader]');
1006
+ if (loaderElement === null) {
1007
+ return;
1008
+ }
1009
+ (_a = loaderElement.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(loaderElement);
1010
+ unstashStyles(container);
1011
+ }
1012
+ async function show(container, loadingTemplate = getLoadingTemplate) {
1013
+ const loaderElement = embed$1(container, loadingTemplate);
1014
+ const { position } = getComputedStyle(container);
1015
+ /**
1016
+ * In order to properly position the loader,
1017
+ * the container's position should be anything but 'static'.
1018
+ */
1019
+ if (position === 'static') {
1020
+ container.style.position = 'relative';
1021
+ }
1022
+ /**
1023
+ * Setting styles to the loader for a nice fade in animation
1024
+ */
1025
+ loaderElement.style.opacity = '0';
1026
+ /**
1027
+ * Kicking fade animation in.
1028
+ */
1029
+ setTimeout(() => {
1030
+ loaderElement.style.transition = `all ${LOADER_ANIMATION_DURATION}ms`;
1031
+ loaderElement.style.opacity = '1';
1032
+ }, 0);
1033
+ /**
1034
+ * Wait until the animation is finished. We do not use "transitionend" event
1035
+ * here as it will just make the code more bloated and unnecessary complex.
1036
+ */
1037
+ await sdkUtil.delay(LOADER_ANIMATION_DURATION);
1038
+ }
1039
+ async function hide(container) {
1040
+ const loaderElement = container.querySelector('[data-role=loader]');
1041
+ if (loaderElement === null) {
1042
+ return;
1043
+ }
1044
+ /**
1045
+ * Kicking fade out animation.
1046
+ */
1047
+ setTimeout(() => {
1048
+ loaderElement.style.opacity = '0';
1049
+ }, 0);
1050
+ /**
1051
+ * Wait until the animation is finished. We do not use "transitionend" event
1052
+ * here as it will just make the code more bloated and unnecessary complex.
1053
+ */
1054
+ await sdkUtil.delay(LOADER_ANIMATION_DURATION);
1055
+ unstashStyles(container);
1056
+ unmount$1(container);
1057
+ }
1058
+ function stashStyles(element, props) {
1059
+ const styles = getComputedStyle(element);
1060
+ const stash = props
1061
+ .map((prop) => `${String(prop)}=${styles[prop]}`)
1062
+ .join(';');
1063
+ element.setAttribute('data-stash', stash);
1064
+ }
1065
+ function unstashStyles(element) {
1066
+ const stash = element.getAttribute('data-stash');
1067
+ if (stash === null) {
1068
+ return;
1069
+ }
1070
+ const attributes = stash
1071
+ .split(';')
1072
+ .map((attr) => attr.split('='));
1073
+ for (const [attr, value] of attributes) {
1074
+ element.style[attr] = value;
1075
+ }
1076
+ element.removeAttribute('data-stash');
1077
+ }
1078
+
1079
+ var version = "2.0.0-rc.4";
1080
+
1081
+ /**
1082
+ * @license
1083
+ * @monterosa/sdk-launcher-kit
1084
+ *
1085
+ * Copyright © 2022-2026 Monterosa Productions Limited. All rights reserved.
1086
+ *
1087
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1088
+ */
1089
+ /**
1090
+ * The current SDK version.
1091
+ *
1092
+ * @internal
1093
+ */
1094
+ const VERSION = version;
1095
+ /**
1096
+ * Creates an iframe with the provided parameters.
1097
+ *
1098
+ * @param url Url of the web app.
1099
+ *
1100
+ * @private
1101
+ */
1102
+ function createIFrame(url, options = {}) {
1103
+ const iframe = document.createElement('iframe');
1104
+ iframe.style.width = '100%';
1105
+ iframe.style.height = '100%';
1106
+ iframe.style.border = '0';
1107
+ iframe.style.display = 'block';
1108
+ iframe.style.boxSizing = 'border-box';
1109
+ iframe.setAttribute('src', url);
1110
+ if (options.id !== undefined) {
1111
+ iframe.setAttribute('id', options.id);
1112
+ }
1113
+ if (options.allow !== undefined) {
1114
+ iframe.setAttribute('allow', options.allow);
1115
+ }
1116
+ if (options.allowFullScreen === true) {
1117
+ iframe.setAttribute('allowfullscreen', '');
1118
+ }
1119
+ if (options.title !== undefined) {
1120
+ iframe.setAttribute('title', options.title);
1121
+ }
1122
+ /**
1123
+ * Though scrolling attribute is deprecated we still have to rely on it as some
1124
+ * browsers (e.g. Chrome, as of now version 103) just ignores overflow: hidden.
1125
+ * Hence we are setting scrolling to no in order to eliminate scroll and calculate
1126
+ * width of the child Experience correctly. If scroll persists it appears on each
1127
+ * content change what leads to incorrect width calculation.
1128
+ *
1129
+ * Later we will look into alternatives such as iframeless Experience embed
1130
+ */
1131
+ if (!options.scrolling) {
1132
+ iframe.style.overflow = 'hidden';
1133
+ iframe.setAttribute('scrolling', 'no');
1134
+ }
1135
+ return iframe;
1136
+ }
1137
+ function concealIFrame(iframe) {
1138
+ iframe.style.opacity = '0';
1139
+ }
1140
+ function revealIFrame(iframe) {
1141
+ iframe.style.opacity = '1';
1142
+ }
1143
+ function isSdk(value) {
1144
+ return value instanceof sdkCore.Sdk;
1145
+ }
1146
+ function getExperience(sdkOrConfig, config) {
1147
+ let sdk;
1148
+ let experienceConfig;
1149
+ if (isSdk(sdkOrConfig)) {
1150
+ /**
1151
+ * Interface: getExperience(sdk, config?)
1152
+ */
1153
+ sdk = sdkOrConfig;
1154
+ if (config !== undefined) {
1155
+ experienceConfig = config;
1156
+ }
1157
+ else {
1158
+ experienceConfig = {};
1159
+ }
1160
+ }
1161
+ else if (sdkOrConfig !== undefined) {
1162
+ /**
1163
+ * Interface: getExperience(config)
1164
+ */
1165
+ sdk = sdkCore.getSdk();
1166
+ experienceConfig = sdkOrConfig;
1167
+ }
1168
+ else {
1169
+ /**
1170
+ * Interface: getExperience()
1171
+ */
1172
+ sdk = sdkCore.getSdk();
1173
+ experienceConfig = {};
1174
+ }
1175
+ const experience = new ExperienceImpl(sdk, experienceConfig);
1176
+ return experience;
1177
+ }
1178
+ async function waitForAction(experience, action) {
1179
+ return new Promise((resolve) => {
1180
+ const unsubscribe = onSdkMessage(experience, (message) => {
1181
+ if (message.action === action) {
1182
+ unsubscribe();
1183
+ resolve();
1184
+ }
1185
+ });
1186
+ });
1187
+ }
1188
+ async function experienceReady(experience) {
1189
+ /**
1190
+ * Bumper delay during which loading state can't be hidden even
1191
+ * if Experience loaded earlier than timer reached bumper timeout
1192
+ */
1193
+ const bumper = sdkUtil.delay(LOADER_BUMPER_TIMEOUT);
1194
+ /**
1195
+ * Final cut off timeout delay after which loading state must
1196
+ * be hidden even if Experience is still loading
1197
+ */
1198
+ const timeout = sdkUtil.delay(LOADER_TIMEOUT);
1199
+ const loaded = waitForAction(experience, exports.Action.OnReady);
1200
+ const hasFullyLoadedExperience = Promise.all([bumper, loaded]);
1201
+ const eitherTimeoutOrFullyLoaded = Promise.race([
1202
+ timeout,
1203
+ hasFullyLoadedExperience,
1204
+ ]);
1205
+ return eitherTimeoutOrFullyLoaded;
1206
+ }
1207
+ /**
1208
+ * Embeds a web Experience app into an iframe.
1209
+ *
1210
+ * @remarks
1211
+ * There is only one app that can be associated with an Experience and it is
1212
+ * configured in Monterosa / Interaction Cloud. Please refer to the developer
1213
+ * guide for more information:
1214
+ * {@link https://products.monterosa.co/mic/developer-guides/whats-an-app}
1215
+ *
1216
+ * @example
1217
+ * ```javascript
1218
+ * const experience = getExperience();
1219
+ *
1220
+ * embed(experience, 'container-id');
1221
+ * ```
1222
+ * @param experience - An instance of Experience
1223
+ * @param containerOrId - HTML element instance or
1224
+ * element id where iframe is embedded into.
1225
+ *
1226
+ * @public
1227
+ */
1228
+ async function embed(experience, containerOrId) {
1229
+ const container = containerOrId instanceof HTMLElement
1230
+ ? containerOrId
1231
+ : document.getElementById(containerOrId);
1232
+ if (container === null) {
1233
+ throw new Error(`Container element "${containerOrId}" not found in DOM. ` +
1234
+ 'Please ensure the element exists before calling embed().');
1235
+ }
1236
+ if (hasIntegration(container)) {
1237
+ throw new Error('Container already contains an embedded experience. Use unmount() first ' +
1238
+ 'to remove the existing experience before embedding a new one.');
1239
+ }
1240
+ if (hasIntegration(experience)) {
1241
+ throw new Error('This experience is already embedded in another container. Use unmount() ' +
1242
+ 'to remove it from that container before embedding it into this one.');
1243
+ }
1244
+ const controller = new AbortController();
1245
+ const integration = {
1246
+ container,
1247
+ experience,
1248
+ controller,
1249
+ };
1250
+ addIntegration(container, integration);
1251
+ if (experience.config.supportsLoadingState === true) {
1252
+ // Although showLoader is an asynchronous function, we execute
1253
+ // it synchronously to embed the iframe as quickly as possible.
1254
+ show(container, experience.config.loadingTemplate);
1255
+ }
1256
+ const url = await experience.getUrl();
1257
+ if (controller.signal.aborted) {
1258
+ return;
1259
+ }
1260
+ const iframe = createIFrame(url, {
1261
+ id: experience.bridge.iFrameId,
1262
+ scrolling: !experience.config.autoresizesHeight,
1263
+ allow: experience.config.allow,
1264
+ allowFullScreen: experience.config.allowFullScreen,
1265
+ title: experience.config.title,
1266
+ });
1267
+ container.appendChild(iframe);
1268
+ concealIFrame(iframe);
1269
+ updateExperienceState(experience, 'mounted');
1270
+ await waitForAction(experience, exports.Action.OnExperienceInitialised);
1271
+ if (controller.signal.aborted) {
1272
+ return;
1273
+ }
1274
+ updateExperienceState(experience, 'initialised');
1275
+ await experienceReady(experience);
1276
+ if (controller.signal.aborted) {
1277
+ return;
1278
+ }
1279
+ updateExperienceState(experience, 'ready');
1280
+ revealIFrame(iframe);
1281
+ if (experience.config.supportsLoadingState === true) {
1282
+ await hide(container);
1283
+ }
1284
+ }
1285
+ /**
1286
+ * Removes an Experience from its container and resets its state to `unmounted`.
1287
+ *
1288
+ * This is the preferred method for removing an embedded Experience.
1289
+ * Use {@link onStateChanged} to observe when the Experience transitions
1290
+ * to the `unmounted` state.
1291
+ *
1292
+ * @example
1293
+ * ```javascript
1294
+ * const experience = getExperience(sdk, { eventId: 'poll-123' });
1295
+ * embed(experience, container);
1296
+ *
1297
+ * // Later, to remove:
1298
+ * unembed(experience);
1299
+ * ```
1300
+ *
1301
+ * @param experience - The Experience instance to unembed
1302
+ *
1303
+ * @public
1304
+ */
1305
+ function unembed(experience) {
1306
+ const integration = getIntegration(experience);
1307
+ if (!integration) {
1308
+ throw new Error('This Experience is not currently embedded. ' +
1309
+ 'Please ensure the Experience is embedded before calling unembed().');
1310
+ }
1311
+ const { container } = integration;
1312
+ integration.controller.abort();
1313
+ while (container.lastElementChild) {
1314
+ container.removeChild(container.lastElementChild);
1315
+ }
1316
+ deleteIntegration(container);
1317
+ container.style.height = '';
1318
+ updateExperienceState(experience, 'unmounted');
1319
+ }
1320
+ /**
1321
+ * Unmounts web Experience app which was previously embedded in the container.
1322
+ *
1323
+ * @deprecated Use {@link unembed} instead, which takes an Experience instance
1324
+ * rather than a container.
1325
+ *
1326
+ * @example
1327
+ * ```javascript
1328
+ * unmount('container-id');
1329
+ * ```
1330
+ *
1331
+ * @param {HTMLElement | string} containerOrId - HTML element instance or
1332
+ * element id where iframe is embedded into.
1333
+ *
1334
+ * @public
1335
+ */
1336
+ function unmount(containerOrId) {
1337
+ console.warn('[launcher-kit] unmount() is deprecated. Use unembed(experience) instead.');
1338
+ const container = containerOrId instanceof HTMLElement
1339
+ ? containerOrId
1340
+ : document.getElementById(containerOrId);
1341
+ if (container === null) {
1342
+ throw new Error(`Container element "${containerOrId}" not found in DOM. ` +
1343
+ 'Please ensure the element exists before calling unmount().');
1344
+ }
1345
+ const integration = getIntegration(container);
1346
+ if (!integration) {
1347
+ throw new Error(`No Experience found embedded in container "${containerOrId}". ` +
1348
+ 'Please ensure the Experience is embedded before calling unmount().');
1349
+ }
1350
+ integration.controller.abort();
1351
+ while (container.lastElementChild) {
1352
+ container.removeChild(container.lastElementChild);
1353
+ }
1354
+ deleteIntegration(container);
1355
+ container.style.height = '';
1356
+ updateExperienceState(integration.experience, 'unmounted');
1357
+ }
1358
+ /**
1359
+ * Informs the Experience that more data should be loaded and displayed on the UI.
1360
+ *
1361
+ * @remarks
1362
+ * One example is when Experience renders items feed partially. Once a user scrolled
1363
+ * to the bottom edge of the app, more elements to load is requested.
1364
+ *
1365
+ * @param experience - Experience instance
1366
+ */
1367
+ function requestMoreData(experience) {
1368
+ sendSdkMessage(experience, exports.Action.OnMoreDataRequested);
1369
+ }
1370
+ function enableLogging(logLevelOrFlag = true) {
1371
+ if (typeof logLevelOrFlag === 'boolean') {
1372
+ logger.logLevel = logLevelOrFlag ? sdkCore.LogLevel.Verbose : sdkCore.LogLevel.Silent;
1373
+ return;
1374
+ }
1375
+ logger.logLevel = logLevelOrFlag;
1376
+ }
1377
+
1378
+ /**
1379
+ * @license
1380
+ * @monterosa/sdk-launcher-kit
1381
+ *
1382
+ * Copyright © 2022-2026 Monterosa Productions Limited. All rights reserved.
1383
+ *
1384
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1385
+ */
1386
+ const ELEMENT_NAME = 'monterosa-experience';
1387
+ class MonterosaExperienceElement extends HTMLElement {
1388
+ constructor() {
1389
+ super(...arguments);
1390
+ this._experience = null;
1391
+ }
1392
+ /**
1393
+ * The host URL for the Experience.
1394
+ */
1395
+ get host() {
1396
+ return this.getAttribute('host') || '';
1397
+ }
1398
+ /**
1399
+ * The project identifier.
1400
+ */
1401
+ get projectId() {
1402
+ return this.getAttribute('projectId') || '';
1403
+ }
1404
+ /**
1405
+ * The event identifier (optional).
1406
+ */
1407
+ get eventId() {
1408
+ return this.getAttribute('eventId') || undefined;
1409
+ }
1410
+ async connectedCallback() {
1411
+ const host = this.getAttribute('host');
1412
+ if (host === null) {
1413
+ throw new Error('Host attribute is not set for Experience element');
1414
+ }
1415
+ const projectId = this.getAttribute('projectId');
1416
+ if (projectId === null) {
1417
+ throw new Error('Project attribute is not set for Experience element');
1418
+ }
1419
+ const autoresizesHeight = this.getAttribute('autoresizesHeight') !== null;
1420
+ const hidesHeadersAndFooters = this.getAttribute('hidesHeadersAndFooters') !== null;
1421
+ const eventId = this.getAttribute('eventId') !== null
1422
+ ? this.getAttribute('eventId')
1423
+ : undefined;
1424
+ const experienceUrl = this.getAttribute('experienceUrl') !== null
1425
+ ? this.getAttribute('experienceUrl')
1426
+ : undefined;
1427
+ const allow = this.getAttribute('allow') !== null
1428
+ ? this.getAttribute('allow')
1429
+ : undefined;
1430
+ const allowFullScreen = this.getAttribute('allowFullScreen') !== null;
1431
+ const parameters = {};
1432
+ for (let i = 0; i < this.attributes.length; i++) {
1433
+ const attr = this.attributes[i];
1434
+ if (attr.name.startsWith('param-')) {
1435
+ const paramName = attr.name.split('param-')[1];
1436
+ parameters[paramName] = attr.value;
1437
+ }
1438
+ }
1439
+ const title = this.getAttribute('title') !== null
1440
+ ? this.getAttribute('title')
1441
+ : undefined;
1442
+ const sdk = sdkCore.configure({
1443
+ host,
1444
+ projectId,
1445
+ }, `${host}-${projectId}`);
1446
+ const experience = getExperience(sdk, {
1447
+ autoresizesHeight,
1448
+ eventId,
1449
+ hidesHeadersAndFooters,
1450
+ experienceUrl,
1451
+ allow,
1452
+ allowFullScreen,
1453
+ parameters,
1454
+ title,
1455
+ });
1456
+ // Link the custom element to the experience
1457
+ experience.customElement = this;
1458
+ this._experience = experience;
1459
+ embed(experience, this);
1460
+ // eslint-disable-next-line
1461
+ onSdkMessage(experience, ({ payload, action }) => {
1462
+ switch (action) {
1463
+ case exports.Action.OnExperienceInitialised:
1464
+ break;
1465
+ case exports.Action.OnResize: {
1466
+ // const { width, height } = payload;
1467
+ break;
1468
+ }
1469
+ case exports.Action.OnReady:
1470
+ this.dispatchEvent(new CustomEvent('ready', {
1471
+ bubbles: true,
1472
+ cancelable: false,
1473
+ composed: true,
1474
+ }));
1475
+ break;
1476
+ }
1477
+ });
1478
+ }
1479
+ disconnectedCallback() {
1480
+ const experience = this._experience;
1481
+ this._experience = null;
1482
+ if (experience) {
1483
+ try {
1484
+ unembed(experience);
1485
+ }
1486
+ catch (_a) {
1487
+ // Experience may already have been unembedded
1488
+ }
1489
+ }
1490
+ }
1491
+ }
1492
+ if (!customElements.get(ELEMENT_NAME)) {
1493
+ customElements.define(ELEMENT_NAME, MonterosaExperienceElement);
1494
+ }
1495
+
1496
+ /**
1497
+ * @license
1498
+ * @monterosa/sdk-launcher-kit
1499
+ *
1500
+ * Copyright © 2025-2026 Monterosa Productions Limited. All rights reserved.
1501
+ *
1502
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1503
+ */
1504
+ const unsubs$1 = new Map();
1505
+ function handleExperienceEmbedded$1(experience) {
1506
+ if (!experience.config.autoresizesHeight) {
1507
+ return;
1508
+ }
1509
+ const integration = getIntegration(experience);
1510
+ if (!integration) {
1511
+ return;
1512
+ }
1513
+ const { container } = integration;
1514
+ const unsub = onSdkMessage(experience, ({ action, payload }) => {
1515
+ if (action === exports.Action.OnResize) {
1516
+ /**
1517
+ * Container width is maintained the same as it is defined in the parent
1518
+ * page to preserve its behaviour. Only the height is updated
1519
+ */
1520
+ // container.style.width = `${payload.width}px`;
1521
+ container.style.height = `${payload.height}px`;
1522
+ }
1523
+ });
1524
+ unsubs$1.set(experience.id, unsub);
1525
+ }
1526
+ function handleExperienceUnmounted$1(experience) {
1527
+ const unsub = unsubs$1.get(experience.id);
1528
+ if (unsub) {
1529
+ unsub();
1530
+ unsubs$1.delete(experience.id);
1531
+ }
1532
+ }
1533
+ onStateChanged((experience, state) => {
1534
+ if (state === 'mounted') {
1535
+ handleExperienceEmbedded$1(experience);
1536
+ }
1537
+ else if (state === 'unmounted') {
1538
+ handleExperienceUnmounted$1(experience);
1539
+ }
1540
+ });
1541
+
1542
+ /**
1543
+ * @license
1544
+ * @monterosa/sdk-launcher-kit
1545
+ *
1546
+ * Copyright © 2022 Monterosa Productions Limited. All rights reserved.
1547
+ *
1548
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1549
+ */
1550
+ /**
1551
+ * @internal
1552
+ */
1553
+ class ParentApplicationImpl {
1554
+ constructor(bridge) {
1555
+ this.bridge = bridge;
1556
+ }
1557
+ }
1558
+
1559
+ /**
1560
+ * @license
1561
+ * @monterosa/sdk-launcher-kit
1562
+ *
1563
+ * Copyright © 2023 Monterosa Productions Limited. All rights reserved.
1564
+ *
1565
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1566
+ */
1567
+ let parentApplication;
1568
+ /**
1569
+ * Returns instance of parent application.
1570
+ *
1571
+ * @returns Returns {@link ParentApplication}
1572
+ * if an Experience resides within the parent application, and it was embedded
1573
+ * using {@link embed} function. Otherwise it returns `null`.
1574
+ */
1575
+ function getParentApplication() {
1576
+ if (parentApplication !== undefined) {
1577
+ return parentApplication;
1578
+ }
1579
+ const parentBridge = getParentBridge();
1580
+ if (parentBridge === null) {
1581
+ return null;
1582
+ }
1583
+ parentApplication = new ParentApplicationImpl(parentBridge);
1584
+ return parentApplication;
1585
+ }
1586
+
1587
+ /**
1588
+ * @license
1589
+ * @monterosa/sdk-launcher-kit
1590
+ *
1591
+ * Copyright © 2022-2026 Monterosa Productions Limited. All rights reserved.
1592
+ *
1593
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1594
+ */
1595
+ function getUrlParam(param) {
1596
+ let queryString = {};
1597
+ if (typeof window !== 'undefined') {
1598
+ queryString = window.location.search;
1599
+ }
1600
+ const urlParams = new URLSearchParams(queryString);
1601
+ return urlParams.get(param);
1602
+ }
1603
+ /**
1604
+ * Returns whether the Experience should hide its header and footer.
1605
+ *
1606
+ * @remarks
1607
+ * The SDK on the parent application will by default request a child
1608
+ * Experience to hide its header and footer by setting a query parameter called
1609
+ * `micHideHeaderAndFooter` to `1`.
1610
+ *
1611
+ * When true, the developer of a child Experience is expected to hide it's headers
1612
+ * and footers as the parent application is actively providing them.
1613
+ *
1614
+ * You can test whether you are respecting this correctly by adding the following query
1615
+ * to your URL:
1616
+ *
1617
+ * "?micHideHeaderAndFooter=1"
1618
+ *
1619
+ * @returns Whether the header and footer views should be hidden.
1620
+ */
1621
+ function shouldHideHeaderAndFooter() {
1622
+ return getUrlParam(exports.QueryParam.HideHeaderAndFooter) === '1';
1623
+ }
1624
+ /**
1625
+ * This function will returns true if experience is embedded in autoresize height mode.
1626
+ */
1627
+ function isAutoresizesHeight() {
1628
+ return getUrlParam(exports.QueryParam.AutoresizesHeight) === '1';
1629
+ }
1630
+ /**
1631
+ * Notifies the parent application that the Experience has initialised and
1632
+ * is ready to receive messages. This triggers the `initialised` lifecycle state.
1633
+ *
1634
+ * Call this method when your Experience has completed its initial setup and
1635
+ * is ready to receive configuration or other messages from the parent application.
1636
+ *
1637
+ * @example
1638
+ * ```javascript
1639
+ * import { sendInitialised } from '@monterosa/sdk-launcher-kit';
1640
+ *
1641
+ * // After your Experience has initialised
1642
+ * sendInitialised();
1643
+ * ```
1644
+ */
1645
+ function sendInitialised() {
1646
+ const parentApp = getParentApplication();
1647
+ if (parentApp === null) {
1648
+ console.log('Unable to send initialised message, as there is no parent application');
1649
+ return;
1650
+ }
1651
+ sendSdkMessage(parentApp, exports.Action.OnExperienceInitialised);
1652
+ }
1653
+ /**
1654
+ * Notifies the parent application that the Experience UI is fully loaded
1655
+ * and ready to be displayed. This triggers the `ready` lifecycle state.
1656
+ *
1657
+ * @remarks
1658
+ * Call this method when your UI has completed loading and you are ready to
1659
+ * display data to the user. This can be when your network calls have successfully
1660
+ * requested data and you have updated the DOM, or when an error has occurred and
1661
+ * you want to take over the UI to provide details to the user.
1662
+ *
1663
+ * The SDK will use this message to dismiss the loading indicator, allowing a
1664
+ * seamless transition between a native loading UI and the fully loaded Experience.
1665
+ *
1666
+ * If this call is not made, the parent SDK will add a grace period to ensure
1667
+ * the web app has sufficient time to load, and eventually dismiss the loading
1668
+ * state to avoid infinite loading scenarios.
1669
+ *
1670
+ * @example
1671
+ * ```javascript
1672
+ * import { sendReady } from '@monterosa/sdk-launcher-kit';
1673
+ *
1674
+ * // After your UI has finished loading
1675
+ * sendReady();
1676
+ * ```
1677
+ */
1678
+ function sendReady() {
1679
+ const parentApp = getParentApplication();
1680
+ if (parentApp === null) {
1681
+ console.log('Unable to send ready message, as there is no parent application');
1682
+ return;
1683
+ }
1684
+ sendSdkMessage(parentApp, exports.Action.OnReady);
1685
+ }
1686
+ /**
1687
+ * @deprecated Use {@link sendReady} instead.
1688
+ *
1689
+ * Sends a message to the SDK of the parent application informing it that
1690
+ * the UI of this Experience has completed loading.
1691
+ */
1692
+ function sendFinishedLoadingUI() {
1693
+ console.warn('[launcher-kit] sendFinishedLoadingUI() is deprecated. Use sendReady() instead.');
1694
+ sendReady();
1695
+ }
1696
+ /**
1697
+ * Adds an observer for when more data is requested by the parent application
1698
+ *
1699
+ * @param callback - The callback that is triggered when a request for more data
1700
+ * is received
1701
+ * @returns The unsubscribe function. When it's called,
1702
+ * the observer will be removed and requests for data will no longer be received
1703
+ */
1704
+ function onMoreDataRequested(callback) {
1705
+ const parentApp = getParentApplication();
1706
+ if (parentApp === null) {
1707
+ console.log('Unable to subscribe to more data event, as there is no parent application');
1708
+ return () => { };
1709
+ }
1710
+ return onSdkMessage(parentApp, ({ action }) => {
1711
+ if (action === exports.Action.OnMoreDataRequested) {
1712
+ callback();
1713
+ }
1714
+ });
1715
+ }
1716
+ /**
1717
+ * Adds an observer for when experience is fully embedded and ready to accept
1718
+ * incoming messages
1719
+ *
1720
+ * @deprecated Use `onStateChanged(experience, (state) => {
1721
+ * if (state === 'initialised') ...
1722
+ * })` instead.
1723
+ *
1724
+ * @param experience - Experience instance
1725
+ * @param callback - The callback that is triggered when experience is embedded
1726
+ * @returns The unsubscribe function. When it's called, the observer will be
1727
+ * removed and ready event will not be received
1728
+ */
1729
+ function onReady(experience, callback) {
1730
+ console.warn('[launcher-kit] onReady() is deprecated. Use onStateChanged(' +
1731
+ "experience, (state) => { if (state === 'initialised') ... }) instead.");
1732
+ return onSdkMessage(experience, ({ action }) => {
1733
+ if (action === exports.Action.OnExperienceInitialised) {
1734
+ callback();
1735
+ }
1736
+ });
1737
+ }
1738
+ /**
1739
+ * @internal
1740
+ */
1741
+ const sendExperienceSizeThrottled = sdkUtil.throttle((width, height) => {
1742
+ const parentApp = getParentApplication();
1743
+ if (parentApp !== null) {
1744
+ sendSdkMessage(parentApp, exports.Action.OnResize, { width, height });
1745
+ }
1746
+ }, RESIZE_THROTTLE_TIMEOUT, {
1747
+ leading: true,
1748
+ trailing: true,
1749
+ });
1750
+ /**
1751
+ * Sends the Experience size to the parent page.
1752
+ *
1753
+ * @param width - The width of the Experience.
1754
+ * @param height - The height of the Experience.
1755
+ */
1756
+ function sendExperienceSize(width, height) {
1757
+ sendExperienceSizeThrottled(width, height);
1758
+ }
1759
+ /**
1760
+ * Sets up an observer to watch for the element dimensions change and
1761
+ * automatically reports their changes to the parent application.
1762
+ *
1763
+ * @param element - HTML element whose dimensions need to be watched
1764
+ * @returns The unsubscribe function. When it's called,
1765
+ * the observer will be removed and element dimensions are no longer tracked
1766
+ */
1767
+ function reportExperienceSizeChanges(element) {
1768
+ const observer = new ResizeObserver(() => {
1769
+ const width = Math.max(element.offsetWidth, element.scrollWidth);
1770
+ const height = Math.max(element.offsetHeight, element.scrollHeight);
1771
+ sendExperienceSize(width, height);
1772
+ });
1773
+ observer.observe(element);
1774
+ return () => observer.unobserve(element);
1775
+ }
1776
+
1777
+ /**
1778
+ * @license
1779
+ * share.ts
1780
+ * launcher-kit
1781
+ *
1782
+ * Copyright © 2026 Monterosa Productions Limited. All rights reserved.
1783
+ *
1784
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
1785
+ */
1786
+ /**
1787
+ * Share requests block on the native share tray which waits for user
1788
+ * interaction (composing a message, picking a target app, etc.). The default
1789
+ * bridge timeout of 20 seconds is too short for this. 5 minutes gives users
1790
+ * ample time while still acting as a safety net against lost messages.
1791
+ */
1792
+ const SHARE_REQUEST_TIMEOUT = 300000;
1793
+ exports.ShareError = void 0;
1794
+ (function (ShareError) {
1795
+ ShareError["ParentAppError"] = "parent_app_error";
1796
+ ShareError["ShareFailed"] = "share_failed";
1797
+ })(exports.ShareError || (exports.ShareError = {}));
1798
+ const ShareErrorMessages = {
1799
+ [exports.ShareError.ParentAppError]: (error) => `Parent application error: ${error}`,
1800
+ [exports.ShareError.ShareFailed]: (error) => `Share failed: ${error}`,
1801
+ };
1802
+ /**
1803
+ * Executes share using the Web Share API.
1804
+ *
1805
+ * @internal
1806
+ */
1807
+ async function executeShare(data) {
1808
+ try {
1809
+ await navigator.share({
1810
+ url: data.url,
1811
+ title: data.title,
1812
+ text: data.description,
1813
+ });
1814
+ return 'success';
1815
+ }
1816
+ catch (err) {
1817
+ if (err instanceof DOMException && err.name === 'AbortError') {
1818
+ return 'cancelled';
1819
+ }
1820
+ throw sdkUtil.createError(exports.ShareError.ShareFailed, ShareErrorMessages, sdkUtil.getErrorMessage(err));
1821
+ }
1822
+ }
1823
+ /**
1824
+ * Initiates a share action. When running inside a parent application,
1825
+ * the share request is sent to the parent via the communication bridge.
1826
+ * When running standalone, `navigator.share()` is called directly.
1827
+ *
1828
+ * @param data - The data to share
1829
+ */
1830
+ async function share(data) {
1831
+ const parentApp = getParentApplication();
1832
+ if (parentApp !== null) {
1833
+ const response = await sendSdkRequest(parentApp, exports.Action.OnShare, data, SHARE_REQUEST_TIMEOUT);
1834
+ if (response.payload.error !== undefined) {
1835
+ throw sdkUtil.createError(exports.ShareError.ParentAppError, ShareErrorMessages, response.payload.error);
1836
+ }
1837
+ // 'success' and 'cancelled' both resolve silently
1838
+ return;
1839
+ }
1840
+ await executeShare(data);
1841
+ }
1842
+ /**
1843
+ * Registers a callback to be called when a share request is received
1844
+ * from a child Experience.
1845
+ *
1846
+ * @param experience - The Experience instance to listen on
1847
+ * @param callback - Called with ShareData when a share request is received
1848
+ * @returns Unsubscribe function
1849
+ */
1850
+ function onShare(experience, callback) {
1851
+ return onSdkMessage(experience, (message) => {
1852
+ if (message.action === exports.Action.OnShare) {
1853
+ callback(message.payload);
1854
+ }
1855
+ });
1856
+ }
1857
+ const unsubs = new Map();
1858
+ function handleExperienceEmbedded(experience) {
1859
+ const unsub = onSdkMessage(experience, async (message) => {
1860
+ if (message.action !== exports.Action.OnShare) {
1861
+ return;
1862
+ }
1863
+ try {
1864
+ const parentApp = getParentApplication();
1865
+ let payload;
1866
+ if (parentApp !== null) {
1867
+ const response = await sendSdkRequest(parentApp, exports.Action.OnShare, message.payload, SHARE_REQUEST_TIMEOUT);
1868
+ payload = response.payload;
1869
+ }
1870
+ else {
1871
+ const result = await executeShare(message.payload);
1872
+ payload = {
1873
+ result,
1874
+ message: result === 'success' ? 'Share successful' : 'Share cancelled',
1875
+ data: {},
1876
+ };
1877
+ }
1878
+ respondToSdkMessage(experience, message, payload);
1879
+ }
1880
+ catch (err) {
1881
+ respondToSdkMessage(experience, message, {
1882
+ error: sdkUtil.getErrorMessage(err),
1883
+ });
1884
+ }
1885
+ });
1886
+ unsubs.set(experience.id, unsub);
1887
+ }
1888
+ function handleExperienceUnmounted(experience) {
1889
+ const unsub = unsubs.get(experience.id);
1890
+ if (unsub) {
1891
+ unsub();
1892
+ unsubs.delete(experience.id);
1893
+ }
1894
+ }
1895
+ onStateChanged((experience, state) => {
1896
+ if (state === 'mounted') {
1897
+ handleExperienceEmbedded(experience);
1898
+ }
1899
+ else if (state === 'unmounted') {
1900
+ handleExperienceUnmounted(experience);
1901
+ }
1902
+ });
1903
+
1904
+ exports.BRIDGE_VERSION = VERSION$1;
1905
+ exports.BridgeImpl = BridgeImpl;
1906
+ exports.ExperienceImpl = ExperienceImpl;
1907
+ exports.ParentApplicationImpl = ParentApplicationImpl;
1908
+ exports.ShareErrorMessages = ShareErrorMessages;
1909
+ exports.VERSION = VERSION;
1910
+ exports.embed = embed;
1911
+ exports.enableLogging = enableLogging;
1912
+ exports.executeShare = executeShare;
1913
+ exports.getBridge = getBridge;
1914
+ exports.getExperience = getExperience;
1915
+ exports.getParentApplication = getParentApplication;
1916
+ exports.getParentBridge = getParentBridge;
1917
+ exports.isAutoresizesHeight = isAutoresizesHeight;
1918
+ exports.isInsideIframe = isInsideIframe;
1919
+ exports.onMessage = onMessage;
1920
+ exports.onMoreDataRequested = onMoreDataRequested;
1921
+ exports.onReady = onReady;
1922
+ exports.onSdkMessage = onSdkMessage;
1923
+ exports.onShare = onShare;
1924
+ exports.onStateChanged = onStateChanged;
1925
+ exports.reportExperienceSizeChanges = reportExperienceSizeChanges;
1926
+ exports.requestMoreData = requestMoreData;
1927
+ exports.respondToMessage = respondToMessage;
1928
+ exports.respondToSdkMessage = respondToSdkMessage;
1929
+ exports.sendExperienceSize = sendExperienceSize;
1930
+ exports.sendExperienceSizeThrottled = sendExperienceSizeThrottled;
1931
+ exports.sendFinishedLoadingUI = sendFinishedLoadingUI;
1932
+ exports.sendInitialised = sendInitialised;
1933
+ exports.sendMessage = sendMessage;
1934
+ exports.sendReady = sendReady;
1935
+ exports.sendRequest = sendRequest;
1936
+ exports.sendSdkMessage = sendSdkMessage;
1937
+ exports.sendSdkRequest = sendSdkRequest;
1938
+ exports.setRequestTimeout = setRequestTimeout;
1939
+ exports.share = share;
1940
+ exports.shouldHideHeaderAndFooter = shouldHideHeaderAndFooter;
1941
+ exports.stateEmitter = stateEmitter;
1942
+ exports.unembed = unembed;
1943
+ exports.unmount = unmount;
1944
+ exports.updateExperienceState = updateExperienceState;
1945
+ //# sourceMappingURL=index.cjs.map