@liquidcommercedev/rmn-sdk 1.5.0-beta.29 → 1.5.0-beta.30

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
@@ -17202,8 +17202,9 @@ var ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX;
17202
17202
  ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_ID"] = 1] = "SPOT_ID";
17203
17203
  ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_TYPE"] = 2] = "SPOT_TYPE";
17204
17204
  ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["EVENTS"] = 3] = "EVENTS";
17205
- ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["PRODUCT_IDS"] = 4] = "PRODUCT_IDS";
17206
- ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["CREATED_AT"] = 5] = "CREATED_AT";
17205
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["FIRED_EVENTS"] = 4] = "FIRED_EVENTS";
17206
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["PRODUCT_IDS"] = 5] = "PRODUCT_IDS";
17207
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["CREATED_AT"] = 6] = "CREATED_AT";
17207
17208
  })(ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX || (ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX = {}));
17208
17209
  const LOCAL_STORAGE_SPOT_EVENTS_ARRAY_INDEX = {
17209
17210
  [exports.RMN_SPOT_EVENT.IMPRESSION]: 0,
@@ -17259,9 +17260,14 @@ class LocalStorageService {
17259
17260
  }
17260
17261
  }
17261
17262
  setSpot(spotId, data) {
17262
- var _a;
17263
+ var _a, _b, _c, _d;
17263
17264
  data.createdAt = Date.now();
17264
- (_a = this.spots) === null || _a === void 0 ? void 0 : _a.set(spotId, data);
17265
+ const isExistentSpot = (_a = this.spots) === null || _a === void 0 ? void 0 : _a.has(spotId);
17266
+ if (isExistentSpot) {
17267
+ const existingData = (_b = this.spots) === null || _b === void 0 ? void 0 : _b.get(spotId);
17268
+ data.firedEvents = (_c = existingData === null || existingData === void 0 ? void 0 : existingData.firedEvents) !== null && _c !== void 0 ? _c : [];
17269
+ }
17270
+ (_d = this.spots) === null || _d === void 0 ? void 0 : _d.set(spotId, data);
17265
17271
  this.updateLocalStorage();
17266
17272
  }
17267
17273
  removeSpot(spotId) {
@@ -17278,38 +17284,12 @@ class LocalStorageService {
17278
17284
  return undefined;
17279
17285
  return this.mapToObject(this.spots);
17280
17286
  }
17281
- updateLocalStorage() {
17282
- if (!this.spots)
17283
- return undefined;
17284
- const data = this.mapToObject(this.spots);
17285
- const dataArray = {};
17286
- for (const [key, value] of Object.entries(data)) {
17287
- dataArray[key] = this.spotObjectToArray(value);
17288
- }
17289
- try {
17290
- const encryptedData = this.encryptData(JSON.stringify(dataArray));
17291
- window.localStorage.setItem(LocalStorageService.localStorageKey, encryptedData);
17292
- }
17293
- catch (_a) {
17294
- // If there is an error parsing the data, clear the local storage to prevent any issues
17295
- this.clearLocalStorage();
17296
- }
17297
- }
17298
- clearLocalStorage() {
17299
- window.localStorage.removeItem(LocalStorageService.localStorageKey);
17300
- }
17301
- removeExpiredSpots() {
17302
- var _a;
17303
- const currentTime = Date.now();
17304
- (_a = this.spots) === null || _a === void 0 ? void 0 : _a.forEach((spot, spotId) => {
17305
- var _a, _b;
17306
- if (currentTime - ((_a = spot.createdAt) !== null && _a !== void 0 ? _a : 0) > LocalStorageService.spotExpirationTime) {
17307
- (_b = this.spots) === null || _b === void 0 ? void 0 : _b.delete(spotId);
17308
- }
17309
- });
17310
- this.updateLocalStorage();
17311
- }
17312
- // ======================== Utility functions ======================== //
17287
+ /**
17288
+ * Retrieves the user ID from the local storage key.
17289
+ * If the key is not found, a new user ID is generated and set.
17290
+ *
17291
+ * @return the user ID extracted from the local storage key
17292
+ */
17313
17293
  getUserId() {
17314
17294
  const key = LocalStorageService.localStorageKey;
17315
17295
  if (!key) {
@@ -17318,9 +17298,11 @@ class LocalStorageService {
17318
17298
  return key.replace(`${LocalStorageService.localStorageKeyPrefix}_`, '');
17319
17299
  }
17320
17300
  /**
17321
- * Sets the user ID in the local storage.
17322
- * If no existing key is found,
17323
- * it generates a new unique ID and sets it as the local storage key.
17301
+ * Sets the user ID in local storage with a unique key if not already present.
17302
+ * If there are existing keys, it ensures only one valid key remains,
17303
+ * removing all other keys.
17304
+ *
17305
+ * @return {void} This method does not return a value.
17324
17306
  */
17325
17307
  setUserId() {
17326
17308
  const prefix = LocalStorageService.localStorageKeyPrefix;
@@ -17352,6 +17334,38 @@ class LocalStorageService {
17352
17334
  }
17353
17335
  }
17354
17336
  }
17337
+ // ======================== Utility functions ======================== //
17338
+ updateLocalStorage() {
17339
+ if (!this.spots)
17340
+ return undefined;
17341
+ const data = this.mapToObject(this.spots);
17342
+ const dataArray = {};
17343
+ for (const [key, value] of Object.entries(data)) {
17344
+ dataArray[key] = this.spotObjectToArray(value);
17345
+ }
17346
+ try {
17347
+ const encryptedData = this.encryptData(JSON.stringify(dataArray));
17348
+ window.localStorage.setItem(LocalStorageService.localStorageKey, encryptedData);
17349
+ }
17350
+ catch (_a) {
17351
+ // If there is an error parsing the data, clear the local storage to prevent any issues
17352
+ this.clearLocalStorage();
17353
+ }
17354
+ }
17355
+ clearLocalStorage() {
17356
+ window.localStorage.removeItem(LocalStorageService.localStorageKey);
17357
+ }
17358
+ removeExpiredSpots() {
17359
+ var _a;
17360
+ const currentTime = Date.now();
17361
+ (_a = this.spots) === null || _a === void 0 ? void 0 : _a.forEach((spot, spotId) => {
17362
+ var _a, _b;
17363
+ if (currentTime - ((_a = spot.createdAt) !== null && _a !== void 0 ? _a : 0) > LocalStorageService.spotExpirationTime) {
17364
+ (_b = this.spots) === null || _b === void 0 ? void 0 : _b.delete(spotId);
17365
+ }
17366
+ });
17367
+ this.updateLocalStorage();
17368
+ }
17355
17369
  mapToObject(map) {
17356
17370
  return Object.fromEntries(map);
17357
17371
  }
@@ -17370,39 +17384,76 @@ class LocalStorageService {
17370
17384
  url: arr[LOCAL_STORAGE_SPOT_EVENTS_ARRAY_INDEX[type]],
17371
17385
  }));
17372
17386
  }
17387
+ /**
17388
+ * Converts a spot object to an array.
17389
+ *
17390
+ * @param {ILocalStorageSpot} obj - The spot object to convert.
17391
+ * @return {LocalStorageSpotArray} An array representation of the spot object.
17392
+ */
17373
17393
  spotObjectToArray(obj) {
17374
17394
  return [
17375
17395
  obj.placementId,
17376
17396
  obj.spotId,
17377
17397
  obj.spotType,
17378
17398
  this.spotEventObjectToArray(obj.events),
17399
+ obj.firedEvents.map((event) => [event.productId, event.event]),
17379
17400
  obj.productIds,
17380
17401
  obj.createdAt,
17381
17402
  ];
17382
17403
  }
17404
+ /**
17405
+ * Converts an array representation of spot data into an object representation.
17406
+ *
17407
+ * @param {LocalStorageSpotArray} arr - The array containing spot data.
17408
+ * @return {ILocalStorageSpot} An object representation of the spot data.
17409
+ */
17383
17410
  spotArrayToObject(arr) {
17384
17411
  return {
17385
17412
  placementId: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.PLACEMENT_ID],
17386
17413
  spotId: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_ID],
17387
17414
  spotType: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_TYPE],
17388
17415
  events: this.spotEventArrayToObject(arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.EVENTS]),
17416
+ firedEvents: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.FIRED_EVENTS].map((item) => ({
17417
+ productId: item[0],
17418
+ event: item[1],
17419
+ })),
17389
17420
  productIds: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.PRODUCT_IDS],
17390
17421
  createdAt: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.CREATED_AT],
17391
17422
  };
17392
17423
  }
17424
+ /**
17425
+ * Encodes a given string into a Unicode-encoded base64 format.
17426
+ *
17427
+ * @param {string} str - The string to be encoded.
17428
+ * @return {string} The Unicode-encoded base64 representation of the input string.
17429
+ */
17430
+ unicodeEncode(str) {
17431
+ return btoa(Array.from(new TextEncoder().encode(str))
17432
+ .map((byte) => String.fromCharCode(byte))
17433
+ .join(''));
17434
+ }
17435
+ /**
17436
+ * Decodes a Base64 encoded Unicode string.
17437
+ *
17438
+ * @param {string} str - The Base64 encoded string to decode.
17439
+ * @return {string} The decoded Unicode string.
17440
+ */
17441
+ unicodeDecode(str) {
17442
+ return new TextDecoder().decode(Uint8Array.from(atob(str), (char) => char.charCodeAt(0)));
17443
+ }
17393
17444
  encryptData(data) {
17394
17445
  if (!LocalStorageService.encryptData)
17395
17446
  return data;
17396
17447
  // For now, we are using base64 encoding to encrypt the data
17397
17448
  // Later we will use Jose encryption
17398
- return btoa(data);
17449
+ return this.unicodeEncode(data);
17399
17450
  }
17400
17451
  decryptData(data) {
17401
17452
  if (!LocalStorageService.encryptData)
17402
17453
  return data;
17403
17454
  // For now, we are using base64 encoding to encrypt
17404
17455
  // Later we will use Jose encryption
17405
- return atob(data);
17456
+ return this.unicodeDecode(data);
17406
17457
  }
17407
17458
  }
17408
17459
  LocalStorageService.localStorageKeyPrefix = 'lc_rmn';
@@ -20742,8 +20793,13 @@ class MonitorService {
20742
20793
  if (!Object.values(exports.RMN_SPOT_EVENT).includes(eventData.event)) {
20743
20794
  continue;
20744
20795
  }
20745
- const spotRelatedProductIdsSet = new Set(cleanProductIds(spot.productIds));
20796
+ const firedEvents = spot.firedEvents;
20746
20797
  const [eventProductId] = cleanProductIds([data.id]);
20798
+ const isEventAlreadyFired = firedEvents.some((event) => event.productId === eventProductId && event.event === eventData.event);
20799
+ if (isEventAlreadyFired) {
20800
+ continue;
20801
+ }
20802
+ const spotRelatedProductIdsSet = new Set(cleanProductIds(spot.productIds));
20747
20803
  const [eventProductBrand] = cleanProductIds([data.brand]);
20748
20804
  const [eventVariantBrand] = cleanProductIds([data.variant]);
20749
20805
  const isProductMatch = [eventProductId, eventProductBrand, eventVariantBrand].some((id) => spotRelatedProductIdsSet.has(id));
@@ -20767,14 +20823,18 @@ class MonitorService {
20767
20823
  placementId: spot.placementId,
20768
20824
  spotId: spot.spotId,
20769
20825
  });
20770
- // Remove the event url from the spot to prevent duplicate events
20771
- spot.events[eventPosition].url = '';
20826
+ // Add the fired event of the product to spot fired events
20827
+ firedEvents.push({
20828
+ productId: eventProductId,
20829
+ event: eventData.event,
20830
+ });
20772
20831
  // Update the spots in the local storage
20773
20832
  (_a = this.localStorageService) === null || _a === void 0 ? void 0 : _a.setSpot(spot.spotId, {
20774
20833
  placementId: spot.placementId,
20775
20834
  spotId: spot.spotId,
20776
20835
  spotType: spot.spotType,
20777
20836
  events: spot.events,
20837
+ firedEvents,
20778
20838
  productIds: spot.productIds,
20779
20839
  });
20780
20840
  }
@@ -20932,6 +20992,7 @@ class EventService {
20932
20992
  spotType: spot.spot,
20933
20993
  events: spot.events,
20934
20994
  productIds: (_a = spot.productIds) !== null && _a !== void 0 ? _a : [],
20995
+ firedEvents: [],
20935
20996
  });
20936
20997
  }
20937
20998
  async handleClickEvent({ placementId, spot }) {
@@ -21208,6 +21269,7 @@ class LiquidCommerceRmnClient {
21208
21269
  // Validate inject data
21209
21270
  const inject = validateInjectData(params.inject);
21210
21271
  const placementElementShowedInDOM = (placement) => {
21272
+ var _a, _b;
21211
21273
  const data = inject.find((item) => item.placementId === placement.id);
21212
21274
  // Handle placement not found error state
21213
21275
  if (!data) {
@@ -21229,7 +21291,7 @@ class LiquidCommerceRmnClient {
21229
21291
  }, false);
21230
21292
  prepareSpotPlacement(placement);
21231
21293
  const skeletonElement = this.elementService.createSkeletonElement({
21232
- fluid: config === null || config === void 0 ? void 0 : config.fluid,
21294
+ fluid: (_b = (_a = data === null || data === void 0 ? void 0 : data.config) === null || _a === void 0 ? void 0 : _a.fluid) !== null && _b !== void 0 ? _b : config === null || config === void 0 ? void 0 : config.fluid,
21233
21295
  spotType: data.spotType,
21234
21296
  });
21235
21297
  // Handle skeleton loader error state
package/dist/index.esm.js CHANGED
@@ -17200,8 +17200,9 @@ var ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX;
17200
17200
  ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_ID"] = 1] = "SPOT_ID";
17201
17201
  ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_TYPE"] = 2] = "SPOT_TYPE";
17202
17202
  ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["EVENTS"] = 3] = "EVENTS";
17203
- ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["PRODUCT_IDS"] = 4] = "PRODUCT_IDS";
17204
- ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["CREATED_AT"] = 5] = "CREATED_AT";
17203
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["FIRED_EVENTS"] = 4] = "FIRED_EVENTS";
17204
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["PRODUCT_IDS"] = 5] = "PRODUCT_IDS";
17205
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["CREATED_AT"] = 6] = "CREATED_AT";
17205
17206
  })(ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX || (ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX = {}));
17206
17207
  const LOCAL_STORAGE_SPOT_EVENTS_ARRAY_INDEX = {
17207
17208
  [RMN_SPOT_EVENT.IMPRESSION]: 0,
@@ -17257,9 +17258,14 @@ class LocalStorageService {
17257
17258
  }
17258
17259
  }
17259
17260
  setSpot(spotId, data) {
17260
- var _a;
17261
+ var _a, _b, _c, _d;
17261
17262
  data.createdAt = Date.now();
17262
- (_a = this.spots) === null || _a === void 0 ? void 0 : _a.set(spotId, data);
17263
+ const isExistentSpot = (_a = this.spots) === null || _a === void 0 ? void 0 : _a.has(spotId);
17264
+ if (isExistentSpot) {
17265
+ const existingData = (_b = this.spots) === null || _b === void 0 ? void 0 : _b.get(spotId);
17266
+ data.firedEvents = (_c = existingData === null || existingData === void 0 ? void 0 : existingData.firedEvents) !== null && _c !== void 0 ? _c : [];
17267
+ }
17268
+ (_d = this.spots) === null || _d === void 0 ? void 0 : _d.set(spotId, data);
17263
17269
  this.updateLocalStorage();
17264
17270
  }
17265
17271
  removeSpot(spotId) {
@@ -17276,38 +17282,12 @@ class LocalStorageService {
17276
17282
  return undefined;
17277
17283
  return this.mapToObject(this.spots);
17278
17284
  }
17279
- updateLocalStorage() {
17280
- if (!this.spots)
17281
- return undefined;
17282
- const data = this.mapToObject(this.spots);
17283
- const dataArray = {};
17284
- for (const [key, value] of Object.entries(data)) {
17285
- dataArray[key] = this.spotObjectToArray(value);
17286
- }
17287
- try {
17288
- const encryptedData = this.encryptData(JSON.stringify(dataArray));
17289
- window.localStorage.setItem(LocalStorageService.localStorageKey, encryptedData);
17290
- }
17291
- catch (_a) {
17292
- // If there is an error parsing the data, clear the local storage to prevent any issues
17293
- this.clearLocalStorage();
17294
- }
17295
- }
17296
- clearLocalStorage() {
17297
- window.localStorage.removeItem(LocalStorageService.localStorageKey);
17298
- }
17299
- removeExpiredSpots() {
17300
- var _a;
17301
- const currentTime = Date.now();
17302
- (_a = this.spots) === null || _a === void 0 ? void 0 : _a.forEach((spot, spotId) => {
17303
- var _a, _b;
17304
- if (currentTime - ((_a = spot.createdAt) !== null && _a !== void 0 ? _a : 0) > LocalStorageService.spotExpirationTime) {
17305
- (_b = this.spots) === null || _b === void 0 ? void 0 : _b.delete(spotId);
17306
- }
17307
- });
17308
- this.updateLocalStorage();
17309
- }
17310
- // ======================== Utility functions ======================== //
17285
+ /**
17286
+ * Retrieves the user ID from the local storage key.
17287
+ * If the key is not found, a new user ID is generated and set.
17288
+ *
17289
+ * @return the user ID extracted from the local storage key
17290
+ */
17311
17291
  getUserId() {
17312
17292
  const key = LocalStorageService.localStorageKey;
17313
17293
  if (!key) {
@@ -17316,9 +17296,11 @@ class LocalStorageService {
17316
17296
  return key.replace(`${LocalStorageService.localStorageKeyPrefix}_`, '');
17317
17297
  }
17318
17298
  /**
17319
- * Sets the user ID in the local storage.
17320
- * If no existing key is found,
17321
- * it generates a new unique ID and sets it as the local storage key.
17299
+ * Sets the user ID in local storage with a unique key if not already present.
17300
+ * If there are existing keys, it ensures only one valid key remains,
17301
+ * removing all other keys.
17302
+ *
17303
+ * @return {void} This method does not return a value.
17322
17304
  */
17323
17305
  setUserId() {
17324
17306
  const prefix = LocalStorageService.localStorageKeyPrefix;
@@ -17350,6 +17332,38 @@ class LocalStorageService {
17350
17332
  }
17351
17333
  }
17352
17334
  }
17335
+ // ======================== Utility functions ======================== //
17336
+ updateLocalStorage() {
17337
+ if (!this.spots)
17338
+ return undefined;
17339
+ const data = this.mapToObject(this.spots);
17340
+ const dataArray = {};
17341
+ for (const [key, value] of Object.entries(data)) {
17342
+ dataArray[key] = this.spotObjectToArray(value);
17343
+ }
17344
+ try {
17345
+ const encryptedData = this.encryptData(JSON.stringify(dataArray));
17346
+ window.localStorage.setItem(LocalStorageService.localStorageKey, encryptedData);
17347
+ }
17348
+ catch (_a) {
17349
+ // If there is an error parsing the data, clear the local storage to prevent any issues
17350
+ this.clearLocalStorage();
17351
+ }
17352
+ }
17353
+ clearLocalStorage() {
17354
+ window.localStorage.removeItem(LocalStorageService.localStorageKey);
17355
+ }
17356
+ removeExpiredSpots() {
17357
+ var _a;
17358
+ const currentTime = Date.now();
17359
+ (_a = this.spots) === null || _a === void 0 ? void 0 : _a.forEach((spot, spotId) => {
17360
+ var _a, _b;
17361
+ if (currentTime - ((_a = spot.createdAt) !== null && _a !== void 0 ? _a : 0) > LocalStorageService.spotExpirationTime) {
17362
+ (_b = this.spots) === null || _b === void 0 ? void 0 : _b.delete(spotId);
17363
+ }
17364
+ });
17365
+ this.updateLocalStorage();
17366
+ }
17353
17367
  mapToObject(map) {
17354
17368
  return Object.fromEntries(map);
17355
17369
  }
@@ -17368,39 +17382,76 @@ class LocalStorageService {
17368
17382
  url: arr[LOCAL_STORAGE_SPOT_EVENTS_ARRAY_INDEX[type]],
17369
17383
  }));
17370
17384
  }
17385
+ /**
17386
+ * Converts a spot object to an array.
17387
+ *
17388
+ * @param {ILocalStorageSpot} obj - The spot object to convert.
17389
+ * @return {LocalStorageSpotArray} An array representation of the spot object.
17390
+ */
17371
17391
  spotObjectToArray(obj) {
17372
17392
  return [
17373
17393
  obj.placementId,
17374
17394
  obj.spotId,
17375
17395
  obj.spotType,
17376
17396
  this.spotEventObjectToArray(obj.events),
17397
+ obj.firedEvents.map((event) => [event.productId, event.event]),
17377
17398
  obj.productIds,
17378
17399
  obj.createdAt,
17379
17400
  ];
17380
17401
  }
17402
+ /**
17403
+ * Converts an array representation of spot data into an object representation.
17404
+ *
17405
+ * @param {LocalStorageSpotArray} arr - The array containing spot data.
17406
+ * @return {ILocalStorageSpot} An object representation of the spot data.
17407
+ */
17381
17408
  spotArrayToObject(arr) {
17382
17409
  return {
17383
17410
  placementId: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.PLACEMENT_ID],
17384
17411
  spotId: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_ID],
17385
17412
  spotType: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_TYPE],
17386
17413
  events: this.spotEventArrayToObject(arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.EVENTS]),
17414
+ firedEvents: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.FIRED_EVENTS].map((item) => ({
17415
+ productId: item[0],
17416
+ event: item[1],
17417
+ })),
17387
17418
  productIds: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.PRODUCT_IDS],
17388
17419
  createdAt: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.CREATED_AT],
17389
17420
  };
17390
17421
  }
17422
+ /**
17423
+ * Encodes a given string into a Unicode-encoded base64 format.
17424
+ *
17425
+ * @param {string} str - The string to be encoded.
17426
+ * @return {string} The Unicode-encoded base64 representation of the input string.
17427
+ */
17428
+ unicodeEncode(str) {
17429
+ return btoa(Array.from(new TextEncoder().encode(str))
17430
+ .map((byte) => String.fromCharCode(byte))
17431
+ .join(''));
17432
+ }
17433
+ /**
17434
+ * Decodes a Base64 encoded Unicode string.
17435
+ *
17436
+ * @param {string} str - The Base64 encoded string to decode.
17437
+ * @return {string} The decoded Unicode string.
17438
+ */
17439
+ unicodeDecode(str) {
17440
+ return new TextDecoder().decode(Uint8Array.from(atob(str), (char) => char.charCodeAt(0)));
17441
+ }
17391
17442
  encryptData(data) {
17392
17443
  if (!LocalStorageService.encryptData)
17393
17444
  return data;
17394
17445
  // For now, we are using base64 encoding to encrypt the data
17395
17446
  // Later we will use Jose encryption
17396
- return btoa(data);
17447
+ return this.unicodeEncode(data);
17397
17448
  }
17398
17449
  decryptData(data) {
17399
17450
  if (!LocalStorageService.encryptData)
17400
17451
  return data;
17401
17452
  // For now, we are using base64 encoding to encrypt
17402
17453
  // Later we will use Jose encryption
17403
- return atob(data);
17454
+ return this.unicodeDecode(data);
17404
17455
  }
17405
17456
  }
17406
17457
  LocalStorageService.localStorageKeyPrefix = 'lc_rmn';
@@ -20740,8 +20791,13 @@ class MonitorService {
20740
20791
  if (!Object.values(RMN_SPOT_EVENT).includes(eventData.event)) {
20741
20792
  continue;
20742
20793
  }
20743
- const spotRelatedProductIdsSet = new Set(cleanProductIds(spot.productIds));
20794
+ const firedEvents = spot.firedEvents;
20744
20795
  const [eventProductId] = cleanProductIds([data.id]);
20796
+ const isEventAlreadyFired = firedEvents.some((event) => event.productId === eventProductId && event.event === eventData.event);
20797
+ if (isEventAlreadyFired) {
20798
+ continue;
20799
+ }
20800
+ const spotRelatedProductIdsSet = new Set(cleanProductIds(spot.productIds));
20745
20801
  const [eventProductBrand] = cleanProductIds([data.brand]);
20746
20802
  const [eventVariantBrand] = cleanProductIds([data.variant]);
20747
20803
  const isProductMatch = [eventProductId, eventProductBrand, eventVariantBrand].some((id) => spotRelatedProductIdsSet.has(id));
@@ -20765,14 +20821,18 @@ class MonitorService {
20765
20821
  placementId: spot.placementId,
20766
20822
  spotId: spot.spotId,
20767
20823
  });
20768
- // Remove the event url from the spot to prevent duplicate events
20769
- spot.events[eventPosition].url = '';
20824
+ // Add the fired event of the product to spot fired events
20825
+ firedEvents.push({
20826
+ productId: eventProductId,
20827
+ event: eventData.event,
20828
+ });
20770
20829
  // Update the spots in the local storage
20771
20830
  (_a = this.localStorageService) === null || _a === void 0 ? void 0 : _a.setSpot(spot.spotId, {
20772
20831
  placementId: spot.placementId,
20773
20832
  spotId: spot.spotId,
20774
20833
  spotType: spot.spotType,
20775
20834
  events: spot.events,
20835
+ firedEvents,
20776
20836
  productIds: spot.productIds,
20777
20837
  });
20778
20838
  }
@@ -20930,6 +20990,7 @@ class EventService {
20930
20990
  spotType: spot.spot,
20931
20991
  events: spot.events,
20932
20992
  productIds: (_a = spot.productIds) !== null && _a !== void 0 ? _a : [],
20993
+ firedEvents: [],
20933
20994
  });
20934
20995
  }
20935
20996
  async handleClickEvent({ placementId, spot }) {
@@ -21206,6 +21267,7 @@ class LiquidCommerceRmnClient {
21206
21267
  // Validate inject data
21207
21268
  const inject = validateInjectData(params.inject);
21208
21269
  const placementElementShowedInDOM = (placement) => {
21270
+ var _a, _b;
21209
21271
  const data = inject.find((item) => item.placementId === placement.id);
21210
21272
  // Handle placement not found error state
21211
21273
  if (!data) {
@@ -21227,7 +21289,7 @@ class LiquidCommerceRmnClient {
21227
21289
  }, false);
21228
21290
  prepareSpotPlacement(placement);
21229
21291
  const skeletonElement = this.elementService.createSkeletonElement({
21230
- fluid: config === null || config === void 0 ? void 0 : config.fluid,
21292
+ fluid: (_b = (_a = data === null || data === void 0 ? void 0 : data.config) === null || _a === void 0 ? void 0 : _a.fluid) !== null && _b !== void 0 ? _b : config === null || config === void 0 ? void 0 : config.fluid,
21231
21293
  spotType: data.spotType,
21232
21294
  });
21233
21295
  // Handle skeleton loader error state
@@ -1,10 +1,16 @@
1
1
  import type { RMN_SPOT_TYPE } from 'enums';
2
+ import { RMN_SPOT_EVENT } from 'enums';
2
3
  import type { ISpotEvent } from 'modules/selection';
4
+ export interface IFiredSpotEvent {
5
+ productId: string;
6
+ event: RMN_SPOT_EVENT;
7
+ }
3
8
  export interface ILocalStorageSpot {
4
9
  placementId: string;
5
10
  spotId: string;
6
11
  spotType: RMN_SPOT_TYPE;
7
12
  events: ISpotEvent[];
13
+ firedEvents: IFiredSpotEvent[];
8
14
  productIds: Array<string | number>;
9
15
  createdAt?: number;
10
16
  }
@@ -17,8 +23,9 @@ export type LocalStorageSpotArray = [
17
23
  string,
18
24
  RMN_SPOT_TYPE,
19
25
  string[],
26
+ Array<[string, RMN_SPOT_EVENT]>,
20
27
  Array<string | number>,
21
- // PRODUCT_IDS = 4
28
+ // PRODUCT_IDS = 5
22
29
  number | undefined
23
30
  ];
24
31
  export declare enum ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX {
@@ -26,8 +33,9 @@ export declare enum ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX {
26
33
  SPOT_ID = 1,
27
34
  SPOT_TYPE = 2,
28
35
  EVENTS = 3,
29
- PRODUCT_IDS = 4,
30
- CREATED_AT = 5
36
+ FIRED_EVENTS = 4,
37
+ PRODUCT_IDS = 5,
38
+ CREATED_AT = 6
31
39
  }
32
40
  export declare const LOCAL_STORAGE_SPOT_EVENTS_ARRAY_INDEX: {
33
41
  readonly IMPRESSION: 0;
@@ -56,22 +64,56 @@ export declare class LocalStorageService {
56
64
  removeSpot(spotId: string): void;
57
65
  getSpot(spotId: string): ILocalStorageSpot | undefined;
58
66
  getSpots(): LocalStorageSpotsObjectType | undefined;
59
- private updateLocalStorage;
60
- private clearLocalStorage;
61
- private removeExpiredSpots;
67
+ /**
68
+ * Retrieves the user ID from the local storage key.
69
+ * If the key is not found, a new user ID is generated and set.
70
+ *
71
+ * @return the user ID extracted from the local storage key
72
+ */
62
73
  getUserId(): string;
63
74
  /**
64
- * Sets the user ID in the local storage.
65
- * If no existing key is found,
66
- * it generates a new unique ID and sets it as the local storage key.
75
+ * Sets the user ID in local storage with a unique key if not already present.
76
+ * If there are existing keys, it ensures only one valid key remains,
77
+ * removing all other keys.
78
+ *
79
+ * @return {void} This method does not return a value.
67
80
  */
68
81
  setUserId(): void;
82
+ private updateLocalStorage;
83
+ private clearLocalStorage;
84
+ private removeExpiredSpots;
69
85
  private mapToObject;
70
86
  private objectToMap;
71
87
  private spotEventObjectToArray;
72
88
  private spotEventArrayToObject;
89
+ /**
90
+ * Converts a spot object to an array.
91
+ *
92
+ * @param {ILocalStorageSpot} obj - The spot object to convert.
93
+ * @return {LocalStorageSpotArray} An array representation of the spot object.
94
+ */
73
95
  private spotObjectToArray;
96
+ /**
97
+ * Converts an array representation of spot data into an object representation.
98
+ *
99
+ * @param {LocalStorageSpotArray} arr - The array containing spot data.
100
+ * @return {ILocalStorageSpot} An object representation of the spot data.
101
+ */
74
102
  private spotArrayToObject;
103
+ /**
104
+ * Encodes a given string into a Unicode-encoded base64 format.
105
+ *
106
+ * @param {string} str - The string to be encoded.
107
+ * @return {string} The Unicode-encoded base64 representation of the input string.
108
+ */
109
+ private unicodeEncode;
110
+ /**
111
+ * Decodes a Base64 encoded Unicode string.
112
+ *
113
+ * @param {string} str - The Base64 encoded string to decode.
114
+ * @return {string} The decoded Unicode string.
115
+ */
116
+ private unicodeDecode;
75
117
  private encryptData;
76
118
  private decryptData;
77
119
  }
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.5.0-beta.29",
5
+ "version": "1.5.0-beta.30",
6
6
  "homepage": "https://docs.liquidcommerce.co/rmn-sdk",
7
7
  "main": "./dist/index.cjs",
8
8
  "module": "./dist/index.esm.js",