@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.cjs CHANGED
@@ -56,9 +56,7 @@ exports.RMN_FILTER_PROPERTIES = void 0;
56
56
  })(exports.RMN_FILTER_PROPERTIES || (exports.RMN_FILTER_PROPERTIES = {}));
57
57
  exports.RMN_SPOT_EVENT = void 0;
58
58
  (function (RMN_SPOT_EVENT) {
59
- RMN_SPOT_EVENT["INJECT_SPOTS"] = "INJECT_SPOTS";
60
- RMN_SPOT_EVENT["MOUNTED"] = "MOUNTED";
61
- RMN_SPOT_EVENT["UNMOUNTED"] = "UNMOUNTED";
59
+ RMN_SPOT_EVENT["LIFECYCLE_STATE"] = "LIFECYCLE_STATE";
62
60
  RMN_SPOT_EVENT["IMPRESSION"] = "IMPRESSION";
63
61
  RMN_SPOT_EVENT["CLICK"] = "CLICK";
64
62
  RMN_SPOT_EVENT["PURCHASE"] = "PURCHASE";
@@ -16828,11 +16826,11 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
16828
16826
  align-items: flex-start;
16829
16827
  width: 100%;
16830
16828
  height: fit-content;
16831
- gap: 5px;
16829
+ gap: 8px;
16832
16830
  }
16833
16831
 
16834
16832
  .${prefix}__header {
16835
- font-size: 18px;
16833
+ font-size: 24px;
16836
16834
  margin: 0;
16837
16835
  font-family: "Cormorant";
16838
16836
  font-style: normal;
@@ -16890,10 +16888,6 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
16890
16888
  height: 50%;
16891
16889
  }
16892
16890
 
16893
- .${prefix}__header {
16894
- font-size: 22px;
16895
- }
16896
-
16897
16891
  .${prefix}__description {
16898
16892
  font-size: 12px;
16899
16893
  }
@@ -16905,7 +16899,7 @@ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderCo
16905
16899
 
16906
16900
  @container (min-width: 1024px) {
16907
16901
  .${prefix}__header {
16908
- font-size: 24px;
16902
+ font-size: 26px;
16909
16903
  }
16910
16904
 
16911
16905
  .${prefix}__description {
@@ -16966,7 +16960,7 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16966
16960
  display: flex;
16967
16961
  flex-direction: column;
16968
16962
  background-color: transparent;
16969
- gap: 5px;
16963
+ gap: 6px;
16970
16964
  color: inherit;
16971
16965
  cursor: pointer;
16972
16966
  }
@@ -16985,7 +16979,7 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16985
16979
  height: 40%;
16986
16980
  display: flex;
16987
16981
  flex-direction: row;
16988
- gap: 5px;
16982
+ gap: 6px;
16989
16983
  }
16990
16984
 
16991
16985
  .${prefix}__secondary-image {
@@ -17007,7 +17001,7 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17007
17001
  align-items: center;
17008
17002
  width: 50%;
17009
17003
  height: 100%;
17010
- gap: 5px;
17004
+ gap: 10px;
17011
17005
  padding: 0 10px;
17012
17006
  box-sizing: border-box;
17013
17007
  }
@@ -17153,7 +17147,7 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17153
17147
  display: flex;
17154
17148
  flex-direction: column-reverse;
17155
17149
  background-color: transparent;
17156
- gap: 5px;
17150
+ gap: 6px;
17157
17151
  cursor: pointer;
17158
17152
  container-type: inline-size;
17159
17153
  position: relative;
@@ -17178,7 +17172,7 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
17178
17172
  align-items: center;
17179
17173
  width: 100%;
17180
17174
  height: 100%;
17181
- gap: 5px;
17175
+ gap: 10px;
17182
17176
  padding: 0 10px;
17183
17177
  box-sizing: border-box;
17184
17178
  }
@@ -17788,6 +17782,7 @@ class EventService {
17788
17782
  constructor() {
17789
17783
  this.pubSub = new PubSub();
17790
17784
  this.activeSpots = new Map();
17785
+ this.spotStates = new Map();
17791
17786
  this.intersectionObserver = new IntersectionObserverService();
17792
17787
  }
17793
17788
  static getInstance() {
@@ -17796,6 +17791,46 @@ class EventService {
17796
17791
  }
17797
17792
  return EventService.instance;
17798
17793
  }
17794
+ subscribe(eventType, callback) {
17795
+ return this.pubSub.subscribe(eventType, callback);
17796
+ }
17797
+ publish(eventType, data) {
17798
+ this.pubSub.publish(eventType, data);
17799
+ }
17800
+ handleSpotState(placementId, updates, publish = true) {
17801
+ let currentState = this.spotStates.get(placementId);
17802
+ if (!currentState) {
17803
+ currentState = {
17804
+ identifier: {
17805
+ placementId,
17806
+ spotId: '',
17807
+ spotType: '',
17808
+ },
17809
+ dom: {
17810
+ element: undefined,
17811
+ visible: false,
17812
+ },
17813
+ state: {
17814
+ mounted: false,
17815
+ unmounted: false,
17816
+ loading: false,
17817
+ error: undefined,
17818
+ },
17819
+ displayConfig: {
17820
+ isCarousel: false,
17821
+ isCarouselItem: false,
17822
+ isSingleItem: false,
17823
+ },
17824
+ };
17825
+ }
17826
+ this.spotStates.set(placementId, {
17827
+ ...currentState,
17828
+ ...updates,
17829
+ });
17830
+ if (publish) {
17831
+ this.pubSub.publish(exports.RMN_SPOT_EVENT.LIFECYCLE_STATE, this.spotStates.get(placementId));
17832
+ }
17833
+ }
17799
17834
  registerSpot({ placementId, element, spot }) {
17800
17835
  this.activeSpots.set(spot.id, {
17801
17836
  placementId,
@@ -17818,23 +17853,20 @@ class EventService {
17818
17853
  eventUrl: (_b = (_a = spot.events.find((event) => event.event === exports.RMN_SPOT_EVENT.CLICK)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '',
17819
17854
  });
17820
17855
  });
17821
- // Publish spot created event
17822
- this.pubSub.publish(exports.RMN_SPOT_EVENT.MOUNTED, {
17823
- placementId,
17824
- spotId: spot.id,
17825
- spotType: spot.spot,
17826
- spotVariant: spot.variant,
17827
- element,
17828
- });
17829
17856
  }
17830
17857
  unregisterSpot(spotId) {
17831
17858
  const spotData = this.activeSpots.get(spotId);
17832
17859
  if (spotData) {
17833
17860
  this.intersectionObserver.unobserve(spotData.element);
17834
- // this.resizeObserver?.disconnect();
17835
- this.pubSub.publish(exports.RMN_SPOT_EVENT.UNMOUNTED, {
17836
- placementId: spotData.placementId,
17837
- spotId,
17861
+ this.handleSpotState(spotData.placementId, {
17862
+ dom: {
17863
+ element: undefined,
17864
+ visible: false,
17865
+ },
17866
+ state: {
17867
+ unmounted: true,
17868
+ mounted: false,
17869
+ },
17838
17870
  });
17839
17871
  this.activeSpots.delete(spotId);
17840
17872
  }
@@ -17853,6 +17885,12 @@ class EventService {
17853
17885
  element,
17854
17886
  impressionTracked: true,
17855
17887
  });
17888
+ this.handleSpotState(placementId, {
17889
+ dom: {
17890
+ element,
17891
+ visible: true,
17892
+ },
17893
+ });
17856
17894
  // Fire impression event
17857
17895
  await this.fireEvent({
17858
17896
  event: exports.RMN_SPOT_EVENT.IMPRESSION,
@@ -17861,12 +17899,6 @@ class EventService {
17861
17899
  };
17862
17900
  this.intersectionObserver.observe(element, spotIsVisibleCb);
17863
17901
  }
17864
- subscribe(eventType, callback) {
17865
- return this.pubSub.subscribe(eventType, callback);
17866
- }
17867
- publish(eventType, data) {
17868
- this.pubSub.publish(eventType, data);
17869
- }
17870
17902
  /**
17871
17903
  * Fires an event using the navigator.sendBeacon method and redirects the user if the event is a click event.
17872
17904
  *
@@ -17932,6 +17964,21 @@ class SelectionService extends BaseApi {
17932
17964
 
17933
17965
  class LiquidCommerceRmnClient {
17934
17966
  constructor(auth) {
17967
+ /**
17968
+ * Returns the event manager instance.
17969
+ *
17970
+ * @return {EventService} - The event manager instance.
17971
+ */
17972
+ this.eventManager = {
17973
+ subscribe: (eventType, callback
17974
+ /* eslint-disable arrow-body-style */
17975
+ ) => {
17976
+ return this.eventService.subscribe(eventType, callback);
17977
+ },
17978
+ publish: (eventType, data) => {
17979
+ this.eventService.publish(eventType, data);
17980
+ },
17981
+ };
17935
17982
  this.selectionService = SelectionService.getInstance(auth);
17936
17983
  this.elementService = ElementService.getInstance();
17937
17984
  this.eventService = EventService.getInstance();
@@ -17959,36 +18006,56 @@ class LiquidCommerceRmnClient {
17959
18006
  var _a;
17960
18007
  const config = params.config;
17961
18008
  let inject = params.inject;
17962
- this.eventService.publish(exports.RMN_SPOT_EVENT.INJECT_SPOTS, {
17963
- isLoading: true,
17964
- isCompleted: false,
17965
- error: null,
17966
- });
17967
18009
  if (!inject.length) {
17968
- this.eventError('RmnSdk: Failed to inject spot element. Please provide at least one spot element to inject.');
18010
+ this.eventService.handleSpotState('all', {
18011
+ state: {
18012
+ error: 'No spot elements provided for injection.',
18013
+ loading: false,
18014
+ },
18015
+ });
17969
18016
  return;
17970
18017
  }
18018
+ // Update the state of the spots to loading
18019
+ this.updateSpotsState(inject);
18020
+ // Prevent duplicate placement ids
17971
18021
  const hasDuplicatePlacementIds = this.preventDuplicateSpotPlacementIds(inject);
17972
18022
  if (!hasDuplicatePlacementIds) {
17973
18023
  return;
17974
18024
  }
18025
+ // Prevent non-existent spot types
17975
18026
  inject = this.preventNonExistentSpotTypes(inject);
18027
+ // Make the spot selection request
17976
18028
  const response = await this.spotSelectionRequest({ ...params, inject });
18029
+ // Handle the response
17977
18030
  if (typeof response === 'object' && 'error' in response) {
17978
- this.eventError(response.error);
18031
+ this.eventService.handleSpotState('all', {
18032
+ state: {
18033
+ error: response.error,
18034
+ },
18035
+ });
17979
18036
  return;
17980
18037
  }
17981
18038
  for (const item of inject) {
17982
18039
  const itemConfig = (_a = item.config) !== null && _a !== void 0 ? _a : config;
17983
18040
  const spots = response[item.placementId];
17984
18041
  if (!(spots === null || spots === void 0 ? void 0 : spots.length)) {
17985
- this.eventError(`RmnSdk: Failed to inject spot element. No spots found for type "${item.spotType}".`, { placementId: item.placementId, type: item.spotType });
18042
+ this.eventService.handleSpotState(item.placementId, {
18043
+ state: {
18044
+ error: `No spots found for type "${item.spotType}".`,
18045
+ loading: false,
18046
+ },
18047
+ });
17986
18048
  continue;
17987
18049
  }
17988
18050
  const placementId = item.placementId.replace('#', '');
17989
18051
  const placement = document.getElementById(placementId);
17990
18052
  if (!placement) {
17991
- this.eventError(`RmnSdk: Failed to inject spot element. Placement not found for id "#${placementId}".`, { placementId, type: item.spotType });
18053
+ this.eventService.handleSpotState(item.placementId, {
18054
+ state: {
18055
+ error: `Placement not found for id "${placementId}".`,
18056
+ loading: false,
18057
+ },
18058
+ });
17992
18059
  continue;
17993
18060
  }
17994
18061
  if (spots.length === 1) {
@@ -18005,14 +18072,6 @@ class LiquidCommerceRmnClient {
18005
18072
  }
18006
18073
  }
18007
18074
  }
18008
- /**
18009
- * Returns the event manager instance.
18010
- *
18011
- * @return {EventService} - The event manager instance.
18012
- */
18013
- eventManager() {
18014
- return this.eventService;
18015
- }
18016
18075
  /**
18017
18076
  * Makes a selection request on our server based on the provided data.
18018
18077
  *
@@ -18025,12 +18084,14 @@ class LiquidCommerceRmnClient {
18025
18084
  const request = {
18026
18085
  url: config === null || config === void 0 ? void 0 : config.url,
18027
18086
  filter,
18028
- spots: inject.map((item) => ({
18029
- placementId: item.placementId,
18030
- spot: item.spotType,
18031
- count: item === null || item === void 0 ? void 0 : item.count,
18032
- ...item === null || item === void 0 ? void 0 : item.filter,
18033
- })),
18087
+ spots: inject.map((item) => {
18088
+ return {
18089
+ placementId: item.placementId,
18090
+ spot: item.spotType,
18091
+ count: item === null || item === void 0 ? void 0 : item.count,
18092
+ ...item === null || item === void 0 ? void 0 : item.filter,
18093
+ };
18094
+ }),
18034
18095
  };
18035
18096
  return this.spotSelection(request);
18036
18097
  }
@@ -18047,23 +18108,39 @@ class LiquidCommerceRmnClient {
18047
18108
  var _a;
18048
18109
  const carouselSlides = [];
18049
18110
  for (const spotItem of spots) {
18111
+ this.eventService.handleSpotState(placement.id, {
18112
+ displayConfig: {
18113
+ isCarousel: true,
18114
+ isCarouselItem: true,
18115
+ isSingleItem: false,
18116
+ },
18117
+ }, false);
18050
18118
  const spot = this.elementService.overrideSpotColors(spotItem, config === null || config === void 0 ? void 0 : config.colors);
18051
18119
  const content = SPOT_TEMPLATE_HTML_ELEMENT(spot, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
18052
18120
  if (!content) {
18053
- this.eventError(`RmnSdk: Failed to inject carousel spot element. Could not create element for type "${spot.spot}".`, { placementId: placement.id, type: spot.spot });
18121
+ this.eventService.handleSpotState(placement.id, {
18122
+ state: {
18123
+ error: `Failed to inject carousel spot item element. Could not create element for type "${spot.spot}".`,
18124
+ loading: false,
18125
+ },
18126
+ });
18054
18127
  continue;
18055
18128
  }
18056
- this.eventSpotElement({
18129
+ this.eventService.registerSpot({
18057
18130
  spot,
18058
18131
  placementId: placement.id,
18059
18132
  element: content,
18060
18133
  });
18061
18134
  carouselSlides.push(content);
18062
18135
  }
18063
- const { maxWidth, maxHeight } = spots.reduce((max, spot) => ({
18064
- maxWidth: Math.max(max.maxWidth, spot.width),
18065
- maxHeight: Math.max(max.maxHeight, spot.height),
18066
- }), { maxWidth: 0, maxHeight: 0 });
18136
+ // Get the max width and height of the spots
18137
+ const { maxWidth, maxHeight } = spots.reduce((max, spot) => {
18138
+ return {
18139
+ maxWidth: Math.max(max.maxWidth, spot.width),
18140
+ maxHeight: Math.max(max.maxHeight, spot.height),
18141
+ };
18142
+ }, { maxWidth: 0, maxHeight: 0 });
18143
+ // Create the carousel element
18067
18144
  const carouselElement = this.elementService.createCarouselElement({
18068
18145
  slides: carouselSlides,
18069
18146
  config: {
@@ -18075,10 +18152,24 @@ class LiquidCommerceRmnClient {
18075
18152
  },
18076
18153
  });
18077
18154
  if (!carouselElement) {
18078
- this.eventError(`RmnSdk: Failed to inject spot carousel element. Could not create spot carousel element.`, { placementId: placement.id });
18155
+ this.eventService.handleSpotState(placement.id, {
18156
+ state: {
18157
+ error: `Failed to inject spot carousel element. Could not create spot carousel element.`,
18158
+ loading: false,
18159
+ },
18160
+ });
18079
18161
  return false;
18080
18162
  }
18081
18163
  placement.replaceChildren(carouselElement);
18164
+ this.eventService.handleSpotState(placement.id, {
18165
+ dom: {
18166
+ element: carouselElement,
18167
+ },
18168
+ state: {
18169
+ mounted: true,
18170
+ loading: false,
18171
+ },
18172
+ });
18082
18173
  return true;
18083
18174
  }
18084
18175
  /**
@@ -18094,11 +18185,23 @@ class LiquidCommerceRmnClient {
18094
18185
  injectOneSpotElement(injectItem, placement, spot, config) {
18095
18186
  var _a;
18096
18187
  const spotData = this.elementService.overrideSpotColors(spot, config === null || config === void 0 ? void 0 : config.colors);
18188
+ this.eventService.handleSpotState(injectItem.placementId, {
18189
+ displayConfig: {
18190
+ isSingleItem: true,
18191
+ },
18192
+ }, false);
18193
+ // Create the spot template element
18097
18194
  const content = SPOT_TEMPLATE_HTML_ELEMENT(spotData, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
18098
18195
  if (!content) {
18099
- this.eventError(`RmnSdk: Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`, { placementId: injectItem.placementId, type: injectItem.spotType });
18196
+ this.eventService.handleSpotState(injectItem.placementId, {
18197
+ state: {
18198
+ error: `Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`,
18199
+ loading: false,
18200
+ },
18201
+ });
18100
18202
  return false;
18101
18203
  }
18204
+ // Create the spot element
18102
18205
  const spotElement = this.elementService.createSpotElement({
18103
18206
  content,
18104
18207
  config: {
@@ -18110,23 +18213,30 @@ class LiquidCommerceRmnClient {
18110
18213
  },
18111
18214
  });
18112
18215
  if (!spotElement) {
18113
- this.eventError(`RmnSdk: Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`, { placementId: injectItem.placementId, type: injectItem.spotType });
18216
+ this.eventService.handleSpotState(injectItem.placementId, {
18217
+ state: {
18218
+ error: `Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`,
18219
+ loading: false,
18220
+ },
18221
+ });
18114
18222
  return false;
18115
18223
  }
18116
- this.eventSpotElement({
18117
- spot,
18224
+ this.eventService.registerSpot({
18225
+ spot: spotData,
18118
18226
  placementId: injectItem.placementId,
18119
18227
  element: spotElement,
18120
18228
  });
18121
18229
  placement.replaceChildren(spotElement);
18122
- return true;
18123
- }
18124
- eventSpotElement({ spot, placementId, element, }) {
18125
- this.eventService.registerSpot({
18126
- placementId,
18127
- element,
18128
- spot,
18230
+ this.eventService.handleSpotState(injectItem.placementId, {
18231
+ dom: {
18232
+ element: spotElement,
18233
+ },
18234
+ state: {
18235
+ mounted: true,
18236
+ loading: false,
18237
+ },
18129
18238
  });
18239
+ return true;
18130
18240
  }
18131
18241
  /**
18132
18242
  * Prevents duplicate placement ids in the inject data.
@@ -18141,7 +18251,11 @@ class LiquidCommerceRmnClient {
18141
18251
  const placementIds = new Set();
18142
18252
  for (const item of inject) {
18143
18253
  if (placementIds.has(item.placementId)) {
18144
- 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 });
18254
+ this.eventService.handleSpotState(item.placementId, {
18255
+ state: {
18256
+ error: `Duplicate placement id (${item.placementId}) found. Please provide a unique placement id for each spot element.`,
18257
+ },
18258
+ });
18145
18259
  return false;
18146
18260
  }
18147
18261
  placementIds.add(item.placementId);
@@ -18152,22 +18266,29 @@ class LiquidCommerceRmnClient {
18152
18266
  const newInject = [];
18153
18267
  for (const item of inject) {
18154
18268
  if (!Object.values(exports.RMN_SPOT_TYPE).includes(item.spotType)) {
18155
- 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 });
18269
+ this.eventService.handleSpotState(item.placementId, {
18270
+ state: {
18271
+ error: `Invalid spot type (${item.spotType}) found. Please provide a valid spot type for each spot element.`,
18272
+ },
18273
+ });
18156
18274
  continue;
18157
18275
  }
18158
18276
  newInject.push(item);
18159
18277
  }
18160
18278
  return newInject;
18161
18279
  }
18162
- eventError(error, spot) {
18163
- this.eventService.publish(exports.RMN_SPOT_EVENT.INJECT_SPOTS, {
18164
- isLoading: false,
18165
- isCompleted: true,
18166
- error: {
18167
- message: error,
18168
- spot,
18169
- },
18170
- });
18280
+ updateSpotsState(inject) {
18281
+ for (const item of inject) {
18282
+ this.eventService.handleSpotState(item.placementId, {
18283
+ identifier: {
18284
+ placementId: item.placementId,
18285
+ spotType: item.spotType,
18286
+ },
18287
+ state: {
18288
+ loading: true,
18289
+ },
18290
+ });
18291
+ }
18171
18292
  }
18172
18293
  }
18173
18294
  /**