@liquidcommercedev/rmn-sdk 1.4.6-beta.4 → 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 +301 -8
- package/dist/index.esm.js +301 -8
- package/dist/types/enums.d.ts +3 -0
- package/dist/types/modules/element/component/carousel/carousel.interface.d.ts +3 -3
- 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 +1 -0
- package/dist/types/rmn-client.d.ts +9 -0
- package/dist/types/types.d.ts +4 -1
- package/package.json +1 -1
- package/umd/liquidcommerce-rmn-sdk.min.js +1 -1
    
        package/dist/index.esm.js
    CHANGED
    
    | @@ -54,6 +54,9 @@ var RMN_FILTER_PROPERTIES; | |
| 54 54 | 
             
            })(RMN_FILTER_PROPERTIES || (RMN_FILTER_PROPERTIES = {}));
         | 
| 55 55 | 
             
            var RMN_SPOT_EVENT;
         | 
| 56 56 | 
             
            (function (RMN_SPOT_EVENT) {
         | 
| 57 | 
            +
                RMN_SPOT_EVENT["MOUNTED"] = "MOUNTED";
         | 
| 58 | 
            +
                RMN_SPOT_EVENT["UNMOUNTED"] = "UNMOUNTED";
         | 
| 59 | 
            +
                RMN_SPOT_EVENT["RESIZED"] = "RESIZED";
         | 
| 57 60 | 
             
                RMN_SPOT_EVENT["IMPRESSION"] = "IMPRESSION";
         | 
| 58 61 | 
             
                RMN_SPOT_EVENT["CLICK"] = "CLICK";
         | 
| 59 62 | 
             
                RMN_SPOT_EVENT["PURCHASE"] = "PURCHASE";
         | 
| @@ -15162,6 +15165,46 @@ const GFONT_CORMORANT = ` | |
| 15162 15165 | 
             
              <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">
         | 
| 15163 15166 | 
             
            `;
         | 
| 15164 15167 |  | 
| 15168 | 
            +
            class IntersectionObserverService {
         | 
| 15169 | 
            +
                constructor(defaultOptions = {}) {
         | 
| 15170 | 
            +
                    this.observers = new Map();
         | 
| 15171 | 
            +
                    this.defaultOptions = {
         | 
| 15172 | 
            +
                        root: null,
         | 
| 15173 | 
            +
                        rootMargin: '0px',
         | 
| 15174 | 
            +
                        threshold: 0.5,
         | 
| 15175 | 
            +
                        ...defaultOptions,
         | 
| 15176 | 
            +
                    };
         | 
| 15177 | 
            +
                }
         | 
| 15178 | 
            +
                observe(element, callback, options = {}) {
         | 
| 15179 | 
            +
                    const mergedOptions = { ...this.defaultOptions, ...options };
         | 
| 15180 | 
            +
                    const ioCallback = (entries) => {
         | 
| 15181 | 
            +
                        entries.forEach((entry) => {
         | 
| 15182 | 
            +
                            if (entry.isIntersecting) {
         | 
| 15183 | 
            +
                                callback(entry);
         | 
| 15184 | 
            +
                            }
         | 
| 15185 | 
            +
                        });
         | 
| 15186 | 
            +
                    };
         | 
| 15187 | 
            +
                    const observer = new IntersectionObserver(ioCallback, mergedOptions);
         | 
| 15188 | 
            +
                    this.observers.set(element, observer);
         | 
| 15189 | 
            +
                    observer.observe(element);
         | 
| 15190 | 
            +
                }
         | 
| 15191 | 
            +
                unobserve(element) {
         | 
| 15192 | 
            +
                    const observer = this.observers.get(element);
         | 
| 15193 | 
            +
                    if (observer) {
         | 
| 15194 | 
            +
                        observer.unobserve(element);
         | 
| 15195 | 
            +
                        observer.disconnect();
         | 
| 15196 | 
            +
                        this.observers.delete(element);
         | 
| 15197 | 
            +
                    }
         | 
| 15198 | 
            +
                }
         | 
| 15199 | 
            +
                unobserveAll() {
         | 
| 15200 | 
            +
                    this.observers.forEach((observer, element) => {
         | 
| 15201 | 
            +
                        observer.unobserve(element);
         | 
| 15202 | 
            +
                        observer.disconnect();
         | 
| 15203 | 
            +
                    });
         | 
| 15204 | 
            +
                    this.observers.clear();
         | 
| 15205 | 
            +
                }
         | 
| 15206 | 
            +
            }
         | 
| 15207 | 
            +
             | 
| 15165 15208 | 
             
            class ResizeObserverService {
         | 
| 15166 15209 | 
             
                constructor({ element, maxSize, minScale }) {
         | 
| 15167 15210 | 
             
                    this.element = element;
         | 
| @@ -15467,8 +15510,9 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined | |
| 15467 15510 | 
             
                            this.addEventListener('spotSizeChanged', this.handleCarouselSizeChanged.bind(this));
         | 
| 15468 15511 | 
             
                        }
         | 
| 15469 15512 | 
             
                    }
         | 
| 15470 | 
            -
                     | 
| 15471 | 
            -
             | 
| 15513 | 
            +
                    // eslint-disable-next-line @typescript-eslint/no-unused-vars
         | 
| 15514 | 
            +
                    handleCarouselSizeChanged(_event) {
         | 
| 15515 | 
            +
                        // console.info('Carousel Size Changed', event);
         | 
| 15472 15516 | 
             
                    }
         | 
| 15473 15517 | 
             
                    render() {
         | 
| 15474 15518 | 
             
                        var _a;
         | 
| @@ -15694,7 +15738,7 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined | |
| 15694 15738 | 
             
                     * #########################################################
         | 
| 15695 15739 | 
             
                     */
         | 
| 15696 15740 | 
             
                    handleSpotSizeChanged(event) {
         | 
| 15697 | 
            -
                        console.info('Spot Size Changed', event);
         | 
| 15741 | 
            +
                        // console.info('Spot Size Changed', event);
         | 
| 15698 15742 | 
             
                        // Adjust text elements font size based on the scale factor
         | 
| 15699 15743 | 
             
                        this.adjustFontSize(event.detail.scale);
         | 
| 15700 15744 | 
             
                    }
         | 
| @@ -15706,8 +15750,8 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined | |
| 15706 15750 | 
             
                        elements === null || elements === void 0 ? void 0 : elements.forEach((element) => {
         | 
| 15707 15751 | 
             
                            if (element instanceof HTMLElement) {
         | 
| 15708 15752 | 
             
                                if (!this.originalFontSizes.has(element)) {
         | 
| 15709 | 
            -
                                    const  | 
| 15710 | 
            -
                                    this.originalFontSizes.set(element,  | 
| 15753 | 
            +
                                    const originalSize = parseFloat(window.getComputedStyle(element).fontSize);
         | 
| 15754 | 
            +
                                    this.originalFontSizes.set(element, originalSize);
         | 
| 15711 15755 | 
             
                                }
         | 
| 15712 15756 | 
             
                                const originalSize = this.originalFontSizes.get(element);
         | 
| 15713 15757 | 
             
                                const newFontSize = originalSize * scaleFactor;
         | 
| @@ -17538,11 +17582,12 @@ function rbSmallDiscoverToutTemplate(spot, config) { | |
| 17538 17582 | 
             
            }
         | 
| 17539 17583 |  | 
| 17540 17584 | 
             
            /**
         | 
| 17541 | 
            -
             *  | 
| 17585 | 
            +
             * Returns the HTML element for the given spot.
         | 
| 17542 17586 | 
             
             *
         | 
| 17543 | 
            -
             * @param {ISpot} spot - The spot  | 
| 17587 | 
            +
             * @param {ISpot} spot - The spot object.
         | 
| 17588 | 
            +
             * @param {ISpotTemplateConfig} config - The spot template configuration.
         | 
| 17544 17589 | 
             
             *
         | 
| 17545 | 
            -
             * @return { | 
| 17590 | 
            +
             * @return {HTMLElement | null} - The HTML element for the given spot or null if the spot template is not found.
         | 
| 17546 17591 | 
             
             */
         | 
| 17547 17592 | 
             
            const SPOT_TEMPLATE_HTML_ELEMENT = (spot, config) => {
         | 
| 17548 17593 | 
             
                const templates = {
         | 
| @@ -17615,6 +17660,228 @@ const SPOT_TEMPLATE_HTML_ELEMENT = (spot, config) => { | |
| 17615 17660 | 
             
                return spotHtmlStringToElement(spotHtmlString);
         | 
| 17616 17661 | 
             
            };
         | 
| 17617 17662 |  | 
| 17663 | 
            +
            /**
         | 
| 17664 | 
            +
             * PubSub class
         | 
| 17665 | 
            +
             * Manages event subscriptions and publications
         | 
| 17666 | 
            +
             * @template IEventMap A record type defining the structure of events and their data
         | 
| 17667 | 
            +
             */
         | 
| 17668 | 
            +
            class PubSub {
         | 
| 17669 | 
            +
                constructor() {
         | 
| 17670 | 
            +
                    /**
         | 
| 17671 | 
            +
                     * Object to store subscribers for each event type
         | 
| 17672 | 
            +
                     */
         | 
| 17673 | 
            +
                    this.subscribers = {};
         | 
| 17674 | 
            +
                }
         | 
| 17675 | 
            +
                /**
         | 
| 17676 | 
            +
                 * Subscribe to an event
         | 
| 17677 | 
            +
                 * @param eventType - The type of event to subscribe to
         | 
| 17678 | 
            +
                 * @param callback - The function to be called when the event is published
         | 
| 17679 | 
            +
                 * @returns A function to unsubscribe from the event
         | 
| 17680 | 
            +
                 *
         | 
| 17681 | 
            +
                 * @Example:
         | 
| 17682 | 
            +
                 * const unsubscribe = pubSub.subscribe('userLogin', (data) => {
         | 
| 17683 | 
            +
                 *   console.log(`User ${data.username} logged in`);
         | 
| 17684 | 
            +
                 * });
         | 
| 17685 | 
            +
                 */
         | 
| 17686 | 
            +
                subscribe(eventType, callback) {
         | 
| 17687 | 
            +
                    if (!this.subscribers[eventType]) {
         | 
| 17688 | 
            +
                        this.subscribers[eventType] = [];
         | 
| 17689 | 
            +
                    }
         | 
| 17690 | 
            +
                    this.subscribers[eventType].push(callback);
         | 
| 17691 | 
            +
                    // Return an unsubscribe function
         | 
| 17692 | 
            +
                    return () => {
         | 
| 17693 | 
            +
                        this.subscribers[eventType] = this.subscribers[eventType].filter((cb) => cb !== callback);
         | 
| 17694 | 
            +
                    };
         | 
| 17695 | 
            +
                }
         | 
| 17696 | 
            +
                /**
         | 
| 17697 | 
            +
                 * Publish an event
         | 
| 17698 | 
            +
                 * @param eventType - The type of event to publish
         | 
| 17699 | 
            +
                 * @param data - The data to be passed to the event subscribers
         | 
| 17700 | 
            +
                 *
         | 
| 17701 | 
            +
                 * @Example:
         | 
| 17702 | 
            +
                 * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
         | 
| 17703 | 
            +
                 */
         | 
| 17704 | 
            +
                publish(eventType, data) {
         | 
| 17705 | 
            +
                    if (!this.subscribers[eventType]) {
         | 
| 17706 | 
            +
                        return;
         | 
| 17707 | 
            +
                    }
         | 
| 17708 | 
            +
                    this.subscribers[eventType].forEach((callback) => callback(data));
         | 
| 17709 | 
            +
                }
         | 
| 17710 | 
            +
            }
         | 
| 17711 | 
            +
            /**
         | 
| 17712 | 
            +
             * Usage Example:
         | 
| 17713 | 
            +
             *
         | 
| 17714 | 
            +
             * interface IEventMap {
         | 
| 17715 | 
            +
             *   userLogin: { username: string; timestamp: number };
         | 
| 17716 | 
            +
             *   pageView: { url: string; timestamp: number };
         | 
| 17717 | 
            +
             * }
         | 
| 17718 | 
            +
             *
         | 
| 17719 | 
            +
             * const pubSub = new PubSub<IEventMap>();
         | 
| 17720 | 
            +
             *
         | 
| 17721 | 
            +
             * // Subscribe to events
         | 
| 17722 | 
            +
             * const unsubscribeLogin = pubSub.subscribe('userLogin', (data) => {
         | 
| 17723 | 
            +
             *   console.log(`User ${data.username} logged in at ${new Date(data.timestamp)}`);
         | 
| 17724 | 
            +
             * });
         | 
| 17725 | 
            +
             *
         | 
| 17726 | 
            +
             * pubSub.subscribe('pageView', (data) => {
         | 
| 17727 | 
            +
             *   console.log(`Page ${data.url} viewed at ${new Date(data.timestamp)}`);
         | 
| 17728 | 
            +
             * });
         | 
| 17729 | 
            +
             *
         | 
| 17730 | 
            +
             * // Publish events
         | 
| 17731 | 
            +
             * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
         | 
| 17732 | 
            +
             * pubSub.publish('pageView', { url: '/home', timestamp: Date.now() });
         | 
| 17733 | 
            +
             *
         | 
| 17734 | 
            +
             * // Unsubscribe from an event
         | 
| 17735 | 
            +
             * unsubscribeLogin();
         | 
| 17736 | 
            +
             */
         | 
| 17737 | 
            +
             | 
| 17738 | 
            +
            class EventService {
         | 
| 17739 | 
            +
                constructor() {
         | 
| 17740 | 
            +
                    this.pubSub = new PubSub();
         | 
| 17741 | 
            +
                    this.activeSpots = new Map();
         | 
| 17742 | 
            +
                    this.intersectionObserver = new IntersectionObserverService();
         | 
| 17743 | 
            +
                }
         | 
| 17744 | 
            +
                static getInstance() {
         | 
| 17745 | 
            +
                    if (!EventService.instance) {
         | 
| 17746 | 
            +
                        EventService.instance = new EventService();
         | 
| 17747 | 
            +
                    }
         | 
| 17748 | 
            +
                    return EventService.instance;
         | 
| 17749 | 
            +
                }
         | 
| 17750 | 
            +
                registerSpot({ placementId, element, spot }) {
         | 
| 17751 | 
            +
                    this.activeSpots.set(spot.id, {
         | 
| 17752 | 
            +
                        placementId,
         | 
| 17753 | 
            +
                        element,
         | 
| 17754 | 
            +
                        impressionTracked: false,
         | 
| 17755 | 
            +
                    });
         | 
| 17756 | 
            +
                    // Handle resize observer
         | 
| 17757 | 
            +
                    // this.handleResizeObserver(placementId, spot, element);
         | 
| 17758 | 
            +
                    // Handle intersection observer
         | 
| 17759 | 
            +
                    this.handleIntersectionObserver(placementId, spot, element);
         | 
| 17760 | 
            +
                    // Attach click event listener
         | 
| 17761 | 
            +
                    element.addEventListener('click', async () => {
         | 
| 17762 | 
            +
                        var _a, _b;
         | 
| 17763 | 
            +
                        this.pubSub.publish(RMN_SPOT_EVENT.CLICK, {
         | 
| 17764 | 
            +
                            placementId,
         | 
| 17765 | 
            +
                            spotId: spot.id,
         | 
| 17766 | 
            +
                            element,
         | 
| 17767 | 
            +
                        });
         | 
| 17768 | 
            +
                        // Fire click event
         | 
| 17769 | 
            +
                        await this.fireEvent({
         | 
| 17770 | 
            +
                            event: RMN_SPOT_EVENT.CLICK,
         | 
| 17771 | 
            +
                            eventUrl: (_b = (_a = spot.events.find((event) => event.event === RMN_SPOT_EVENT.CLICK)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
         | 
| 17772 | 
            +
                        });
         | 
| 17773 | 
            +
                    });
         | 
| 17774 | 
            +
                    // Publish spot created event
         | 
| 17775 | 
            +
                    this.pubSub.publish(RMN_SPOT_EVENT.MOUNTED, {
         | 
| 17776 | 
            +
                        placementId,
         | 
| 17777 | 
            +
                        spotId: spot.id,
         | 
| 17778 | 
            +
                        spotType: spot.spot,
         | 
| 17779 | 
            +
                        spotVariant: spot.variant,
         | 
| 17780 | 
            +
                        element,
         | 
| 17781 | 
            +
                    });
         | 
| 17782 | 
            +
                }
         | 
| 17783 | 
            +
                unregisterSpot(spotId) {
         | 
| 17784 | 
            +
                    const spotData = this.activeSpots.get(spotId);
         | 
| 17785 | 
            +
                    if (spotData) {
         | 
| 17786 | 
            +
                        this.intersectionObserver.unobserve(spotData.element);
         | 
| 17787 | 
            +
                        // this.resizeObserver?.disconnect();
         | 
| 17788 | 
            +
                        this.pubSub.publish(RMN_SPOT_EVENT.UNMOUNTED, {
         | 
| 17789 | 
            +
                            placementId: spotData.placementId,
         | 
| 17790 | 
            +
                            spotId,
         | 
| 17791 | 
            +
                        });
         | 
| 17792 | 
            +
                        this.activeSpots.delete(spotId);
         | 
| 17793 | 
            +
                    }
         | 
| 17794 | 
            +
                }
         | 
| 17795 | 
            +
                // private handleResizeObserver(placementId: string, spot: ISpot, element: HTMLElement): void {
         | 
| 17796 | 
            +
                //   // this.resizeObserver = new ResizeObserverService({
         | 
| 17797 | 
            +
                //   //   element,
         | 
| 17798 | 
            +
                //   //   maxSize: {
         | 
| 17799 | 
            +
                //   //     width: spot.width,
         | 
| 17800 | 
            +
                //   //     height: spot.height,
         | 
| 17801 | 
            +
                //   //   },
         | 
| 17802 | 
            +
                //   //   minScale: 0.25,
         | 
| 17803 | 
            +
                //   // });
         | 
| 17804 | 
            +
                //
         | 
| 17805 | 
            +
                //   const sizeChangedCb = (event: ISizeChangedEvent) => {
         | 
| 17806 | 
            +
                //     // Publish spot resized event
         | 
| 17807 | 
            +
                //     this.pubSub.publish(RMN_SPOT_EVENT.RESIZED, {
         | 
| 17808 | 
            +
                //       placementId,
         | 
| 17809 | 
            +
                //       spotId: spot.id,
         | 
| 17810 | 
            +
                //       scale: event.detail.scale,
         | 
| 17811 | 
            +
                //       previousDimensions: {
         | 
| 17812 | 
            +
                //         width: event.detail.width,
         | 
| 17813 | 
            +
                //         height: event.detail.height,
         | 
| 17814 | 
            +
                //       },
         | 
| 17815 | 
            +
                //       currentDimensions: {
         | 
| 17816 | 
            +
                //         width: event.detail.newWidth,
         | 
| 17817 | 
            +
                //         height: event.detail.newHeight,
         | 
| 17818 | 
            +
                //       },
         | 
| 17819 | 
            +
                //     });
         | 
| 17820 | 
            +
                //   };
         | 
| 17821 | 
            +
                //
         | 
| 17822 | 
            +
                //   element.addEventListener('spotSizeChanged', sizeChangedCb as EventListener);
         | 
| 17823 | 
            +
                // }
         | 
| 17824 | 
            +
                handleIntersectionObserver(placementId, spot, element) {
         | 
| 17825 | 
            +
                    const spotIsVisibleCb = async () => {
         | 
| 17826 | 
            +
                        var _a, _b;
         | 
| 17827 | 
            +
                        this.pubSub.publish(RMN_SPOT_EVENT.IMPRESSION, {
         | 
| 17828 | 
            +
                            placementId,
         | 
| 17829 | 
            +
                            spotId: spot.id,
         | 
| 17830 | 
            +
                            element,
         | 
| 17831 | 
            +
                        });
         | 
| 17832 | 
            +
                        this.intersectionObserver.unobserve(element);
         | 
| 17833 | 
            +
                        this.activeSpots.set(spot.id, {
         | 
| 17834 | 
            +
                            placementId,
         | 
| 17835 | 
            +
                            element,
         | 
| 17836 | 
            +
                            impressionTracked: true,
         | 
| 17837 | 
            +
                        });
         | 
| 17838 | 
            +
                        // Fire impression event
         | 
| 17839 | 
            +
                        await this.fireEvent({
         | 
| 17840 | 
            +
                            event: RMN_SPOT_EVENT.IMPRESSION,
         | 
| 17841 | 
            +
                            eventUrl: (_b = (_a = spot.events.find((event) => event.event === RMN_SPOT_EVENT.IMPRESSION)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
         | 
| 17842 | 
            +
                        });
         | 
| 17843 | 
            +
                    };
         | 
| 17844 | 
            +
                    this.intersectionObserver.observe(element, spotIsVisibleCb);
         | 
| 17845 | 
            +
                }
         | 
| 17846 | 
            +
                subscribe(eventType, callback) {
         | 
| 17847 | 
            +
                    return this.pubSub.subscribe(eventType, callback);
         | 
| 17848 | 
            +
                }
         | 
| 17849 | 
            +
                publish(eventType, data) {
         | 
| 17850 | 
            +
                    this.pubSub.publish(eventType, data);
         | 
| 17851 | 
            +
                }
         | 
| 17852 | 
            +
                /**
         | 
| 17853 | 
            +
                 * Fires an event using the navigator.sendBeacon method and redirects the user if the event is a click event.
         | 
| 17854 | 
            +
                 *
         | 
| 17855 | 
            +
                 * @param {IFireEventParams} params - The parameters for firing the event.
         | 
| 17856 | 
            +
                 * @param {RMN_SPOT_EVENT} params.event - The event type.
         | 
| 17857 | 
            +
                 * @param {string} params.eventUrl - The URL to which the event is sent.
         | 
| 17858 | 
            +
                 * @returns {Promise<void>} - A promise that resolves when the event is fired.
         | 
| 17859 | 
            +
                 */
         | 
| 17860 | 
            +
                async fireEvent({ event, eventUrl }) {
         | 
| 17861 | 
            +
                    const didFireEvent = navigator.sendBeacon(eventUrl);
         | 
| 17862 | 
            +
                    if (didFireEvent && event === RMN_SPOT_EVENT.CLICK) {
         | 
| 17863 | 
            +
                        window.location.href = this.getRedirectUrlFromPayload(eventUrl);
         | 
| 17864 | 
            +
                    }
         | 
| 17865 | 
            +
                }
         | 
| 17866 | 
            +
                /**
         | 
| 17867 | 
            +
                 * Extracts and decodes a URL from a base64-encoded query parameter.
         | 
| 17868 | 
            +
                 *
         | 
| 17869 | 
            +
                 * @param {string} url - The URL containing the base64-encoded query parameter.
         | 
| 17870 | 
            +
                 * @returns {string} - The decoded URL or an empty string if decoding fails.
         | 
| 17871 | 
            +
                 */
         | 
| 17872 | 
            +
                getRedirectUrlFromPayload(url) {
         | 
| 17873 | 
            +
                    var _a, _b;
         | 
| 17874 | 
            +
                    const base64String = (_a = new URL(url).searchParams.get('e')) !== null && _a !== void 0 ? _a : '';
         | 
| 17875 | 
            +
                    try {
         | 
| 17876 | 
            +
                        const data = JSON.parse(atob(base64String));
         | 
| 17877 | 
            +
                        return (_b = data.ur) !== null && _b !== void 0 ? _b : '';
         | 
| 17878 | 
            +
                    }
         | 
| 17879 | 
            +
                    catch (_c) {
         | 
| 17880 | 
            +
                        return '';
         | 
| 17881 | 
            +
                    }
         | 
| 17882 | 
            +
                }
         | 
| 17883 | 
            +
            }
         | 
| 17884 | 
            +
             | 
| 17618 17885 | 
             
            const SELECTION_API_PATH = '/spots/selection';
         | 
| 17619 17886 |  | 
| 17620 17887 | 
             
            class SelectionService extends BaseApi {
         | 
| @@ -17649,6 +17916,7 @@ class LiquidCommerceRmnClient { | |
| 17649 17916 | 
             
                constructor(auth) {
         | 
| 17650 17917 | 
             
                    this.selectionService = SelectionService.getInstance(auth);
         | 
| 17651 17918 | 
             
                    this.elementService = ElementService.getInstance();
         | 
| 17919 | 
            +
                    this.eventService = EventService.getInstance();
         | 
| 17652 17920 | 
             
                }
         | 
| 17653 17921 | 
             
                /**
         | 
| 17654 17922 | 
             
                 * Makes a selection request on our server based on the provided data.
         | 
| @@ -17699,6 +17967,14 @@ class LiquidCommerceRmnClient { | |
| 17699 17967 | 
             
                        }
         | 
| 17700 17968 | 
             
                    }
         | 
| 17701 17969 | 
             
                }
         | 
| 17970 | 
            +
                /**
         | 
| 17971 | 
            +
                 * Returns the event manager instance.
         | 
| 17972 | 
            +
                 *
         | 
| 17973 | 
            +
                 * @return {EventService} - The event manager instance.
         | 
| 17974 | 
            +
                 */
         | 
| 17975 | 
            +
                eventManager() {
         | 
| 17976 | 
            +
                    return this.eventService;
         | 
| 17977 | 
            +
                }
         | 
| 17702 17978 | 
             
                /**
         | 
| 17703 17979 | 
             
                 * Makes a selection request on our server based on the provided data.
         | 
| 17704 17980 | 
             
                 *
         | 
| @@ -17739,6 +18015,11 @@ class LiquidCommerceRmnClient { | |
| 17739 18015 | 
             
                            console.warn(`RmnSdk: Failed to inject carousel spot element. Could not create element for type "${spot.spot}".`);
         | 
| 17740 18016 | 
             
                            return;
         | 
| 17741 18017 | 
             
                        }
         | 
| 18018 | 
            +
                        this.eventSpotElement({
         | 
| 18019 | 
            +
                            spot,
         | 
| 18020 | 
            +
                            placementId: placement.id,
         | 
| 18021 | 
            +
                            element: content,
         | 
| 18022 | 
            +
                        });
         | 
| 17742 18023 | 
             
                        carouselSlides.push(content);
         | 
| 17743 18024 | 
             
                    }
         | 
| 17744 18025 | 
             
                    const { maxWidth, maxHeight } = spots.reduce((max, spot) => ({
         | 
| @@ -17790,8 +18071,20 @@ class LiquidCommerceRmnClient { | |
| 17790 18071 | 
             
                        console.warn(`RmnSdk: Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`);
         | 
| 17791 18072 | 
             
                        return;
         | 
| 17792 18073 | 
             
                    }
         | 
| 18074 | 
            +
                    this.eventSpotElement({
         | 
| 18075 | 
            +
                        spot,
         | 
| 18076 | 
            +
                        placementId: injectItem.placementId,
         | 
| 18077 | 
            +
                        element: spotElement,
         | 
| 18078 | 
            +
                    });
         | 
| 17793 18079 | 
             
                    placement.replaceChildren(spotElement);
         | 
| 17794 18080 | 
             
                }
         | 
| 18081 | 
            +
                eventSpotElement({ spot, placementId, element, }) {
         | 
| 18082 | 
            +
                    this.eventService.registerSpot({
         | 
| 18083 | 
            +
                        placementId,
         | 
| 18084 | 
            +
                        element,
         | 
| 18085 | 
            +
                        spot,
         | 
| 18086 | 
            +
                    });
         | 
| 18087 | 
            +
                }
         | 
| 17795 18088 | 
             
                /**
         | 
| 17796 18089 | 
             
                 * Prevents duplicate placement ids in the inject data.
         | 
| 17797 18090 | 
             
                 *
         | 
    
        package/dist/types/enums.d.ts
    CHANGED
    
    | @@ -49,6 +49,9 @@ export declare enum RMN_FILTER_PROPERTIES { | |
| 49 49 | 
             
                SECTION = "section"
         | 
| 50 50 | 
             
            }
         | 
| 51 51 | 
             
            export declare enum RMN_SPOT_EVENT {
         | 
| 52 | 
            +
                MOUNTED = "MOUNTED",
         | 
| 53 | 
            +
                UNMOUNTED = "UNMOUNTED",
         | 
| 54 | 
            +
                RESIZED = "RESIZED",
         | 
| 52 55 | 
             
                IMPRESSION = "IMPRESSION",
         | 
| 53 56 | 
             
                CLICK = "CLICK",
         | 
| 54 57 | 
             
                PURCHASE = "PURCHASE",
         | 
| @@ -1,12 +1,12 @@ | |
| 1 1 | 
             
            import type { ICreateElementConfig } from 'modules/element';
         | 
| 2 | 
            -
            export type  | 
| 2 | 
            +
            export type CarouselNavPositionType = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right' | 'middle-left' | 'middle-right' | 'middle-sides';
         | 
| 3 3 | 
             
            export interface ICarouselDotOptions {
         | 
| 4 | 
            -
                position:  | 
| 4 | 
            +
                position: CarouselNavPositionType;
         | 
| 5 5 | 
             
                color: string;
         | 
| 6 6 | 
             
                activeColor: string;
         | 
| 7 7 | 
             
            }
         | 
| 8 8 | 
             
            export interface ICarouselButtonOptions {
         | 
| 9 | 
            -
                position:  | 
| 9 | 
            +
                position: CarouselNavPositionType;
         | 
| 10 10 | 
             
                together: boolean;
         | 
| 11 11 | 
             
                textColor: string;
         | 
| 12 12 | 
             
                backgroundColor: string;
         | 
| @@ -1,10 +1,11 @@ | |
| 1 1 | 
             
            import type { ISpot } from 'types';
         | 
| 2 2 | 
             
            import type { ISpotTemplateConfig } from './template.type';
         | 
| 3 3 | 
             
            /**
         | 
| 4 | 
            -
             *  | 
| 4 | 
            +
             * Returns the HTML element for the given spot.
         | 
| 5 5 | 
             
             *
         | 
| 6 | 
            -
             * @param {ISpot} spot - The spot  | 
| 6 | 
            +
             * @param {ISpot} spot - The spot object.
         | 
| 7 | 
            +
             * @param {ISpotTemplateConfig} config - The spot template configuration.
         | 
| 7 8 | 
             
             *
         | 
| 8 | 
            -
             * @return { | 
| 9 | 
            +
             * @return {HTMLElement | null} - The HTML element for the given spot or null if the spot template is not found.
         | 
| 9 10 | 
             
             */
         | 
| 10 11 | 
             
            export declare const SPOT_TEMPLATE_HTML_ELEMENT: (spot: ISpot, config?: ISpotTemplateConfig) => HTMLElement | null;
         | 
| @@ -1,5 +1,72 @@ | |
| 1 1 | 
             
            import type { RMN_SPOT_EVENT } from 'enums';
         | 
| 2 | 
            +
            import type { ISpot } from '../selection';
         | 
| 2 3 | 
             
            export interface IFireEventParams {
         | 
| 3 4 | 
             
                event: RMN_SPOT_EVENT;
         | 
| 4 5 | 
             
                eventUrl: string;
         | 
| 5 6 | 
             
            }
         | 
| 7 | 
            +
            export interface IMountedEvent {
         | 
| 8 | 
            +
                placementId: string;
         | 
| 9 | 
            +
                spotId: string;
         | 
| 10 | 
            +
                spotType: string;
         | 
| 11 | 
            +
                spotVariant: string;
         | 
| 12 | 
            +
                element: HTMLElement;
         | 
| 13 | 
            +
            }
         | 
| 14 | 
            +
            export interface IUnMountedEvent {
         | 
| 15 | 
            +
                placementId: string;
         | 
| 16 | 
            +
                spotId: string;
         | 
| 17 | 
            +
            }
         | 
| 18 | 
            +
            export interface IResizedEvent {
         | 
| 19 | 
            +
                placementId: string;
         | 
| 20 | 
            +
                spotId: string;
         | 
| 21 | 
            +
                scale: number;
         | 
| 22 | 
            +
                previousDimensions: {
         | 
| 23 | 
            +
                    width: number;
         | 
| 24 | 
            +
                    height: number;
         | 
| 25 | 
            +
                };
         | 
| 26 | 
            +
                currentDimensions: {
         | 
| 27 | 
            +
                    width: number;
         | 
| 28 | 
            +
                    height: number;
         | 
| 29 | 
            +
                };
         | 
| 30 | 
            +
            }
         | 
| 31 | 
            +
            export interface IClickEvent {
         | 
| 32 | 
            +
                placementId: string;
         | 
| 33 | 
            +
                spotId: string;
         | 
| 34 | 
            +
                element: HTMLElement;
         | 
| 35 | 
            +
            }
         | 
| 36 | 
            +
            export interface IImpressionEvent {
         | 
| 37 | 
            +
                placementId: string;
         | 
| 38 | 
            +
                spotId: string;
         | 
| 39 | 
            +
                element: HTMLElement;
         | 
| 40 | 
            +
            }
         | 
| 41 | 
            +
            export interface IAddToCartEvent {
         | 
| 42 | 
            +
                placementId: string;
         | 
| 43 | 
            +
                spotId: string;
         | 
| 44 | 
            +
            }
         | 
| 45 | 
            +
            export interface IAddToWishlistEvent {
         | 
| 46 | 
            +
                placementId: string;
         | 
| 47 | 
            +
                spotId: string;
         | 
| 48 | 
            +
            }
         | 
| 49 | 
            +
            export interface IPurchaseEvent {
         | 
| 50 | 
            +
                placementId: string;
         | 
| 51 | 
            +
                spotId: string;
         | 
| 52 | 
            +
            }
         | 
| 53 | 
            +
            export interface IBuyNowEvent {
         | 
| 54 | 
            +
                placementId: string;
         | 
| 55 | 
            +
                spotId: string;
         | 
| 56 | 
            +
            }
         | 
| 57 | 
            +
            export interface IEventMap {
         | 
| 58 | 
            +
                [RMN_SPOT_EVENT.MOUNTED]: IMountedEvent;
         | 
| 59 | 
            +
                [RMN_SPOT_EVENT.UNMOUNTED]: IUnMountedEvent;
         | 
| 60 | 
            +
                [RMN_SPOT_EVENT.RESIZED]: IResizedEvent;
         | 
| 61 | 
            +
                [RMN_SPOT_EVENT.CLICK]: IClickEvent;
         | 
| 62 | 
            +
                [RMN_SPOT_EVENT.IMPRESSION]: IImpressionEvent;
         | 
| 63 | 
            +
                [RMN_SPOT_EVENT.ADD_TO_CART]: IAddToCartEvent;
         | 
| 64 | 
            +
                [RMN_SPOT_EVENT.ADD_TO_WISHLIST]: IAddToWishlistEvent;
         | 
| 65 | 
            +
                [RMN_SPOT_EVENT.PURCHASE]: IPurchaseEvent;
         | 
| 66 | 
            +
                [RMN_SPOT_EVENT.BUY_NOW]: IBuyNowEvent;
         | 
| 67 | 
            +
            }
         | 
| 68 | 
            +
            export interface IRegisterSpotParams {
         | 
| 69 | 
            +
                placementId: string;
         | 
| 70 | 
            +
                element: HTMLElement;
         | 
| 71 | 
            +
                spot: ISpot;
         | 
| 72 | 
            +
            }
         | 
| @@ -1,5 +1,30 @@ | |
| 1 | 
            -
            import type {  | 
| 1 | 
            +
            import type { IEventMap, IRegisterSpotParams } from './event.interface';
         | 
| 2 2 | 
             
            export declare class EventService {
         | 
| 3 | 
            -
                 | 
| 3 | 
            +
                private static instance;
         | 
| 4 | 
            +
                private pubSub;
         | 
| 5 | 
            +
                private intersectionObserver;
         | 
| 6 | 
            +
                private activeSpots;
         | 
| 7 | 
            +
                private constructor();
         | 
| 8 | 
            +
                static getInstance(): EventService;
         | 
| 9 | 
            +
                registerSpot({ placementId, element, spot }: IRegisterSpotParams): void;
         | 
| 10 | 
            +
                unregisterSpot(spotId: string): void;
         | 
| 11 | 
            +
                private handleIntersectionObserver;
         | 
| 12 | 
            +
                subscribe<K extends keyof IEventMap>(eventType: K, callback: (data: IEventMap[K]) => void): () => void;
         | 
| 13 | 
            +
                publish<K extends keyof IEventMap>(eventType: K, data: IEventMap[K]): void;
         | 
| 14 | 
            +
                /**
         | 
| 15 | 
            +
                 * Fires an event using the navigator.sendBeacon method and redirects the user if the event is a click event.
         | 
| 16 | 
            +
                 *
         | 
| 17 | 
            +
                 * @param {IFireEventParams} params - The parameters for firing the event.
         | 
| 18 | 
            +
                 * @param {RMN_SPOT_EVENT} params.event - The event type.
         | 
| 19 | 
            +
                 * @param {string} params.eventUrl - The URL to which the event is sent.
         | 
| 20 | 
            +
                 * @returns {Promise<void>} - A promise that resolves when the event is fired.
         | 
| 21 | 
            +
                 */
         | 
| 22 | 
            +
                private fireEvent;
         | 
| 23 | 
            +
                /**
         | 
| 24 | 
            +
                 * Extracts and decodes a URL from a base64-encoded query parameter.
         | 
| 25 | 
            +
                 *
         | 
| 26 | 
            +
                 * @param {string} url - The URL containing the base64-encoded query parameter.
         | 
| 27 | 
            +
                 * @returns {string} - The decoded URL or an empty string if decoding fails.
         | 
| 28 | 
            +
                 */
         | 
| 4 29 | 
             
                private getRedirectUrlFromPayload;
         | 
| 5 30 | 
             
            }
         | 
| @@ -0,0 +1,67 @@ | |
| 1 | 
            +
            /**
         | 
| 2 | 
            +
             * Callback function type for event subscribers
         | 
| 3 | 
            +
             * @template T The type of data the callback receives
         | 
| 4 | 
            +
             */
         | 
| 5 | 
            +
            export type PSCallback<T> = (data: T) => void;
         | 
| 6 | 
            +
            /**
         | 
| 7 | 
            +
             * Function type for unsubscribing from an event
         | 
| 8 | 
            +
             */
         | 
| 9 | 
            +
            export type PSUnsubscribe = () => void;
         | 
| 10 | 
            +
            /**
         | 
| 11 | 
            +
             * PubSub class
         | 
| 12 | 
            +
             * Manages event subscriptions and publications
         | 
| 13 | 
            +
             * @template IEventMap A record type defining the structure of events and their data
         | 
| 14 | 
            +
             */
         | 
| 15 | 
            +
            export declare class PubSub<IEventMap> {
         | 
| 16 | 
            +
                /**
         | 
| 17 | 
            +
                 * Object to store subscribers for each event type
         | 
| 18 | 
            +
                 */
         | 
| 19 | 
            +
                private subscribers;
         | 
| 20 | 
            +
                /**
         | 
| 21 | 
            +
                 * Subscribe to an event
         | 
| 22 | 
            +
                 * @param eventType - The type of event to subscribe to
         | 
| 23 | 
            +
                 * @param callback - The function to be called when the event is published
         | 
| 24 | 
            +
                 * @returns A function to unsubscribe from the event
         | 
| 25 | 
            +
                 *
         | 
| 26 | 
            +
                 * @Example:
         | 
| 27 | 
            +
                 * const unsubscribe = pubSub.subscribe('userLogin', (data) => {
         | 
| 28 | 
            +
                 *   console.log(`User ${data.username} logged in`);
         | 
| 29 | 
            +
                 * });
         | 
| 30 | 
            +
                 */
         | 
| 31 | 
            +
                subscribe<K extends keyof IEventMap>(eventType: K, callback: PSCallback<IEventMap[K]>): PSUnsubscribe;
         | 
| 32 | 
            +
                /**
         | 
| 33 | 
            +
                 * Publish an event
         | 
| 34 | 
            +
                 * @param eventType - The type of event to publish
         | 
| 35 | 
            +
                 * @param data - The data to be passed to the event subscribers
         | 
| 36 | 
            +
                 *
         | 
| 37 | 
            +
                 * @Example:
         | 
| 38 | 
            +
                 * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
         | 
| 39 | 
            +
                 */
         | 
| 40 | 
            +
                publish<K extends keyof IEventMap>(eventType: K, data: IEventMap[K]): void;
         | 
| 41 | 
            +
            }
         | 
| 42 | 
            +
            /**
         | 
| 43 | 
            +
             * Usage Example:
         | 
| 44 | 
            +
             *
         | 
| 45 | 
            +
             * interface IEventMap {
         | 
| 46 | 
            +
             *   userLogin: { username: string; timestamp: number };
         | 
| 47 | 
            +
             *   pageView: { url: string; timestamp: number };
         | 
| 48 | 
            +
             * }
         | 
| 49 | 
            +
             *
         | 
| 50 | 
            +
             * const pubSub = new PubSub<IEventMap>();
         | 
| 51 | 
            +
             *
         | 
| 52 | 
            +
             * // Subscribe to events
         | 
| 53 | 
            +
             * const unsubscribeLogin = pubSub.subscribe('userLogin', (data) => {
         | 
| 54 | 
            +
             *   console.log(`User ${data.username} logged in at ${new Date(data.timestamp)}`);
         | 
| 55 | 
            +
             * });
         | 
| 56 | 
            +
             *
         | 
| 57 | 
            +
             * pubSub.subscribe('pageView', (data) => {
         | 
| 58 | 
            +
             *   console.log(`Page ${data.url} viewed at ${new Date(data.timestamp)}`);
         | 
| 59 | 
            +
             * });
         | 
| 60 | 
            +
             *
         | 
| 61 | 
            +
             * // Publish events
         | 
| 62 | 
            +
             * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
         | 
| 63 | 
            +
             * pubSub.publish('pageView', { url: '/home', timestamp: Date.now() });
         | 
| 64 | 
            +
             *
         | 
| 65 | 
            +
             * // Unsubscribe from an event
         | 
| 66 | 
            +
             * unsubscribeLogin();
         | 
| 67 | 
            +
             */
         | 
| @@ -1,10 +1,12 @@ | |
| 1 1 | 
             
            import type { IAuthCredentials } from 'modules/auth';
         | 
| 2 2 | 
             
            import type { IInjectSpotElementParams, IRmnCreateSpotElementConfig } from 'modules/element';
         | 
| 3 | 
            +
            import { EventService } from 'modules/event';
         | 
| 3 4 | 
             
            import type { ISpot, ISpots, ISpotSelectionParams } from 'modules/selection';
         | 
| 4 5 | 
             
            import type { IRmnClient, IRmnConfig } from 'types';
         | 
| 5 6 | 
             
            export declare class LiquidCommerceRmnClient implements IRmnClient {
         | 
| 6 7 | 
             
                private readonly selectionService;
         | 
| 7 8 | 
             
                private readonly elementService;
         | 
| 9 | 
            +
                private readonly eventService;
         | 
| 8 10 | 
             
                constructor(auth: IAuthCredentials);
         | 
| 9 11 | 
             
                /**
         | 
| 10 12 | 
             
                 * Makes a selection request on our server based on the provided data.
         | 
| @@ -24,6 +26,12 @@ export declare class LiquidCommerceRmnClient implements IRmnClient { | |
| 24 26 | 
             
                 * @return {Promise<void>} - A promise that resolves when the spot elements are injected.
         | 
| 25 27 | 
             
                 */
         | 
| 26 28 | 
             
                injectSpotElement(params: IInjectSpotElementParams): Promise<void>;
         | 
| 29 | 
            +
                /**
         | 
| 30 | 
            +
                 * Returns the event manager instance.
         | 
| 31 | 
            +
                 *
         | 
| 32 | 
            +
                 * @return {EventService} - The event manager instance.
         | 
| 33 | 
            +
                 */
         | 
| 34 | 
            +
                eventManager(): EventService;
         | 
| 27 35 | 
             
                /**
         | 
| 28 36 | 
             
                 * Makes a selection request on our server based on the provided data.
         | 
| 29 37 | 
             
                 *
         | 
| @@ -53,6 +61,7 @@ export declare class LiquidCommerceRmnClient implements IRmnClient { | |
| 53 61 | 
             
                 * @return {void}
         | 
| 54 62 | 
             
                 */
         | 
| 55 63 | 
             
                private injectOneSpotElement;
         | 
| 64 | 
            +
                private eventSpotElement;
         | 
| 56 65 | 
             
                /**
         | 
| 57 66 | 
             
                 * Prevents duplicate placement ids in the inject data.
         | 
| 58 67 | 
             
                 *
         | 
    
        package/dist/types/types.d.ts
    CHANGED
    
    | @@ -1,4 +1,6 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            import type { EventService } from './modules/event';
         | 
| 2 | 
            +
            export type { IInjectSpotElement, IInjectSpotElementConfig, IInjectSpotElementParams, IRmnCreateSpotElementConfig, ISpotColors, ISpotOverlay, } from 'modules/element';
         | 
| 3 | 
            +
            export type { CarouselNavPositionType, ICarouselButtonOptions, ICarouselDotOptions, ICarouselOptions, } from 'modules/element/component/carousel';
         | 
| 2 4 | 
             
            export type { ISpots, RmnFilterType, RmnSpotType } from 'modules/selection';
         | 
| 3 5 | 
             
            export { ISpot, ISpotEvent, ISpotSelectionParams } from 'modules/selection';
         | 
| 4 6 | 
             
            import type { RMN_ENV } from 'enums';
         | 
| @@ -7,6 +9,7 @@ import type { ISpots, ISpotSelectionParams } from 'modules/selection'; | |
| 7 9 | 
             
            export interface IRmnClient {
         | 
| 8 10 | 
             
                spotSelection(params: ISpotSelectionParams): Promise<ISpots>;
         | 
| 9 11 | 
             
                injectSpotElement(params: IInjectSpotElementParams): Promise<void>;
         | 
| 12 | 
            +
                eventManager(): EventService;
         | 
| 10 13 | 
             
            }
         | 
| 11 14 | 
             
            export interface IRmnConfig {
         | 
| 12 15 | 
             
                env: RMN_ENV;
         | 
    
        package/package.json
    CHANGED
    
    | @@ -2,7 +2,7 @@ | |
| 2 2 | 
             
              "name": "@liquidcommercedev/rmn-sdk",
         | 
| 3 3 | 
             
              "description": "LiquidCommerce RMN SDK",
         | 
| 4 4 | 
             
              "author": "LiquidCommerce Tech",
         | 
| 5 | 
            -
              "version": "1.4.6-beta. | 
| 5 | 
            +
              "version": "1.4.6-beta.5",
         | 
| 6 6 | 
             
              "homepage": "https://docs.liquidcommerce.co/rmn-sdk",
         | 
| 7 7 | 
             
              "main": "./dist/index.cjs",
         | 
| 8 8 | 
             
              "module": "./dist/index.esm.js",
         |