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

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 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
  /**