@liquidcommercedev/rmn-sdk 1.4.6-beta.7 → 1.4.6-beta.8

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.esm.js CHANGED
@@ -54,9 +54,7 @@ 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["INJECT_SPOTS"] = "INJECT_SPOTS";
58
- RMN_SPOT_EVENT["MOUNTED"] = "MOUNTED";
59
- RMN_SPOT_EVENT["UNMOUNTED"] = "UNMOUNTED";
57
+ RMN_SPOT_EVENT["LIFECYCLE_STATE"] = "LIFECYCLE_STATE";
60
58
  RMN_SPOT_EVENT["IMPRESSION"] = "IMPRESSION";
61
59
  RMN_SPOT_EVENT["CLICK"] = "CLICK";
62
60
  RMN_SPOT_EVENT["PURCHASE"] = "PURCHASE";
@@ -16826,11 +16824,11 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
16826
16824
  align-items: flex-start;
16827
16825
  width: 100%;
16828
16826
  height: fit-content;
16829
- gap: 5px;
16827
+ gap: 8px;
16830
16828
  }
16831
16829
 
16832
16830
  .${prefix}__header {
16833
- font-size: 18px;
16831
+ font-size: 24px;
16834
16832
  margin: 0;
16835
16833
  font-family: "Cormorant";
16836
16834
  font-style: normal;
@@ -16888,10 +16886,6 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
16888
16886
  height: 50%;
16889
16887
  }
16890
16888
 
16891
- .${prefix}__header {
16892
- font-size: 22px;
16893
- }
16894
-
16895
16889
  .${prefix}__description {
16896
16890
  font-size: 12px;
16897
16891
  }
@@ -16903,7 +16897,7 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
16903
16897
 
16904
16898
  @container (min-width: 1024px) {
16905
16899
  .${prefix}__header {
16906
- font-size: 24px;
16900
+ font-size: 26px;
16907
16901
  }
16908
16902
 
16909
16903
  .${prefix}__description {
@@ -16964,7 +16958,7 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16964
16958
  display: flex;
16965
16959
  flex-direction: column;
16966
16960
  background-color: transparent;
16967
- gap: 5px;
16961
+ gap: 6px;
16968
16962
  color: inherit;
16969
16963
  cursor: pointer;
16970
16964
  }
@@ -16983,7 +16977,7 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16983
16977
  height: 40%;
16984
16978
  display: flex;
16985
16979
  flex-direction: row;
16986
- gap: 5px;
16980
+ gap: 6px;
16987
16981
  }
16988
16982
 
16989
16983
  .${prefix}__secondary-image {
@@ -17005,7 +16999,7 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17005
16999
  align-items: center;
17006
17000
  width: 50%;
17007
17001
  height: 100%;
17008
- gap: 5px;
17002
+ gap: 10px;
17009
17003
  padding: 0 10px;
17010
17004
  box-sizing: border-box;
17011
17005
  }
@@ -17151,7 +17145,7 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17151
17145
  display: flex;
17152
17146
  flex-direction: column-reverse;
17153
17147
  background-color: transparent;
17154
- gap: 5px;
17148
+ gap: 6px;
17155
17149
  cursor: pointer;
17156
17150
  container-type: inline-size;
17157
17151
  position: relative;
@@ -17176,7 +17170,7 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17176
17170
  align-items: center;
17177
17171
  width: 100%;
17178
17172
  height: 100%;
17179
- gap: 5px;
17173
+ gap: 10px;
17180
17174
  padding: 0 10px;
17181
17175
  box-sizing: border-box;
17182
17176
  }
@@ -17786,6 +17780,7 @@ class EventService {
17786
17780
  constructor() {
17787
17781
  this.pubSub = new PubSub();
17788
17782
  this.activeSpots = new Map();
17783
+ this.spotStates = new Map();
17789
17784
  this.intersectionObserver = new IntersectionObserverService();
17790
17785
  }
17791
17786
  static getInstance() {
@@ -17794,6 +17789,46 @@ class EventService {
17794
17789
  }
17795
17790
  return EventService.instance;
17796
17791
  }
17792
+ subscribe(eventType, callback) {
17793
+ return this.pubSub.subscribe(eventType, callback);
17794
+ }
17795
+ publish(eventType, data) {
17796
+ this.pubSub.publish(eventType, data);
17797
+ }
17798
+ handleSpotState(placementId, updates, publish = true) {
17799
+ let currentState = this.spotStates.get(placementId);
17800
+ if (!currentState) {
17801
+ currentState = {
17802
+ identifier: {
17803
+ placementId,
17804
+ spotId: '',
17805
+ spotType: '',
17806
+ },
17807
+ dom: {
17808
+ element: undefined,
17809
+ visible: false,
17810
+ },
17811
+ state: {
17812
+ mounted: false,
17813
+ unmounted: false,
17814
+ loading: false,
17815
+ error: undefined,
17816
+ },
17817
+ displayConfig: {
17818
+ isCarousel: false,
17819
+ isCarouselItem: false,
17820
+ isSingleItem: false,
17821
+ },
17822
+ };
17823
+ }
17824
+ this.spotStates.set(placementId, {
17825
+ ...currentState,
17826
+ ...updates,
17827
+ });
17828
+ if (publish) {
17829
+ this.pubSub.publish(RMN_SPOT_EVENT.LIFECYCLE_STATE, this.spotStates.get(placementId));
17830
+ }
17831
+ }
17797
17832
  registerSpot({ placementId, element, spot }) {
17798
17833
  this.activeSpots.set(spot.id, {
17799
17834
  placementId,
@@ -17816,23 +17851,20 @@ class EventService {
17816
17851
  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 : '',
17817
17852
  });
17818
17853
  });
17819
- // Publish spot created event
17820
- this.pubSub.publish(RMN_SPOT_EVENT.MOUNTED, {
17821
- placementId,
17822
- spotId: spot.id,
17823
- spotType: spot.spot,
17824
- spotVariant: spot.variant,
17825
- element,
17826
- });
17827
17854
  }
17828
17855
  unregisterSpot(spotId) {
17829
17856
  const spotData = this.activeSpots.get(spotId);
17830
17857
  if (spotData) {
17831
17858
  this.intersectionObserver.unobserve(spotData.element);
17832
- // this.resizeObserver?.disconnect();
17833
- this.pubSub.publish(RMN_SPOT_EVENT.UNMOUNTED, {
17834
- placementId: spotData.placementId,
17835
- spotId,
17859
+ this.handleSpotState(spotData.placementId, {
17860
+ dom: {
17861
+ element: undefined,
17862
+ visible: false,
17863
+ },
17864
+ state: {
17865
+ unmounted: true,
17866
+ mounted: false,
17867
+ },
17836
17868
  });
17837
17869
  this.activeSpots.delete(spotId);
17838
17870
  }
@@ -17851,6 +17883,12 @@ class EventService {
17851
17883
  element,
17852
17884
  impressionTracked: true,
17853
17885
  });
17886
+ this.handleSpotState(placementId, {
17887
+ dom: {
17888
+ element,
17889
+ visible: true,
17890
+ },
17891
+ });
17854
17892
  // Fire impression event
17855
17893
  await this.fireEvent({
17856
17894
  event: RMN_SPOT_EVENT.IMPRESSION,
@@ -17859,12 +17897,6 @@ class EventService {
17859
17897
  };
17860
17898
  this.intersectionObserver.observe(element, spotIsVisibleCb);
17861
17899
  }
17862
- subscribe(eventType, callback) {
17863
- return this.pubSub.subscribe(eventType, callback);
17864
- }
17865
- publish(eventType, data) {
17866
- this.pubSub.publish(eventType, data);
17867
- }
17868
17900
  /**
17869
17901
  * Fires an event using the navigator.sendBeacon method and redirects the user if the event is a click event.
17870
17902
  *
@@ -17930,6 +17962,21 @@ class SelectionService extends BaseApi {
17930
17962
 
17931
17963
  class LiquidCommerceRmnClient {
17932
17964
  constructor(auth) {
17965
+ /**
17966
+ * Returns the event manager instance.
17967
+ *
17968
+ * @return {EventService} - The event manager instance.
17969
+ */
17970
+ this.eventManager = {
17971
+ subscribe: (eventType, callback
17972
+ /* eslint-disable arrow-body-style */
17973
+ ) => {
17974
+ return this.eventService.subscribe(eventType, callback);
17975
+ },
17976
+ publish: (eventType, data) => {
17977
+ this.eventService.publish(eventType, data);
17978
+ },
17979
+ };
17933
17980
  this.selectionService = SelectionService.getInstance(auth);
17934
17981
  this.elementService = ElementService.getInstance();
17935
17982
  this.eventService = EventService.getInstance();
@@ -17957,36 +18004,56 @@ class LiquidCommerceRmnClient {
17957
18004
  var _a;
17958
18005
  const config = params.config;
17959
18006
  let inject = params.inject;
17960
- this.eventService.publish(RMN_SPOT_EVENT.INJECT_SPOTS, {
17961
- isLoading: true,
17962
- isCompleted: false,
17963
- error: null,
17964
- });
17965
18007
  if (!inject.length) {
17966
- this.eventError('RmnSdk: Failed to inject spot element. Please provide at least one spot element to inject.');
18008
+ this.eventService.handleSpotState('all', {
18009
+ state: {
18010
+ error: 'No spot elements provided for injection.',
18011
+ loading: false,
18012
+ },
18013
+ });
17967
18014
  return;
17968
18015
  }
18016
+ // Update the state of the spots to loading
18017
+ this.updateSpotsState(inject);
18018
+ // Prevent duplicate placement ids
17969
18019
  const hasDuplicatePlacementIds = this.preventDuplicateSpotPlacementIds(inject);
17970
18020
  if (!hasDuplicatePlacementIds) {
17971
18021
  return;
17972
18022
  }
18023
+ // Prevent non-existent spot types
17973
18024
  inject = this.preventNonExistentSpotTypes(inject);
18025
+ // Make the spot selection request
17974
18026
  const response = await this.spotSelectionRequest({ ...params, inject });
18027
+ // Handle the response
17975
18028
  if (typeof response === 'object' && 'error' in response) {
17976
- this.eventError(response.error);
18029
+ this.eventService.handleSpotState('all', {
18030
+ state: {
18031
+ error: response.error,
18032
+ },
18033
+ });
17977
18034
  return;
17978
18035
  }
17979
18036
  for (const item of inject) {
17980
18037
  const itemConfig = (_a = item.config) !== null && _a !== void 0 ? _a : config;
17981
18038
  const spots = response[item.placementId];
17982
18039
  if (!(spots === null || spots === void 0 ? void 0 : spots.length)) {
17983
- this.eventError(`RmnSdk: Failed to inject spot element. No spots found for type "${item.spotType}".`, { placementId: item.placementId, type: item.spotType });
18040
+ this.eventService.handleSpotState(item.placementId, {
18041
+ state: {
18042
+ error: `No spots found for type "${item.spotType}".`,
18043
+ loading: false,
18044
+ },
18045
+ });
17984
18046
  continue;
17985
18047
  }
17986
18048
  const placementId = item.placementId.replace('#', '');
17987
18049
  const placement = document.getElementById(placementId);
17988
18050
  if (!placement) {
17989
- this.eventError(`RmnSdk: Failed to inject spot element. Placement not found for id "#${placementId}".`, { placementId, type: item.spotType });
18051
+ this.eventService.handleSpotState(item.placementId, {
18052
+ state: {
18053
+ error: `Placement not found for id "${placementId}".`,
18054
+ loading: false,
18055
+ },
18056
+ });
17990
18057
  continue;
17991
18058
  }
17992
18059
  if (spots.length === 1) {
@@ -18003,14 +18070,6 @@ class LiquidCommerceRmnClient {
18003
18070
  }
18004
18071
  }
18005
18072
  }
18006
- /**
18007
- * Returns the event manager instance.
18008
- *
18009
- * @return {EventService} - The event manager instance.
18010
- */
18011
- eventManager() {
18012
- return this.eventService;
18013
- }
18014
18073
  /**
18015
18074
  * Makes a selection request on our server based on the provided data.
18016
18075
  *
@@ -18023,12 +18082,14 @@ class LiquidCommerceRmnClient {
18023
18082
  const request = {
18024
18083
  url: config === null || config === void 0 ? void 0 : config.url,
18025
18084
  filter,
18026
- spots: inject.map((item) => ({
18027
- placementId: item.placementId,
18028
- spot: item.spotType,
18029
- count: item === null || item === void 0 ? void 0 : item.count,
18030
- ...item === null || item === void 0 ? void 0 : item.filter,
18031
- })),
18085
+ spots: inject.map((item) => {
18086
+ return {
18087
+ placementId: item.placementId,
18088
+ spot: item.spotType,
18089
+ count: item === null || item === void 0 ? void 0 : item.count,
18090
+ ...item === null || item === void 0 ? void 0 : item.filter,
18091
+ };
18092
+ }),
18032
18093
  };
18033
18094
  return this.spotSelection(request);
18034
18095
  }
@@ -18045,23 +18106,39 @@ class LiquidCommerceRmnClient {
18045
18106
  var _a;
18046
18107
  const carouselSlides = [];
18047
18108
  for (const spotItem of spots) {
18109
+ this.eventService.handleSpotState(placement.id, {
18110
+ displayConfig: {
18111
+ isCarousel: true,
18112
+ isCarouselItem: true,
18113
+ isSingleItem: false,
18114
+ },
18115
+ }, false);
18048
18116
  const spot = this.elementService.overrideSpotColors(spotItem, config === null || config === void 0 ? void 0 : config.colors);
18049
18117
  const content = SPOT_TEMPLATE_HTML_ELEMENT(spot, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
18050
18118
  if (!content) {
18051
- this.eventError(`RmnSdk: Failed to inject carousel spot element. Could not create element for type "${spot.spot}".`, { placementId: placement.id, type: spot.spot });
18119
+ this.eventService.handleSpotState(placement.id, {
18120
+ state: {
18121
+ error: `Failed to inject carousel spot item element. Could not create element for type "${spot.spot}".`,
18122
+ loading: false,
18123
+ },
18124
+ });
18052
18125
  continue;
18053
18126
  }
18054
- this.eventSpotElement({
18127
+ this.eventService.registerSpot({
18055
18128
  spot,
18056
18129
  placementId: placement.id,
18057
18130
  element: content,
18058
18131
  });
18059
18132
  carouselSlides.push(content);
18060
18133
  }
18061
- const { maxWidth, maxHeight } = spots.reduce((max, spot) => ({
18062
- maxWidth: Math.max(max.maxWidth, spot.width),
18063
- maxHeight: Math.max(max.maxHeight, spot.height),
18064
- }), { maxWidth: 0, maxHeight: 0 });
18134
+ // Get the max width and height of the spots
18135
+ const { maxWidth, maxHeight } = spots.reduce((max, spot) => {
18136
+ return {
18137
+ maxWidth: Math.max(max.maxWidth, spot.width),
18138
+ maxHeight: Math.max(max.maxHeight, spot.height),
18139
+ };
18140
+ }, { maxWidth: 0, maxHeight: 0 });
18141
+ // Create the carousel element
18065
18142
  const carouselElement = this.elementService.createCarouselElement({
18066
18143
  slides: carouselSlides,
18067
18144
  config: {
@@ -18073,10 +18150,24 @@ class LiquidCommerceRmnClient {
18073
18150
  },
18074
18151
  });
18075
18152
  if (!carouselElement) {
18076
- this.eventError(`RmnSdk: Failed to inject spot carousel element. Could not create spot carousel element.`, { placementId: placement.id });
18153
+ this.eventService.handleSpotState(placement.id, {
18154
+ state: {
18155
+ error: `Failed to inject spot carousel element. Could not create spot carousel element.`,
18156
+ loading: false,
18157
+ },
18158
+ });
18077
18159
  return false;
18078
18160
  }
18079
18161
  placement.replaceChildren(carouselElement);
18162
+ this.eventService.handleSpotState(placement.id, {
18163
+ dom: {
18164
+ element: carouselElement,
18165
+ },
18166
+ state: {
18167
+ mounted: true,
18168
+ loading: false,
18169
+ },
18170
+ });
18080
18171
  return true;
18081
18172
  }
18082
18173
  /**
@@ -18092,11 +18183,23 @@ class LiquidCommerceRmnClient {
18092
18183
  injectOneSpotElement(injectItem, placement, spot, config) {
18093
18184
  var _a;
18094
18185
  const spotData = this.elementService.overrideSpotColors(spot, config === null || config === void 0 ? void 0 : config.colors);
18186
+ this.eventService.handleSpotState(injectItem.placementId, {
18187
+ displayConfig: {
18188
+ isSingleItem: true,
18189
+ },
18190
+ }, false);
18191
+ // Create the spot template element
18095
18192
  const content = SPOT_TEMPLATE_HTML_ELEMENT(spotData, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
18096
18193
  if (!content) {
18097
- this.eventError(`RmnSdk: Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`, { placementId: injectItem.placementId, type: injectItem.spotType });
18194
+ this.eventService.handleSpotState(injectItem.placementId, {
18195
+ state: {
18196
+ error: `Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`,
18197
+ loading: false,
18198
+ },
18199
+ });
18098
18200
  return false;
18099
18201
  }
18202
+ // Create the spot element
18100
18203
  const spotElement = this.elementService.createSpotElement({
18101
18204
  content,
18102
18205
  config: {
@@ -18108,23 +18211,30 @@ class LiquidCommerceRmnClient {
18108
18211
  },
18109
18212
  });
18110
18213
  if (!spotElement) {
18111
- this.eventError(`RmnSdk: Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`, { placementId: injectItem.placementId, type: injectItem.spotType });
18214
+ this.eventService.handleSpotState(injectItem.placementId, {
18215
+ state: {
18216
+ error: `Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`,
18217
+ loading: false,
18218
+ },
18219
+ });
18112
18220
  return false;
18113
18221
  }
18114
- this.eventSpotElement({
18115
- spot,
18222
+ this.eventService.registerSpot({
18223
+ spot: spotData,
18116
18224
  placementId: injectItem.placementId,
18117
18225
  element: spotElement,
18118
18226
  });
18119
18227
  placement.replaceChildren(spotElement);
18120
- return true;
18121
- }
18122
- eventSpotElement({ spot, placementId, element, }) {
18123
- this.eventService.registerSpot({
18124
- placementId,
18125
- element,
18126
- spot,
18228
+ this.eventService.handleSpotState(injectItem.placementId, {
18229
+ dom: {
18230
+ element: spotElement,
18231
+ },
18232
+ state: {
18233
+ mounted: true,
18234
+ loading: false,
18235
+ },
18127
18236
  });
18237
+ return true;
18128
18238
  }
18129
18239
  /**
18130
18240
  * Prevents duplicate placement ids in the inject data.
@@ -18139,7 +18249,11 @@ class LiquidCommerceRmnClient {
18139
18249
  const placementIds = new Set();
18140
18250
  for (const item of inject) {
18141
18251
  if (placementIds.has(item.placementId)) {
18142
- this.eventError(`RmnSdk: Duplicate placement id (${item.placementId}) found. Please provide a unique placement id for each spot element.`, { placementId: item.placementId, type: item.spotType });
18252
+ this.eventService.handleSpotState(item.placementId, {
18253
+ state: {
18254
+ error: `Duplicate placement id (${item.placementId}) found. Please provide a unique placement id for each spot element.`,
18255
+ },
18256
+ });
18143
18257
  return false;
18144
18258
  }
18145
18259
  placementIds.add(item.placementId);
@@ -18150,22 +18264,29 @@ class LiquidCommerceRmnClient {
18150
18264
  const newInject = [];
18151
18265
  for (const item of inject) {
18152
18266
  if (!Object.values(RMN_SPOT_TYPE).includes(item.spotType)) {
18153
- this.eventError(`RmnSdk: Invalid spot type (${item.spotType}) found. Please provide a valid spot type for each spot element.`, { placementId: item.placementId, type: item.spotType });
18267
+ this.eventService.handleSpotState(item.placementId, {
18268
+ state: {
18269
+ error: `Invalid spot type (${item.spotType}) found. Please provide a valid spot type for each spot element.`,
18270
+ },
18271
+ });
18154
18272
  continue;
18155
18273
  }
18156
18274
  newInject.push(item);
18157
18275
  }
18158
18276
  return newInject;
18159
18277
  }
18160
- eventError(error, spot) {
18161
- this.eventService.publish(RMN_SPOT_EVENT.INJECT_SPOTS, {
18162
- isLoading: false,
18163
- isCompleted: true,
18164
- error: {
18165
- message: error,
18166
- spot,
18167
- },
18168
- });
18278
+ updateSpotsState(inject) {
18279
+ for (const item of inject) {
18280
+ this.eventService.handleSpotState(item.placementId, {
18281
+ identifier: {
18282
+ placementId: item.placementId,
18283
+ spotType: item.spotType,
18284
+ },
18285
+ state: {
18286
+ loading: true,
18287
+ },
18288
+ });
18289
+ }
18169
18290
  }
18170
18291
  }
18171
18292
  /**
@@ -49,9 +49,7 @@ export declare enum RMN_FILTER_PROPERTIES {
49
49
  SECTION = "section"
50
50
  }
51
51
  export declare enum RMN_SPOT_EVENT {
52
- INJECT_SPOTS = "INJECT_SPOTS",
53
- MOUNTED = "MOUNTED",
54
- UNMOUNTED = "UNMOUNTED",
52
+ LIFECYCLE_STATE = "LIFECYCLE_STATE",
55
53
  IMPRESSION = "IMPRESSION",
56
54
  CLICK = "CLICK",
57
55
  PURCHASE = "PURCHASE",
@@ -4,28 +4,31 @@ export interface IFireEventParams {
4
4
  event: RMN_SPOT_EVENT;
5
5
  eventUrl: string;
6
6
  }
7
- export interface IInjectSpotError {
8
- message: string;
9
- spot?: {
10
- type?: string;
11
- placementId?: string;
12
- };
13
- }
14
- export interface IInjectSpotsEvent {
15
- isLoading: boolean;
16
- isCompleted: boolean;
17
- error: null | IInjectSpotError;
18
- }
19
- export interface IMountedEvent {
7
+ export interface ILSIdentifier {
20
8
  placementId: string;
21
9
  spotId: string;
22
10
  spotType: string;
23
- spotVariant: string;
24
- element: HTMLElement;
25
11
  }
26
- export interface IUnMountedEvent {
27
- placementId: string;
28
- spotId: string;
12
+ export interface ILSDom {
13
+ visible: boolean;
14
+ element?: HTMLElement;
15
+ }
16
+ export interface ILSState {
17
+ mounted: boolean;
18
+ unmounted: boolean;
19
+ loading: boolean;
20
+ error?: string;
21
+ }
22
+ export interface ILSDisplayConfig {
23
+ isCarousel: boolean;
24
+ isCarouselItem: boolean;
25
+ isSingleItem: boolean;
26
+ }
27
+ export interface ILifecycleState {
28
+ identifier: Partial<ILSIdentifier>;
29
+ dom?: Partial<ILSDom>;
30
+ state?: Partial<ILSState>;
31
+ displayConfig?: Partial<ILSDisplayConfig>;
29
32
  }
30
33
  export interface IClickEvent {
31
34
  placementId: string;
@@ -54,9 +57,7 @@ export interface IBuyNowEvent {
54
57
  spotId: string;
55
58
  }
56
59
  export interface IEventMap {
57
- [RMN_SPOT_EVENT.INJECT_SPOTS]: IInjectSpotsEvent;
58
- [RMN_SPOT_EVENT.MOUNTED]: IMountedEvent;
59
- [RMN_SPOT_EVENT.UNMOUNTED]: IUnMountedEvent;
60
+ [RMN_SPOT_EVENT.LIFECYCLE_STATE]: ILifecycleState;
60
61
  [RMN_SPOT_EVENT.CLICK]: IClickEvent;
61
62
  [RMN_SPOT_EVENT.IMPRESSION]: IImpressionEvent;
62
63
  [RMN_SPOT_EVENT.ADD_TO_CART]: IAddToCartEvent;
@@ -1,16 +1,19 @@
1
- import type { IEventMap, IRegisterSpotParams } from './event.interface';
1
+ import { RMN_SPOT_EVENT } from 'enums';
2
+ import type { IEventMap, ILifecycleState, IRegisterSpotParams } from './event.interface';
2
3
  export declare class EventService {
3
4
  private static instance;
4
5
  private pubSub;
5
6
  private intersectionObserver;
7
+ private spotStates;
6
8
  private activeSpots;
7
9
  private constructor();
8
10
  static getInstance(): EventService;
11
+ subscribe(eventType: RMN_SPOT_EVENT, callback: (data: IEventMap[RMN_SPOT_EVENT]) => void): () => void;
12
+ publish(eventType: RMN_SPOT_EVENT, data: IEventMap[RMN_SPOT_EVENT]): void;
13
+ handleSpotState(placementId: string, updates: Partial<ILifecycleState>, publish?: boolean): void;
9
14
  registerSpot({ placementId, element, spot }: IRegisterSpotParams): void;
10
15
  unregisterSpot(spotId: string): void;
11
16
  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
17
  /**
15
18
  * Fires an event using the navigator.sendBeacon method and redirects the user if the event is a click event.
16
19
  *
@@ -1,8 +1,9 @@
1
1
  import type { IAuthCredentials } from 'modules/auth';
2
2
  import type { IInjectSpotElementParams, IRmnCreateSpotElementConfig } from 'modules/element';
3
- import { EventService } from 'modules/event';
3
+ import { type IEventMap } from 'modules/event';
4
4
  import type { ISpot, ISpots, ISpotSelectionParams } from 'modules/selection';
5
5
  import type { IRmnClient, IRmnConfig } from 'types';
6
+ import type { RMN_SPOT_EVENT } from './enums';
6
7
  export declare class LiquidCommerceRmnClient implements IRmnClient {
7
8
  private readonly selectionService;
8
9
  private readonly elementService;
@@ -33,7 +34,10 @@ export declare class LiquidCommerceRmnClient implements IRmnClient {
33
34
  *
34
35
  * @return {EventService} - The event manager instance.
35
36
  */
36
- eventManager(): EventService;
37
+ eventManager: {
38
+ subscribe: (eventType: RMN_SPOT_EVENT, callback: (data: IEventMap[RMN_SPOT_EVENT]) => void) => (() => void);
39
+ publish: (eventType: RMN_SPOT_EVENT, data: IEventMap[RMN_SPOT_EVENT]) => void;
40
+ };
37
41
  /**
38
42
  * Makes a selection request on our server based on the provided data.
39
43
  *
@@ -63,7 +67,6 @@ export declare class LiquidCommerceRmnClient implements IRmnClient {
63
67
  * @return {void}
64
68
  */
65
69
  private injectOneSpotElement;
66
- private eventSpotElement;
67
70
  /**
68
71
  * Prevents duplicate placement ids in the inject data.
69
72
  *
@@ -75,7 +78,7 @@ export declare class LiquidCommerceRmnClient implements IRmnClient {
75
78
  */
76
79
  private preventDuplicateSpotPlacementIds;
77
80
  private preventNonExistentSpotTypes;
78
- private eventError;
81
+ private updateSpotsState;
79
82
  }
80
83
  /**
81
84
  * Creates a new instance of the RmnClient.
@@ -1,9 +1,9 @@
1
- import type { EventService } from './modules/event';
1
+ import type { IEventMap } from './modules/event';
2
2
  export type { IInjectSpotElement, IInjectSpotElementConfig, IInjectSpotElementParams, IRmnCreateSpotElementConfig, ISpotColors, ISpotOverlay, } from 'modules/element';
3
3
  export type { CarouselNavPositionType, ICarouselButtonOptions, ICarouselDotOptions, ICarouselOptions, } from 'modules/element/component/carousel';
4
4
  export type { ISpots, RmnFilterType, RmnSpotType } from 'modules/selection';
5
5
  export { ISpot, ISpotEvent, ISpotSelectionParams } from 'modules/selection';
6
- import type { RMN_ENV } from 'enums';
6
+ import type { RMN_ENV, RMN_SPOT_EVENT } from 'enums';
7
7
  import type { IInjectSpotElementParams } from 'modules/element';
8
8
  import type { ISpots, ISpotSelectionParams } from 'modules/selection';
9
9
  export interface IRmnClient {
@@ -11,7 +11,10 @@ export interface IRmnClient {
11
11
  error: string;
12
12
  }>;
13
13
  injectSpotElement(params: IInjectSpotElementParams): Promise<void>;
14
- eventManager(): EventService;
14
+ eventManager: {
15
+ subscribe: (eventType: RMN_SPOT_EVENT, callback: (data: IEventMap[RMN_SPOT_EVENT]) => void) => () => void;
16
+ publish: (eventType: RMN_SPOT_EVENT, data: IEventMap[RMN_SPOT_EVENT]) => void;
17
+ };
15
18
  }
16
19
  export interface IRmnConfig {
17
20
  env: RMN_ENV;