@liquidcommercedev/rmn-sdk 1.4.6-beta.6 → 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,8 +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["MOUNTED"] = "MOUNTED";
58
- RMN_SPOT_EVENT["UNMOUNTED"] = "UNMOUNTED";
57
+ RMN_SPOT_EVENT["LIFECYCLE_STATE"] = "LIFECYCLE_STATE";
59
58
  RMN_SPOT_EVENT["IMPRESSION"] = "IMPRESSION";
60
59
  RMN_SPOT_EVENT["CLICK"] = "CLICK";
61
60
  RMN_SPOT_EVENT["PURCHASE"] = "PURCHASE";
@@ -16825,11 +16824,11 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
16825
16824
  align-items: flex-start;
16826
16825
  width: 100%;
16827
16826
  height: fit-content;
16828
- gap: 5px;
16827
+ gap: 8px;
16829
16828
  }
16830
16829
 
16831
16830
  .${prefix}__header {
16832
- font-size: 18px;
16831
+ font-size: 24px;
16833
16832
  margin: 0;
16834
16833
  font-family: "Cormorant";
16835
16834
  font-style: normal;
@@ -16887,10 +16886,6 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
16887
16886
  height: 50%;
16888
16887
  }
16889
16888
 
16890
- .${prefix}__header {
16891
- font-size: 22px;
16892
- }
16893
-
16894
16889
  .${prefix}__description {
16895
16890
  font-size: 12px;
16896
16891
  }
@@ -16902,7 +16897,7 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
16902
16897
 
16903
16898
  @container (min-width: 1024px) {
16904
16899
  .${prefix}__header {
16905
- font-size: 24px;
16900
+ font-size: 26px;
16906
16901
  }
16907
16902
 
16908
16903
  .${prefix}__description {
@@ -16963,7 +16958,7 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16963
16958
  display: flex;
16964
16959
  flex-direction: column;
16965
16960
  background-color: transparent;
16966
- gap: 5px;
16961
+ gap: 6px;
16967
16962
  color: inherit;
16968
16963
  cursor: pointer;
16969
16964
  }
@@ -16982,7 +16977,7 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16982
16977
  height: 40%;
16983
16978
  display: flex;
16984
16979
  flex-direction: row;
16985
- gap: 5px;
16980
+ gap: 6px;
16986
16981
  }
16987
16982
 
16988
16983
  .${prefix}__secondary-image {
@@ -17004,7 +16999,7 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17004
16999
  align-items: center;
17005
17000
  width: 50%;
17006
17001
  height: 100%;
17007
- gap: 5px;
17002
+ gap: 10px;
17008
17003
  padding: 0 10px;
17009
17004
  box-sizing: border-box;
17010
17005
  }
@@ -17150,7 +17145,7 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17150
17145
  display: flex;
17151
17146
  flex-direction: column-reverse;
17152
17147
  background-color: transparent;
17153
- gap: 5px;
17148
+ gap: 6px;
17154
17149
  cursor: pointer;
17155
17150
  container-type: inline-size;
17156
17151
  position: relative;
@@ -17175,7 +17170,7 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17175
17170
  align-items: center;
17176
17171
  width: 100%;
17177
17172
  height: 100%;
17178
- gap: 5px;
17173
+ gap: 10px;
17179
17174
  padding: 0 10px;
17180
17175
  box-sizing: border-box;
17181
17176
  }
@@ -17785,6 +17780,7 @@ class EventService {
17785
17780
  constructor() {
17786
17781
  this.pubSub = new PubSub();
17787
17782
  this.activeSpots = new Map();
17783
+ this.spotStates = new Map();
17788
17784
  this.intersectionObserver = new IntersectionObserverService();
17789
17785
  }
17790
17786
  static getInstance() {
@@ -17793,6 +17789,46 @@ class EventService {
17793
17789
  }
17794
17790
  return EventService.instance;
17795
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
+ }
17796
17832
  registerSpot({ placementId, element, spot }) {
17797
17833
  this.activeSpots.set(spot.id, {
17798
17834
  placementId,
@@ -17815,23 +17851,20 @@ class EventService {
17815
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 : '',
17816
17852
  });
17817
17853
  });
17818
- // Publish spot created event
17819
- this.pubSub.publish(RMN_SPOT_EVENT.MOUNTED, {
17820
- placementId,
17821
- spotId: spot.id,
17822
- spotType: spot.spot,
17823
- spotVariant: spot.variant,
17824
- element,
17825
- });
17826
17854
  }
17827
17855
  unregisterSpot(spotId) {
17828
17856
  const spotData = this.activeSpots.get(spotId);
17829
17857
  if (spotData) {
17830
17858
  this.intersectionObserver.unobserve(spotData.element);
17831
- // this.resizeObserver?.disconnect();
17832
- this.pubSub.publish(RMN_SPOT_EVENT.UNMOUNTED, {
17833
- placementId: spotData.placementId,
17834
- spotId,
17859
+ this.handleSpotState(spotData.placementId, {
17860
+ dom: {
17861
+ element: undefined,
17862
+ visible: false,
17863
+ },
17864
+ state: {
17865
+ unmounted: true,
17866
+ mounted: false,
17867
+ },
17835
17868
  });
17836
17869
  this.activeSpots.delete(spotId);
17837
17870
  }
@@ -17850,6 +17883,12 @@ class EventService {
17850
17883
  element,
17851
17884
  impressionTracked: true,
17852
17885
  });
17886
+ this.handleSpotState(placementId, {
17887
+ dom: {
17888
+ element,
17889
+ visible: true,
17890
+ },
17891
+ });
17853
17892
  // Fire impression event
17854
17893
  await this.fireEvent({
17855
17894
  event: RMN_SPOT_EVENT.IMPRESSION,
@@ -17858,12 +17897,6 @@ class EventService {
17858
17897
  };
17859
17898
  this.intersectionObserver.observe(element, spotIsVisibleCb);
17860
17899
  }
17861
- subscribe(eventType, callback) {
17862
- return this.pubSub.subscribe(eventType, callback);
17863
- }
17864
- publish(eventType, data) {
17865
- this.pubSub.publish(eventType, data);
17866
- }
17867
17900
  /**
17868
17901
  * Fires an event using the navigator.sendBeacon method and redirects the user if the event is a click event.
17869
17902
  *
@@ -17911,24 +17944,39 @@ class SelectionService extends BaseApi {
17911
17944
  *
17912
17945
  * @param {ISpotSelectionParams} data - Spots selection parameters.
17913
17946
  *
17914
- * @return {Promise<ISpots>} - The spots response object.
17947
+ * @return {Promise<ISpots | { error: string }>} - The spots response object.
17915
17948
  */
17916
17949
  async spotSelection(data) {
17917
17950
  const { isOk, val, isErr } = await this.post(SELECTION_API_PATH, data, {});
17918
17951
  if (isErr) {
17919
- throw new Error(`There was an error during spot selection: (${isErr === null || isErr === void 0 ? void 0 : isErr.errorMessage})`);
17952
+ return { error: `There was an error during spot selection: (${isErr === null || isErr === void 0 ? void 0 : isErr.errorMessage})` };
17920
17953
  }
17921
17954
  if (isOk && val && val.data && (val === null || val === void 0 ? void 0 : val.refresh.token)) {
17922
17955
  this.authInfo.authenticated = true;
17923
17956
  this.authInfo.token = val.refresh.token;
17924
17957
  return val.data.spots;
17925
17958
  }
17926
- throw new Error('Spot selection response was not successful');
17959
+ return { error: 'Spot selection response was not successful' };
17927
17960
  }
17928
17961
  }
17929
17962
 
17930
17963
  class LiquidCommerceRmnClient {
17931
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
+ };
17932
17980
  this.selectionService = SelectionService.getInstance(auth);
17933
17981
  this.elementService = ElementService.getInstance();
17934
17982
  this.eventService = EventService.getInstance();
@@ -17940,7 +17988,7 @@ class LiquidCommerceRmnClient {
17940
17988
  *
17941
17989
  * @param {ISpotSelectionParams} params - Spots selection parameters.
17942
17990
  *
17943
- * @return {Promise<ISpots>} - The spots response object.
17991
+ * @return {Promise<ISpots | {error : string}>} - The spots response object.
17944
17992
  */
17945
17993
  async spotSelection(params) {
17946
17994
  return this.selectionService.spotSelection(params);
@@ -17954,60 +18002,94 @@ class LiquidCommerceRmnClient {
17954
18002
  */
17955
18003
  async injectSpotElement(params) {
17956
18004
  var _a;
17957
- const { inject, config } = params;
18005
+ const config = params.config;
18006
+ let inject = params.inject;
17958
18007
  if (!inject.length) {
17959
- console.warn('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
+ });
18014
+ return;
18015
+ }
18016
+ // Update the state of the spots to loading
18017
+ this.updateSpotsState(inject);
18018
+ // Prevent duplicate placement ids
18019
+ const hasDuplicatePlacementIds = this.preventDuplicateSpotPlacementIds(inject);
18020
+ if (!hasDuplicatePlacementIds) {
18021
+ return;
18022
+ }
18023
+ // Prevent non-existent spot types
18024
+ inject = this.preventNonExistentSpotTypes(inject);
18025
+ // Make the spot selection request
18026
+ const response = await this.spotSelectionRequest({ ...params, inject });
18027
+ // Handle the response
18028
+ if (typeof response === 'object' && 'error' in response) {
18029
+ this.eventService.handleSpotState('all', {
18030
+ state: {
18031
+ error: response.error,
18032
+ },
18033
+ });
17960
18034
  return;
17961
18035
  }
17962
- this.preventDuplicateSpotPlacementIds(inject);
17963
- const response = await this.spotSelectionRequest(params);
17964
18036
  for (const item of inject) {
17965
18037
  const itemConfig = (_a = item.config) !== null && _a !== void 0 ? _a : config;
17966
18038
  const spots = response[item.placementId];
17967
18039
  if (!(spots === null || spots === void 0 ? void 0 : spots.length)) {
17968
- console.warn(`RmnSdk: Failed to inject spot element. No spots found for 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
+ });
17969
18046
  continue;
17970
18047
  }
17971
18048
  const placementId = item.placementId.replace('#', '');
17972
18049
  const placement = document.getElementById(placementId);
17973
18050
  if (!placement) {
17974
- console.warn(`RmnSdk: Failed to inject spot element. Placement not found for id "#${placementId}".`);
18051
+ this.eventService.handleSpotState(item.placementId, {
18052
+ state: {
18053
+ error: `Placement not found for id "${placementId}".`,
18054
+ loading: false,
18055
+ },
18056
+ });
17975
18057
  continue;
17976
18058
  }
17977
18059
  if (spots.length === 1) {
17978
- this.injectOneSpotElement(item, placement, spots[0], itemConfig);
18060
+ const isInjected = this.injectOneSpotElement(item, placement, spots[0], itemConfig);
18061
+ if (!isInjected) {
18062
+ continue;
18063
+ }
17979
18064
  }
17980
18065
  if (spots.length > 1) {
17981
- this.injectCarouselSpotElement(placement, spots, itemConfig);
18066
+ const isInjected = this.injectCarouselSpotElement(placement, spots, itemConfig);
18067
+ if (!isInjected) {
18068
+ continue;
18069
+ }
17982
18070
  }
17983
18071
  }
17984
18072
  }
17985
- /**
17986
- * Returns the event manager instance.
17987
- *
17988
- * @return {EventService} - The event manager instance.
17989
- */
17990
- eventManager() {
17991
- return this.eventService;
17992
- }
17993
18073
  /**
17994
18074
  * Makes a selection request on our server based on the provided data.
17995
18075
  *
17996
18076
  * @param {IInjectSpotElementParams} params - Parameters for injecting spot elements.
17997
18077
  *
17998
- * @return {Promise<ISpots>} - The spots response object.
18078
+ * @return {Promise<ISpots | {error: string}>} - The spots response object.
17999
18079
  */
18000
18080
  async spotSelectionRequest(params) {
18001
18081
  const { inject, filter, config } = params;
18002
18082
  const request = {
18003
18083
  url: config === null || config === void 0 ? void 0 : config.url,
18004
18084
  filter,
18005
- spots: inject.map((item) => ({
18006
- placementId: item.placementId,
18007
- spot: item.spotType,
18008
- count: item === null || item === void 0 ? void 0 : item.count,
18009
- ...item === null || item === void 0 ? void 0 : item.filter,
18010
- })),
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
+ }),
18011
18093
  };
18012
18094
  return this.spotSelection(request);
18013
18095
  }
@@ -18024,23 +18106,39 @@ class LiquidCommerceRmnClient {
18024
18106
  var _a;
18025
18107
  const carouselSlides = [];
18026
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);
18027
18116
  const spot = this.elementService.overrideSpotColors(spotItem, config === null || config === void 0 ? void 0 : config.colors);
18028
18117
  const content = SPOT_TEMPLATE_HTML_ELEMENT(spot, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
18029
18118
  if (!content) {
18030
- console.warn(`RmnSdk: Failed to inject carousel spot element. Could not create element for type "${spot.spot}".`);
18031
- return;
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
+ });
18125
+ continue;
18032
18126
  }
18033
- this.eventSpotElement({
18127
+ this.eventService.registerSpot({
18034
18128
  spot,
18035
18129
  placementId: placement.id,
18036
18130
  element: content,
18037
18131
  });
18038
18132
  carouselSlides.push(content);
18039
18133
  }
18040
- const { maxWidth, maxHeight } = spots.reduce((max, spot) => ({
18041
- maxWidth: Math.max(max.maxWidth, spot.width),
18042
- maxHeight: Math.max(max.maxHeight, spot.height),
18043
- }), { 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
18044
18142
  const carouselElement = this.elementService.createCarouselElement({
18045
18143
  slides: carouselSlides,
18046
18144
  config: {
@@ -18052,10 +18150,25 @@ class LiquidCommerceRmnClient {
18052
18150
  },
18053
18151
  });
18054
18152
  if (!carouselElement) {
18055
- console.warn(`RmnSdk: Failed to inject spot carousel element. Could not create spot carousel element.`);
18056
- return;
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
+ });
18159
+ return false;
18057
18160
  }
18058
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
+ });
18171
+ return true;
18059
18172
  }
18060
18173
  /**
18061
18174
  * Injects a single spot element into the provided placement.
@@ -18070,11 +18183,23 @@ class LiquidCommerceRmnClient {
18070
18183
  injectOneSpotElement(injectItem, placement, spot, config) {
18071
18184
  var _a;
18072
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
18073
18192
  const content = SPOT_TEMPLATE_HTML_ELEMENT(spotData, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
18074
18193
  if (!content) {
18075
- console.warn(`RmnSdk: Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`);
18076
- return;
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
+ });
18200
+ return false;
18077
18201
  }
18202
+ // Create the spot element
18078
18203
  const spotElement = this.elementService.createSpotElement({
18079
18204
  content,
18080
18205
  config: {
@@ -18086,22 +18211,30 @@ class LiquidCommerceRmnClient {
18086
18211
  },
18087
18212
  });
18088
18213
  if (!spotElement) {
18089
- console.warn(`RmnSdk: Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`);
18090
- return;
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
+ });
18220
+ return false;
18091
18221
  }
18092
- this.eventSpotElement({
18093
- spot,
18222
+ this.eventService.registerSpot({
18223
+ spot: spotData,
18094
18224
  placementId: injectItem.placementId,
18095
18225
  element: spotElement,
18096
18226
  });
18097
18227
  placement.replaceChildren(spotElement);
18098
- }
18099
- eventSpotElement({ spot, placementId, element, }) {
18100
- this.eventService.registerSpot({
18101
- placementId,
18102
- element,
18103
- spot,
18228
+ this.eventService.handleSpotState(injectItem.placementId, {
18229
+ dom: {
18230
+ element: spotElement,
18231
+ },
18232
+ state: {
18233
+ mounted: true,
18234
+ loading: false,
18235
+ },
18104
18236
  });
18237
+ return true;
18105
18238
  }
18106
18239
  /**
18107
18240
  * Prevents duplicate placement ids in the inject data.
@@ -18116,10 +18249,44 @@ class LiquidCommerceRmnClient {
18116
18249
  const placementIds = new Set();
18117
18250
  for (const item of inject) {
18118
18251
  if (placementIds.has(item.placementId)) {
18119
- throw new Error(`RmnSdk: Duplicate placement id (${item.placementId}) found. Please provide a unique placement id for each spot element.`);
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
+ });
18257
+ return false;
18120
18258
  }
18121
18259
  placementIds.add(item.placementId);
18122
18260
  }
18261
+ return true;
18262
+ }
18263
+ preventNonExistentSpotTypes(inject) {
18264
+ const newInject = [];
18265
+ for (const item of inject) {
18266
+ if (!Object.values(RMN_SPOT_TYPE).includes(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
+ });
18272
+ continue;
18273
+ }
18274
+ newInject.push(item);
18275
+ }
18276
+ return newInject;
18277
+ }
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
+ }
18123
18290
  }
18124
18291
  }
18125
18292
  /**
@@ -49,8 +49,7 @@ 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",
52
+ LIFECYCLE_STATE = "LIFECYCLE_STATE",
54
53
  IMPRESSION = "IMPRESSION",
55
54
  CLICK = "CLICK",
56
55
  PURCHASE = "PURCHASE",
@@ -4,16 +4,31 @@ export interface IFireEventParams {
4
4
  event: RMN_SPOT_EVENT;
5
5
  eventUrl: string;
6
6
  }
7
- export interface IMountedEvent {
7
+ export interface ILSIdentifier {
8
8
  placementId: string;
9
9
  spotId: string;
10
10
  spotType: string;
11
- spotVariant: string;
12
- element: HTMLElement;
13
11
  }
14
- export interface IUnMountedEvent {
15
- placementId: string;
16
- 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>;
17
32
  }
18
33
  export interface IClickEvent {
19
34
  placementId: string;
@@ -42,8 +57,7 @@ export interface IBuyNowEvent {
42
57
  spotId: string;
43
58
  }
44
59
  export interface IEventMap {
45
- [RMN_SPOT_EVENT.MOUNTED]: IMountedEvent;
46
- [RMN_SPOT_EVENT.UNMOUNTED]: IUnMountedEvent;
60
+ [RMN_SPOT_EVENT.LIFECYCLE_STATE]: ILifecycleState;
47
61
  [RMN_SPOT_EVENT.CLICK]: IClickEvent;
48
62
  [RMN_SPOT_EVENT.IMPRESSION]: IImpressionEvent;
49
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
  *
@@ -33,5 +33,7 @@ export interface ISpot {
33
33
  }
34
34
  export type ISpots = Record<PlacementIdType, ISpot[]>;
35
35
  export interface ISelectionService {
36
- spotSelection(data: ISpotSelectionParams): Promise<ISpots>;
36
+ spotSelection(data: ISpotSelectionParams): Promise<ISpots | {
37
+ error: string;
38
+ }>;
37
39
  }
@@ -10,7 +10,9 @@ export declare class SelectionService extends BaseApi implements ISelectionServi
10
10
  *
11
11
  * @param {ISpotSelectionParams} data - Spots selection parameters.
12
12
  *
13
- * @return {Promise<ISpots>} - The spots response object.
13
+ * @return {Promise<ISpots | { error: string }>} - The spots response object.
14
14
  */
15
- spotSelection(data: ISpotSelectionParams): Promise<ISpots>;
15
+ spotSelection(data: ISpotSelectionParams): Promise<ISpots | {
16
+ error: string;
17
+ }>;
16
18
  }