@liquidcommercedev/rmn-sdk 1.4.6-beta.3 → 1.4.6-beta.5
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 +351 -47
- package/dist/index.esm.js +351 -47
- package/dist/types/enums.d.ts +4 -0
- package/dist/types/modules/element/component/carousel/carousel.interface.d.ts +3 -3
- package/dist/types/modules/element/element.interface.d.ts +17 -9
- package/dist/types/modules/element/template/template.service.d.ts +4 -3
- package/dist/types/modules/event/event.interface.d.ts +67 -0
- package/dist/types/modules/event/event.service.d.ts +27 -2
- package/dist/types/modules/event/pubsub.d.ts +67 -0
- package/dist/types/modules/selection/selection.interface.d.ts +3 -2
- package/dist/types/modules/selection/selection.type.d.ts +3 -2
- package/dist/types/rmn-client.d.ts +28 -10
- package/dist/types/types.d.ts +7 -4
- package/package.json +1 -1
- package/umd/liquidcommerce-rmn-sdk.min.js +1 -1
package/dist/index.cjs
CHANGED
|
@@ -44,6 +44,7 @@ exports.RMN_SPOT_TYPE = void 0;
|
|
|
44
44
|
exports.RMN_FILTER_PROPERTIES = void 0;
|
|
45
45
|
(function (RMN_FILTER_PROPERTIES) {
|
|
46
46
|
RMN_FILTER_PROPERTIES["KEYWORDS"] = "keywords";
|
|
47
|
+
RMN_FILTER_PROPERTIES["PAGE_LOCATION"] = "pageLocation";
|
|
47
48
|
RMN_FILTER_PROPERTIES["PARENTCO"] = "parentCo";
|
|
48
49
|
RMN_FILTER_PROPERTIES["BRAND"] = "brand";
|
|
49
50
|
RMN_FILTER_PROPERTIES["CATEGORY"] = "category";
|
|
@@ -55,6 +56,9 @@ exports.RMN_FILTER_PROPERTIES = void 0;
|
|
|
55
56
|
})(exports.RMN_FILTER_PROPERTIES || (exports.RMN_FILTER_PROPERTIES = {}));
|
|
56
57
|
exports.RMN_SPOT_EVENT = void 0;
|
|
57
58
|
(function (RMN_SPOT_EVENT) {
|
|
59
|
+
RMN_SPOT_EVENT["MOUNTED"] = "MOUNTED";
|
|
60
|
+
RMN_SPOT_EVENT["UNMOUNTED"] = "UNMOUNTED";
|
|
61
|
+
RMN_SPOT_EVENT["RESIZED"] = "RESIZED";
|
|
58
62
|
RMN_SPOT_EVENT["IMPRESSION"] = "IMPRESSION";
|
|
59
63
|
RMN_SPOT_EVENT["CLICK"] = "CLICK";
|
|
60
64
|
RMN_SPOT_EVENT["PURCHASE"] = "PURCHASE";
|
|
@@ -15163,6 +15167,46 @@ const GFONT_CORMORANT = `
|
|
|
15163
15167
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300..700;1,300..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
|
|
15164
15168
|
`;
|
|
15165
15169
|
|
|
15170
|
+
class IntersectionObserverService {
|
|
15171
|
+
constructor(defaultOptions = {}) {
|
|
15172
|
+
this.observers = new Map();
|
|
15173
|
+
this.defaultOptions = {
|
|
15174
|
+
root: null,
|
|
15175
|
+
rootMargin: '0px',
|
|
15176
|
+
threshold: 0.5,
|
|
15177
|
+
...defaultOptions,
|
|
15178
|
+
};
|
|
15179
|
+
}
|
|
15180
|
+
observe(element, callback, options = {}) {
|
|
15181
|
+
const mergedOptions = { ...this.defaultOptions, ...options };
|
|
15182
|
+
const ioCallback = (entries) => {
|
|
15183
|
+
entries.forEach((entry) => {
|
|
15184
|
+
if (entry.isIntersecting) {
|
|
15185
|
+
callback(entry);
|
|
15186
|
+
}
|
|
15187
|
+
});
|
|
15188
|
+
};
|
|
15189
|
+
const observer = new IntersectionObserver(ioCallback, mergedOptions);
|
|
15190
|
+
this.observers.set(element, observer);
|
|
15191
|
+
observer.observe(element);
|
|
15192
|
+
}
|
|
15193
|
+
unobserve(element) {
|
|
15194
|
+
const observer = this.observers.get(element);
|
|
15195
|
+
if (observer) {
|
|
15196
|
+
observer.unobserve(element);
|
|
15197
|
+
observer.disconnect();
|
|
15198
|
+
this.observers.delete(element);
|
|
15199
|
+
}
|
|
15200
|
+
}
|
|
15201
|
+
unobserveAll() {
|
|
15202
|
+
this.observers.forEach((observer, element) => {
|
|
15203
|
+
observer.unobserve(element);
|
|
15204
|
+
observer.disconnect();
|
|
15205
|
+
});
|
|
15206
|
+
this.observers.clear();
|
|
15207
|
+
}
|
|
15208
|
+
}
|
|
15209
|
+
|
|
15166
15210
|
class ResizeObserverService {
|
|
15167
15211
|
constructor({ element, maxSize, minScale }) {
|
|
15168
15212
|
this.element = element;
|
|
@@ -15468,8 +15512,9 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined
|
|
|
15468
15512
|
this.addEventListener('spotSizeChanged', this.handleCarouselSizeChanged.bind(this));
|
|
15469
15513
|
}
|
|
15470
15514
|
}
|
|
15471
|
-
|
|
15472
|
-
|
|
15515
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
15516
|
+
handleCarouselSizeChanged(_event) {
|
|
15517
|
+
// console.info('Carousel Size Changed', event);
|
|
15473
15518
|
}
|
|
15474
15519
|
render() {
|
|
15475
15520
|
var _a;
|
|
@@ -15695,7 +15740,7 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined
|
|
|
15695
15740
|
* #########################################################
|
|
15696
15741
|
*/
|
|
15697
15742
|
handleSpotSizeChanged(event) {
|
|
15698
|
-
console.info('Spot Size Changed', event);
|
|
15743
|
+
// console.info('Spot Size Changed', event);
|
|
15699
15744
|
// Adjust text elements font size based on the scale factor
|
|
15700
15745
|
this.adjustFontSize(event.detail.scale);
|
|
15701
15746
|
}
|
|
@@ -15707,8 +15752,8 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined
|
|
|
15707
15752
|
elements === null || elements === void 0 ? void 0 : elements.forEach((element) => {
|
|
15708
15753
|
if (element instanceof HTMLElement) {
|
|
15709
15754
|
if (!this.originalFontSizes.has(element)) {
|
|
15710
|
-
const
|
|
15711
|
-
this.originalFontSizes.set(element,
|
|
15755
|
+
const originalSize = parseFloat(window.getComputedStyle(element).fontSize);
|
|
15756
|
+
this.originalFontSizes.set(element, originalSize);
|
|
15712
15757
|
}
|
|
15713
15758
|
const originalSize = this.originalFontSizes.get(element);
|
|
15714
15759
|
const newFontSize = originalSize * scaleFactor;
|
|
@@ -17539,11 +17584,12 @@ function rbSmallDiscoverToutTemplate(spot, config) {
|
|
|
17539
17584
|
}
|
|
17540
17585
|
|
|
17541
17586
|
/**
|
|
17542
|
-
*
|
|
17587
|
+
* Returns the HTML element for the given spot.
|
|
17543
17588
|
*
|
|
17544
|
-
* @param {ISpot} spot - The spot
|
|
17589
|
+
* @param {ISpot} spot - The spot object.
|
|
17590
|
+
* @param {ISpotTemplateConfig} config - The spot template configuration.
|
|
17545
17591
|
*
|
|
17546
|
-
* @return {
|
|
17592
|
+
* @return {HTMLElement | null} - The HTML element for the given spot or null if the spot template is not found.
|
|
17547
17593
|
*/
|
|
17548
17594
|
const SPOT_TEMPLATE_HTML_ELEMENT = (spot, config) => {
|
|
17549
17595
|
const templates = {
|
|
@@ -17616,6 +17662,228 @@ const SPOT_TEMPLATE_HTML_ELEMENT = (spot, config) => {
|
|
|
17616
17662
|
return spotHtmlStringToElement(spotHtmlString);
|
|
17617
17663
|
};
|
|
17618
17664
|
|
|
17665
|
+
/**
|
|
17666
|
+
* PubSub class
|
|
17667
|
+
* Manages event subscriptions and publications
|
|
17668
|
+
* @template IEventMap A record type defining the structure of events and their data
|
|
17669
|
+
*/
|
|
17670
|
+
class PubSub {
|
|
17671
|
+
constructor() {
|
|
17672
|
+
/**
|
|
17673
|
+
* Object to store subscribers for each event type
|
|
17674
|
+
*/
|
|
17675
|
+
this.subscribers = {};
|
|
17676
|
+
}
|
|
17677
|
+
/**
|
|
17678
|
+
* Subscribe to an event
|
|
17679
|
+
* @param eventType - The type of event to subscribe to
|
|
17680
|
+
* @param callback - The function to be called when the event is published
|
|
17681
|
+
* @returns A function to unsubscribe from the event
|
|
17682
|
+
*
|
|
17683
|
+
* @Example:
|
|
17684
|
+
* const unsubscribe = pubSub.subscribe('userLogin', (data) => {
|
|
17685
|
+
* console.log(`User ${data.username} logged in`);
|
|
17686
|
+
* });
|
|
17687
|
+
*/
|
|
17688
|
+
subscribe(eventType, callback) {
|
|
17689
|
+
if (!this.subscribers[eventType]) {
|
|
17690
|
+
this.subscribers[eventType] = [];
|
|
17691
|
+
}
|
|
17692
|
+
this.subscribers[eventType].push(callback);
|
|
17693
|
+
// Return an unsubscribe function
|
|
17694
|
+
return () => {
|
|
17695
|
+
this.subscribers[eventType] = this.subscribers[eventType].filter((cb) => cb !== callback);
|
|
17696
|
+
};
|
|
17697
|
+
}
|
|
17698
|
+
/**
|
|
17699
|
+
* Publish an event
|
|
17700
|
+
* @param eventType - The type of event to publish
|
|
17701
|
+
* @param data - The data to be passed to the event subscribers
|
|
17702
|
+
*
|
|
17703
|
+
* @Example:
|
|
17704
|
+
* pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
|
|
17705
|
+
*/
|
|
17706
|
+
publish(eventType, data) {
|
|
17707
|
+
if (!this.subscribers[eventType]) {
|
|
17708
|
+
return;
|
|
17709
|
+
}
|
|
17710
|
+
this.subscribers[eventType].forEach((callback) => callback(data));
|
|
17711
|
+
}
|
|
17712
|
+
}
|
|
17713
|
+
/**
|
|
17714
|
+
* Usage Example:
|
|
17715
|
+
*
|
|
17716
|
+
* interface IEventMap {
|
|
17717
|
+
* userLogin: { username: string; timestamp: number };
|
|
17718
|
+
* pageView: { url: string; timestamp: number };
|
|
17719
|
+
* }
|
|
17720
|
+
*
|
|
17721
|
+
* const pubSub = new PubSub<IEventMap>();
|
|
17722
|
+
*
|
|
17723
|
+
* // Subscribe to events
|
|
17724
|
+
* const unsubscribeLogin = pubSub.subscribe('userLogin', (data) => {
|
|
17725
|
+
* console.log(`User ${data.username} logged in at ${new Date(data.timestamp)}`);
|
|
17726
|
+
* });
|
|
17727
|
+
*
|
|
17728
|
+
* pubSub.subscribe('pageView', (data) => {
|
|
17729
|
+
* console.log(`Page ${data.url} viewed at ${new Date(data.timestamp)}`);
|
|
17730
|
+
* });
|
|
17731
|
+
*
|
|
17732
|
+
* // Publish events
|
|
17733
|
+
* pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
|
|
17734
|
+
* pubSub.publish('pageView', { url: '/home', timestamp: Date.now() });
|
|
17735
|
+
*
|
|
17736
|
+
* // Unsubscribe from an event
|
|
17737
|
+
* unsubscribeLogin();
|
|
17738
|
+
*/
|
|
17739
|
+
|
|
17740
|
+
class EventService {
|
|
17741
|
+
constructor() {
|
|
17742
|
+
this.pubSub = new PubSub();
|
|
17743
|
+
this.activeSpots = new Map();
|
|
17744
|
+
this.intersectionObserver = new IntersectionObserverService();
|
|
17745
|
+
}
|
|
17746
|
+
static getInstance() {
|
|
17747
|
+
if (!EventService.instance) {
|
|
17748
|
+
EventService.instance = new EventService();
|
|
17749
|
+
}
|
|
17750
|
+
return EventService.instance;
|
|
17751
|
+
}
|
|
17752
|
+
registerSpot({ placementId, element, spot }) {
|
|
17753
|
+
this.activeSpots.set(spot.id, {
|
|
17754
|
+
placementId,
|
|
17755
|
+
element,
|
|
17756
|
+
impressionTracked: false,
|
|
17757
|
+
});
|
|
17758
|
+
// Handle resize observer
|
|
17759
|
+
// this.handleResizeObserver(placementId, spot, element);
|
|
17760
|
+
// Handle intersection observer
|
|
17761
|
+
this.handleIntersectionObserver(placementId, spot, element);
|
|
17762
|
+
// Attach click event listener
|
|
17763
|
+
element.addEventListener('click', async () => {
|
|
17764
|
+
var _a, _b;
|
|
17765
|
+
this.pubSub.publish(exports.RMN_SPOT_EVENT.CLICK, {
|
|
17766
|
+
placementId,
|
|
17767
|
+
spotId: spot.id,
|
|
17768
|
+
element,
|
|
17769
|
+
});
|
|
17770
|
+
// Fire click event
|
|
17771
|
+
await this.fireEvent({
|
|
17772
|
+
event: exports.RMN_SPOT_EVENT.CLICK,
|
|
17773
|
+
eventUrl: (_b = (_a = spot.events.find((event) => event.event === exports.RMN_SPOT_EVENT.CLICK)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
|
|
17774
|
+
});
|
|
17775
|
+
});
|
|
17776
|
+
// Publish spot created event
|
|
17777
|
+
this.pubSub.publish(exports.RMN_SPOT_EVENT.MOUNTED, {
|
|
17778
|
+
placementId,
|
|
17779
|
+
spotId: spot.id,
|
|
17780
|
+
spotType: spot.spot,
|
|
17781
|
+
spotVariant: spot.variant,
|
|
17782
|
+
element,
|
|
17783
|
+
});
|
|
17784
|
+
}
|
|
17785
|
+
unregisterSpot(spotId) {
|
|
17786
|
+
const spotData = this.activeSpots.get(spotId);
|
|
17787
|
+
if (spotData) {
|
|
17788
|
+
this.intersectionObserver.unobserve(spotData.element);
|
|
17789
|
+
// this.resizeObserver?.disconnect();
|
|
17790
|
+
this.pubSub.publish(exports.RMN_SPOT_EVENT.UNMOUNTED, {
|
|
17791
|
+
placementId: spotData.placementId,
|
|
17792
|
+
spotId,
|
|
17793
|
+
});
|
|
17794
|
+
this.activeSpots.delete(spotId);
|
|
17795
|
+
}
|
|
17796
|
+
}
|
|
17797
|
+
// private handleResizeObserver(placementId: string, spot: ISpot, element: HTMLElement): void {
|
|
17798
|
+
// // this.resizeObserver = new ResizeObserverService({
|
|
17799
|
+
// // element,
|
|
17800
|
+
// // maxSize: {
|
|
17801
|
+
// // width: spot.width,
|
|
17802
|
+
// // height: spot.height,
|
|
17803
|
+
// // },
|
|
17804
|
+
// // minScale: 0.25,
|
|
17805
|
+
// // });
|
|
17806
|
+
//
|
|
17807
|
+
// const sizeChangedCb = (event: ISizeChangedEvent) => {
|
|
17808
|
+
// // Publish spot resized event
|
|
17809
|
+
// this.pubSub.publish(RMN_SPOT_EVENT.RESIZED, {
|
|
17810
|
+
// placementId,
|
|
17811
|
+
// spotId: spot.id,
|
|
17812
|
+
// scale: event.detail.scale,
|
|
17813
|
+
// previousDimensions: {
|
|
17814
|
+
// width: event.detail.width,
|
|
17815
|
+
// height: event.detail.height,
|
|
17816
|
+
// },
|
|
17817
|
+
// currentDimensions: {
|
|
17818
|
+
// width: event.detail.newWidth,
|
|
17819
|
+
// height: event.detail.newHeight,
|
|
17820
|
+
// },
|
|
17821
|
+
// });
|
|
17822
|
+
// };
|
|
17823
|
+
//
|
|
17824
|
+
// element.addEventListener('spotSizeChanged', sizeChangedCb as EventListener);
|
|
17825
|
+
// }
|
|
17826
|
+
handleIntersectionObserver(placementId, spot, element) {
|
|
17827
|
+
const spotIsVisibleCb = async () => {
|
|
17828
|
+
var _a, _b;
|
|
17829
|
+
this.pubSub.publish(exports.RMN_SPOT_EVENT.IMPRESSION, {
|
|
17830
|
+
placementId,
|
|
17831
|
+
spotId: spot.id,
|
|
17832
|
+
element,
|
|
17833
|
+
});
|
|
17834
|
+
this.intersectionObserver.unobserve(element);
|
|
17835
|
+
this.activeSpots.set(spot.id, {
|
|
17836
|
+
placementId,
|
|
17837
|
+
element,
|
|
17838
|
+
impressionTracked: true,
|
|
17839
|
+
});
|
|
17840
|
+
// Fire impression event
|
|
17841
|
+
await this.fireEvent({
|
|
17842
|
+
event: exports.RMN_SPOT_EVENT.IMPRESSION,
|
|
17843
|
+
eventUrl: (_b = (_a = spot.events.find((event) => event.event === exports.RMN_SPOT_EVENT.IMPRESSION)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
|
|
17844
|
+
});
|
|
17845
|
+
};
|
|
17846
|
+
this.intersectionObserver.observe(element, spotIsVisibleCb);
|
|
17847
|
+
}
|
|
17848
|
+
subscribe(eventType, callback) {
|
|
17849
|
+
return this.pubSub.subscribe(eventType, callback);
|
|
17850
|
+
}
|
|
17851
|
+
publish(eventType, data) {
|
|
17852
|
+
this.pubSub.publish(eventType, data);
|
|
17853
|
+
}
|
|
17854
|
+
/**
|
|
17855
|
+
* Fires an event using the navigator.sendBeacon method and redirects the user if the event is a click event.
|
|
17856
|
+
*
|
|
17857
|
+
* @param {IFireEventParams} params - The parameters for firing the event.
|
|
17858
|
+
* @param {RMN_SPOT_EVENT} params.event - The event type.
|
|
17859
|
+
* @param {string} params.eventUrl - The URL to which the event is sent.
|
|
17860
|
+
* @returns {Promise<void>} - A promise that resolves when the event is fired.
|
|
17861
|
+
*/
|
|
17862
|
+
async fireEvent({ event, eventUrl }) {
|
|
17863
|
+
const didFireEvent = navigator.sendBeacon(eventUrl);
|
|
17864
|
+
if (didFireEvent && event === exports.RMN_SPOT_EVENT.CLICK) {
|
|
17865
|
+
window.location.href = this.getRedirectUrlFromPayload(eventUrl);
|
|
17866
|
+
}
|
|
17867
|
+
}
|
|
17868
|
+
/**
|
|
17869
|
+
* Extracts and decodes a URL from a base64-encoded query parameter.
|
|
17870
|
+
*
|
|
17871
|
+
* @param {string} url - The URL containing the base64-encoded query parameter.
|
|
17872
|
+
* @returns {string} - The decoded URL or an empty string if decoding fails.
|
|
17873
|
+
*/
|
|
17874
|
+
getRedirectUrlFromPayload(url) {
|
|
17875
|
+
var _a, _b;
|
|
17876
|
+
const base64String = (_a = new URL(url).searchParams.get('e')) !== null && _a !== void 0 ? _a : '';
|
|
17877
|
+
try {
|
|
17878
|
+
const data = JSON.parse(atob(base64String));
|
|
17879
|
+
return (_b = data.ur) !== null && _b !== void 0 ? _b : '';
|
|
17880
|
+
}
|
|
17881
|
+
catch (_c) {
|
|
17882
|
+
return '';
|
|
17883
|
+
}
|
|
17884
|
+
}
|
|
17885
|
+
}
|
|
17886
|
+
|
|
17619
17887
|
const SELECTION_API_PATH = '/spots/selection';
|
|
17620
17888
|
|
|
17621
17889
|
class SelectionService extends BaseApi {
|
|
@@ -17650,46 +17918,39 @@ class LiquidCommerceRmnClient {
|
|
|
17650
17918
|
constructor(auth) {
|
|
17651
17919
|
this.selectionService = SelectionService.getInstance(auth);
|
|
17652
17920
|
this.elementService = ElementService.getInstance();
|
|
17921
|
+
this.eventService = EventService.getInstance();
|
|
17653
17922
|
}
|
|
17654
17923
|
/**
|
|
17655
17924
|
* Makes a selection request on our server based on the provided data.
|
|
17656
17925
|
*
|
|
17657
17926
|
* To create a spot html element, use the RmnCreateSpotElement function.
|
|
17658
17927
|
*
|
|
17659
|
-
* @param {ISpotSelectionParams}
|
|
17928
|
+
* @param {ISpotSelectionParams} params - Spots selection parameters.
|
|
17660
17929
|
*
|
|
17661
17930
|
* @return {Promise<ISpots>} - The spots response object.
|
|
17662
17931
|
*/
|
|
17663
|
-
async spotSelection(
|
|
17664
|
-
return this.selectionService.spotSelection(
|
|
17932
|
+
async spotSelection(params) {
|
|
17933
|
+
return this.selectionService.spotSelection(params);
|
|
17665
17934
|
}
|
|
17666
17935
|
/**
|
|
17667
17936
|
* Injects the spot elements into their provided placement.
|
|
17668
17937
|
*
|
|
17669
|
-
* @param {
|
|
17670
|
-
* @param {IInjectSpotElementConfig} config - The configuration object.
|
|
17938
|
+
* @param {IInjectSpotElementParams} params - Parameters for injecting spot elements.
|
|
17671
17939
|
*
|
|
17672
17940
|
* @return {Promise<void>} - A promise that resolves when the spot elements are injected.
|
|
17673
17941
|
*/
|
|
17674
|
-
async injectSpotElement(
|
|
17675
|
-
|
|
17676
|
-
|
|
17942
|
+
async injectSpotElement(params) {
|
|
17943
|
+
var _a;
|
|
17944
|
+
const { inject, config } = params;
|
|
17945
|
+
if (!inject.length) {
|
|
17946
|
+
console.warn('RmnSdk: Failed to inject spot element. Please provide at least one spot element to inject.');
|
|
17677
17947
|
return;
|
|
17678
17948
|
}
|
|
17679
|
-
|
|
17680
|
-
|
|
17681
|
-
|
|
17682
|
-
|
|
17683
|
-
|
|
17684
|
-
});
|
|
17685
|
-
});
|
|
17686
|
-
const response = await this.spotSelection({
|
|
17687
|
-
spots: spotSelectionRequest,
|
|
17688
|
-
url: config === null || config === void 0 ? void 0 : config.url,
|
|
17689
|
-
});
|
|
17690
|
-
const normalizedData = this.normalizeDataSpotType(data);
|
|
17691
|
-
for (const item of normalizedData) {
|
|
17692
|
-
const spots = response[item.spotType];
|
|
17949
|
+
this.preventDuplicateSpotPlacementIds(inject);
|
|
17950
|
+
const response = await this.spotSelectionRequest(params);
|
|
17951
|
+
for (const item of inject) {
|
|
17952
|
+
const itemConfig = (_a = item.config) !== null && _a !== void 0 ? _a : config;
|
|
17953
|
+
const spots = response[item.placementId];
|
|
17693
17954
|
if (!(spots === null || spots === void 0 ? void 0 : spots.length)) {
|
|
17694
17955
|
console.warn(`RmnSdk: Failed to inject spot element. No spots found for type "${item.spotType}".`);
|
|
17695
17956
|
continue;
|
|
@@ -17701,13 +17962,42 @@ class LiquidCommerceRmnClient {
|
|
|
17701
17962
|
continue;
|
|
17702
17963
|
}
|
|
17703
17964
|
if (spots.length === 1) {
|
|
17704
|
-
this.injectOneSpotElement(item, placement, spots[0],
|
|
17965
|
+
this.injectOneSpotElement(item, placement, spots[0], itemConfig);
|
|
17705
17966
|
}
|
|
17706
17967
|
if (spots.length > 1) {
|
|
17707
|
-
this.injectCarouselSpotElement(placement, spots,
|
|
17968
|
+
this.injectCarouselSpotElement(placement, spots, itemConfig);
|
|
17708
17969
|
}
|
|
17709
17970
|
}
|
|
17710
17971
|
}
|
|
17972
|
+
/**
|
|
17973
|
+
* Returns the event manager instance.
|
|
17974
|
+
*
|
|
17975
|
+
* @return {EventService} - The event manager instance.
|
|
17976
|
+
*/
|
|
17977
|
+
eventManager() {
|
|
17978
|
+
return this.eventService;
|
|
17979
|
+
}
|
|
17980
|
+
/**
|
|
17981
|
+
* Makes a selection request on our server based on the provided data.
|
|
17982
|
+
*
|
|
17983
|
+
* @param {IInjectSpotElementParams} params - Parameters for injecting spot elements.
|
|
17984
|
+
*
|
|
17985
|
+
* @return {Promise<ISpots>} - The spots response object.
|
|
17986
|
+
*/
|
|
17987
|
+
async spotSelectionRequest(params) {
|
|
17988
|
+
const { inject, filter, config } = params;
|
|
17989
|
+
const request = {
|
|
17990
|
+
url: config === null || config === void 0 ? void 0 : config.url,
|
|
17991
|
+
filter,
|
|
17992
|
+
spots: inject.map((item) => ({
|
|
17993
|
+
placementId: item.placementId,
|
|
17994
|
+
spot: item.spotType,
|
|
17995
|
+
count: item === null || item === void 0 ? void 0 : item.count,
|
|
17996
|
+
...item === null || item === void 0 ? void 0 : item.filter,
|
|
17997
|
+
})),
|
|
17998
|
+
};
|
|
17999
|
+
return this.spotSelection(request);
|
|
18000
|
+
}
|
|
17711
18001
|
/**
|
|
17712
18002
|
* Injects a carousel element with the provided spots into the placement.
|
|
17713
18003
|
*
|
|
@@ -17727,6 +18017,11 @@ class LiquidCommerceRmnClient {
|
|
|
17727
18017
|
console.warn(`RmnSdk: Failed to inject carousel spot element. Could not create element for type "${spot.spot}".`);
|
|
17728
18018
|
return;
|
|
17729
18019
|
}
|
|
18020
|
+
this.eventSpotElement({
|
|
18021
|
+
spot,
|
|
18022
|
+
placementId: placement.id,
|
|
18023
|
+
element: content,
|
|
18024
|
+
});
|
|
17730
18025
|
carouselSlides.push(content);
|
|
17731
18026
|
}
|
|
17732
18027
|
const { maxWidth, maxHeight } = spots.reduce((max, spot) => ({
|
|
@@ -17778,28 +18073,37 @@ class LiquidCommerceRmnClient {
|
|
|
17778
18073
|
console.warn(`RmnSdk: Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`);
|
|
17779
18074
|
return;
|
|
17780
18075
|
}
|
|
18076
|
+
this.eventSpotElement({
|
|
18077
|
+
spot,
|
|
18078
|
+
placementId: injectItem.placementId,
|
|
18079
|
+
element: spotElement,
|
|
18080
|
+
});
|
|
17781
18081
|
placement.replaceChildren(spotElement);
|
|
17782
18082
|
}
|
|
18083
|
+
eventSpotElement({ spot, placementId, element, }) {
|
|
18084
|
+
this.eventService.registerSpot({
|
|
18085
|
+
placementId,
|
|
18086
|
+
element,
|
|
18087
|
+
spot,
|
|
18088
|
+
});
|
|
18089
|
+
}
|
|
17783
18090
|
/**
|
|
17784
|
-
*
|
|
18091
|
+
* Prevents duplicate placement ids in the inject data.
|
|
18092
|
+
*
|
|
18093
|
+
* @param {IInjectSpotElement[]} inject - The inject data.
|
|
17785
18094
|
*
|
|
17786
|
-
* @
|
|
18095
|
+
* @throws {Error} - If a duplicate placement id is found.
|
|
17787
18096
|
*
|
|
17788
|
-
* @return {
|
|
18097
|
+
* @return {void}
|
|
17789
18098
|
*/
|
|
17790
|
-
|
|
17791
|
-
const
|
|
17792
|
-
|
|
17793
|
-
|
|
17794
|
-
|
|
17795
|
-
if (spotTypeCounts[spotType] === 1) {
|
|
17796
|
-
return spot;
|
|
18099
|
+
preventDuplicateSpotPlacementIds(inject) {
|
|
18100
|
+
const placementIds = new Set();
|
|
18101
|
+
for (const item of inject) {
|
|
18102
|
+
if (placementIds.has(item.placementId)) {
|
|
18103
|
+
throw new Error(`RmnSdk: Duplicate placement id (${item.placementId}) found. Please provide a unique placement id for each spot element.`);
|
|
17797
18104
|
}
|
|
17798
|
-
|
|
17799
|
-
|
|
17800
|
-
spotType: `${spotType}${spotTypeCounts[spotType]}`,
|
|
17801
|
-
};
|
|
17802
|
-
});
|
|
18105
|
+
placementIds.add(item.placementId);
|
|
18106
|
+
}
|
|
17803
18107
|
}
|
|
17804
18108
|
}
|
|
17805
18109
|
/**
|