@liquidcommercedev/rmn-sdk 1.5.0-beta.5 → 1.5.0-beta.6

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.cjs CHANGED
@@ -62,6 +62,7 @@ exports.RMN_SPOT_EVENT = void 0;
62
62
  RMN_SPOT_EVENT["CLICK"] = "CLICK";
63
63
  RMN_SPOT_EVENT["PURCHASE"] = "PURCHASE";
64
64
  RMN_SPOT_EVENT["ADD_TO_CART"] = "ADD_TO_CART";
65
+ RMN_SPOT_EVENT["REMOVE_FROM_CART"] = "REMOVE_FROM_CART";
65
66
  RMN_SPOT_EVENT["ADD_TO_WISHLIST"] = "ADD_TO_WISHLIST";
66
67
  RMN_SPOT_EVENT["BUY_NOW"] = "BUY_NOW";
67
68
  })(exports.RMN_SPOT_EVENT || (exports.RMN_SPOT_EVENT = {}));
@@ -15166,6 +15167,84 @@ const GFONT_CORMORANT = `
15166
15167
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300..700;1,300..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15167
15168
  `;
15168
15169
 
15170
+ function getEventTypeFromRawEvent(event) {
15171
+ if (!event) {
15172
+ return null;
15173
+ }
15174
+ if (event.includes('cart')) {
15175
+ if (event.includes('add')) {
15176
+ return exports.RMN_SPOT_EVENT.ADD_TO_CART;
15177
+ }
15178
+ if (event.includes('remove')) {
15179
+ return exports.RMN_SPOT_EVENT.REMOVE_FROM_CART;
15180
+ }
15181
+ }
15182
+ if (event.includes('purchase')) {
15183
+ return exports.RMN_SPOT_EVENT.PURCHASE;
15184
+ }
15185
+ // if(event.includes('refund')) {
15186
+ // return RMN_SPOT_EVENT.REFUND;
15187
+ // }
15188
+ if (event.includes('wishlist') && event.includes('add')) {
15189
+ return exports.RMN_SPOT_EVENT.ADD_TO_WISHLIST;
15190
+ }
15191
+ return null;
15192
+ }
15193
+ /**
15194
+ * Recursively extracts ID values from a nested data structure.
15195
+ * Searches for specified property names and collects their primitive values (strings/numbers).
15196
+ *
15197
+ * @param data - The data structure to search through (can be nested objects/arrays)
15198
+ * @param propertyNames - Array of property names to look for (defaults to ['id', 'upc', 'groupingId', 'sku', 'productId'])
15199
+ * @returns Array of extracted ID values (strings/numbers only)
15200
+ *
15201
+ * @example
15202
+ * const data = {
15203
+ * id: [1, 2, 3],
15204
+ * nested: { id: 'abc' },
15205
+ * items: [{ id: 456 }]
15206
+ * };
15207
+ * extractDeepIds(data); // Returns [1, 2, 3, 'abc', 456]
15208
+ */
15209
+ function extractDeepIds(data, propertyNames = ['id', 'upc', 'groupingId', 'sku', 'productId']) {
15210
+ const ids = [];
15211
+ // Set for faster property name lookups
15212
+ const propertySet = new Set(propertyNames);
15213
+ /**
15214
+ * Processes a value and extracts IDs if it matches criteria
15215
+ * @param value - The value to process
15216
+ * @param currentKey - The property name of the current value
15217
+ */
15218
+ const processValue = (value, currentKey) => {
15219
+ // Early exit for null/undefined values
15220
+ if (value == null)
15221
+ return;
15222
+ // If current key matches our target properties
15223
+ if (currentKey && propertySet.has(currentKey)) {
15224
+ if (Array.isArray(value)) {
15225
+ // Filter and push valid array values in one pass
15226
+ ids.push(...value.filter((item) => typeof item === 'string' || typeof item === 'number'));
15227
+ }
15228
+ else if (typeof value === 'string' || typeof value === 'number') {
15229
+ ids.push(value);
15230
+ }
15231
+ return; // Stop processing this branch after handling the ID
15232
+ }
15233
+ // Recursively process nested structures
15234
+ if (Array.isArray(value)) {
15235
+ value.forEach((item) => processValue(item));
15236
+ }
15237
+ else if (typeof value === 'object') {
15238
+ // Process all enumerable properties
15239
+ for (const [key, val] of Object.entries(value)) {
15240
+ processValue(val, key);
15241
+ }
15242
+ }
15243
+ };
15244
+ processValue(data);
15245
+ return ids; // No need to filter nulls as we handle that during collection
15246
+ }
15247
+
15169
15248
  class DataLayerMonitor {
15170
15249
  constructor() {
15171
15250
  if (!window.dataLayer) {
@@ -15187,11 +15266,25 @@ class DataLayerMonitor {
15187
15266
  const result = this.originalPush.apply(window.dataLayer, args);
15188
15267
  const pushedEvent = args[0];
15189
15268
  if (this.listener) {
15190
- this.listener(pushedEvent);
15269
+ const normalizedData = this.cleanEventData(pushedEvent);
15270
+ if (normalizedData) {
15271
+ this.listener(normalizedData);
15272
+ }
15191
15273
  }
15192
15274
  return result;
15193
15275
  };
15194
15276
  }
15277
+ cleanEventData(data) {
15278
+ const eventName = getEventTypeFromRawEvent(data.event);
15279
+ if (!eventName) {
15280
+ return null;
15281
+ }
15282
+ const productIds = extractDeepIds(data.value);
15283
+ return {
15284
+ event: eventName,
15285
+ productIds,
15286
+ };
15287
+ }
15195
15288
  stop() {
15196
15289
  if (this.originalPush) {
15197
15290
  window.dataLayer.push = this.originalPush;
@@ -15240,6 +15333,14 @@ class IntersectionObserverService {
15240
15333
  }
15241
15334
  }
15242
15335
 
15336
+ var ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX;
15337
+ (function (ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX) {
15338
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_ID"] = 0] = "SPOT_ID";
15339
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_TYPE"] = 1] = "SPOT_TYPE";
15340
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["EVENTS"] = 2] = "EVENTS";
15341
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["PRODUCT_IDS"] = 3] = "PRODUCT_IDS";
15342
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["CREATED_AT"] = 4] = "CREATED_AT";
15343
+ })(ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX || (ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX = {}));
15243
15344
  class LocalStorage {
15244
15345
  constructor() {
15245
15346
  if (typeof window.localStorage === 'undefined') {
@@ -15265,7 +15366,11 @@ class LocalStorage {
15265
15366
  try {
15266
15367
  const parsedData = JSON.parse(localStorageData);
15267
15368
  if (parsedData && typeof parsedData === 'object') {
15268
- this.spots = this.objToMap(parsedData);
15369
+ const data = {};
15370
+ for (const [key, value] of Object.entries(parsedData)) {
15371
+ data[key] = this.arrayToObject(value);
15372
+ }
15373
+ this.spots = this.objectToMap(data);
15269
15374
  }
15270
15375
  else {
15271
15376
  this.clearLocalStorage();
@@ -15295,13 +15400,17 @@ class LocalStorage {
15295
15400
  getSpots() {
15296
15401
  if (!this.spots)
15297
15402
  return undefined;
15298
- return this.mapToObj(this.spots);
15403
+ return this.mapToObject(this.spots);
15299
15404
  }
15300
15405
  updateLocalStorage() {
15301
15406
  if (!this.spots)
15302
15407
  return undefined;
15303
- const data = this.mapToObj(this.spots);
15304
- localStorage.setItem(LocalStorage.localStorageKey, JSON.stringify(data));
15408
+ const data = this.mapToObject(this.spots);
15409
+ const dataArray = {};
15410
+ for (const [key, value] of Object.entries(data)) {
15411
+ dataArray[key] = this.objectToArray(value);
15412
+ }
15413
+ window.localStorage.setItem(LocalStorage.localStorageKey, JSON.stringify(dataArray));
15305
15414
  }
15306
15415
  clearLocalStorage() {
15307
15416
  window.localStorage.removeItem(LocalStorage.localStorageKey);
@@ -15317,12 +15426,24 @@ class LocalStorage {
15317
15426
  });
15318
15427
  this.updateLocalStorage();
15319
15428
  }
15320
- mapToObj(map) {
15429
+ mapToObject(map) {
15321
15430
  return Object.fromEntries(map);
15322
15431
  }
15323
- objToMap(obj) {
15432
+ objectToMap(obj) {
15324
15433
  return new Map(Object.entries(obj));
15325
15434
  }
15435
+ objectToArray(obj) {
15436
+ return [obj.spotId, obj.spotType, obj.events, obj.productIds, obj.createdAt];
15437
+ }
15438
+ arrayToObject(arr) {
15439
+ return {
15440
+ spotId: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_ID],
15441
+ spotType: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_TYPE],
15442
+ events: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.EVENTS],
15443
+ productIds: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.PRODUCT_IDS],
15444
+ createdAt: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.CREATED_AT],
15445
+ };
15446
+ }
15326
15447
  }
15327
15448
  LocalStorage.localStorageKey = 'lc_rmn';
15328
15449
  LocalStorage.spotExpirationTime = 1000 * 60 * 60 * 24 * 7; // 7 days
@@ -18016,7 +18137,7 @@ const SPOT_TEMPLATE_HTML_ELEMENT = (spot, config) => {
18016
18137
  /**
18017
18138
  * PubSub class
18018
18139
  * Manages event subscriptions and publications
18019
- * @template IEventMap A record type defining the structure of events and their data
18140
+ * @template IRmnEventMap A record type defining the structure of events and their data
18020
18141
  */
18021
18142
  class PubSub {
18022
18143
  constructor() {
@@ -18070,12 +18191,12 @@ class PubSub {
18070
18191
  /**
18071
18192
  * Usage Example:
18072
18193
  *
18073
- * interface IEventMap {
18194
+ * interface IRmnEventMap {
18074
18195
  * userLogin: { username: string; timestamp: number };
18075
18196
  * pageView: { url: string; timestamp: number };
18076
18197
  * }
18077
18198
  *
18078
- * const pubSub = new PubSub<IEventMap>();
18199
+ * const pubSub = new PubSub<IRmnEventMap>();
18079
18200
  *
18080
18201
  * // Subscribe to events
18081
18202
  * const unsubscribeLogin = pubSub.subscribe('userLogin', (data) => {
@@ -18106,7 +18227,6 @@ var AnalyticsTool;
18106
18227
  class UserMonitor {
18107
18228
  constructor() {
18108
18229
  const analyticsTool = this.detectAnalyticsTool();
18109
- console.info({ analyticsTool });
18110
18230
  switch (analyticsTool) {
18111
18231
  case AnalyticsTool.GoogleAnalytics:
18112
18232
  this.implementedMonitor = DataLayerMonitor.getInstance();
@@ -18130,13 +18250,19 @@ class UserMonitor {
18130
18250
  start() {
18131
18251
  if (!this.implementedMonitor)
18132
18252
  return;
18133
- this.implementedMonitor.setListener((pushedEvent) => {
18253
+ this.implementedMonitor.setListener((eventData) => {
18134
18254
  var _a;
18135
- console.info({ pushedEvent });
18136
- console.info({ spots: (_a = this.localStorage) === null || _a === void 0 ? void 0 : _a.getSpots() });
18255
+ this.matchAndFireEvent(eventData, (_a = this.localStorage) === null || _a === void 0 ? void 0 : _a.getSpots());
18137
18256
  });
18138
18257
  this.implementedMonitor.start();
18139
18258
  }
18259
+ matchAndFireEvent(
18260
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
18261
+ _eventData,
18262
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
18263
+ _spots) {
18264
+ // console.info({ eventData, spots });
18265
+ }
18140
18266
  detectAnalyticsTool() {
18141
18267
  let analyticsTool = AnalyticsTool.Other;
18142
18268
  // Check for Google Analytics
package/dist/index.esm.js CHANGED
@@ -60,6 +60,7 @@ var RMN_SPOT_EVENT;
60
60
  RMN_SPOT_EVENT["CLICK"] = "CLICK";
61
61
  RMN_SPOT_EVENT["PURCHASE"] = "PURCHASE";
62
62
  RMN_SPOT_EVENT["ADD_TO_CART"] = "ADD_TO_CART";
63
+ RMN_SPOT_EVENT["REMOVE_FROM_CART"] = "REMOVE_FROM_CART";
63
64
  RMN_SPOT_EVENT["ADD_TO_WISHLIST"] = "ADD_TO_WISHLIST";
64
65
  RMN_SPOT_EVENT["BUY_NOW"] = "BUY_NOW";
65
66
  })(RMN_SPOT_EVENT || (RMN_SPOT_EVENT = {}));
@@ -15164,6 +15165,84 @@ const GFONT_CORMORANT = `
15164
15165
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300..700;1,300..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15165
15166
  `;
15166
15167
 
15168
+ function getEventTypeFromRawEvent(event) {
15169
+ if (!event) {
15170
+ return null;
15171
+ }
15172
+ if (event.includes('cart')) {
15173
+ if (event.includes('add')) {
15174
+ return RMN_SPOT_EVENT.ADD_TO_CART;
15175
+ }
15176
+ if (event.includes('remove')) {
15177
+ return RMN_SPOT_EVENT.REMOVE_FROM_CART;
15178
+ }
15179
+ }
15180
+ if (event.includes('purchase')) {
15181
+ return RMN_SPOT_EVENT.PURCHASE;
15182
+ }
15183
+ // if(event.includes('refund')) {
15184
+ // return RMN_SPOT_EVENT.REFUND;
15185
+ // }
15186
+ if (event.includes('wishlist') && event.includes('add')) {
15187
+ return RMN_SPOT_EVENT.ADD_TO_WISHLIST;
15188
+ }
15189
+ return null;
15190
+ }
15191
+ /**
15192
+ * Recursively extracts ID values from a nested data structure.
15193
+ * Searches for specified property names and collects their primitive values (strings/numbers).
15194
+ *
15195
+ * @param data - The data structure to search through (can be nested objects/arrays)
15196
+ * @param propertyNames - Array of property names to look for (defaults to ['id', 'upc', 'groupingId', 'sku', 'productId'])
15197
+ * @returns Array of extracted ID values (strings/numbers only)
15198
+ *
15199
+ * @example
15200
+ * const data = {
15201
+ * id: [1, 2, 3],
15202
+ * nested: { id: 'abc' },
15203
+ * items: [{ id: 456 }]
15204
+ * };
15205
+ * extractDeepIds(data); // Returns [1, 2, 3, 'abc', 456]
15206
+ */
15207
+ function extractDeepIds(data, propertyNames = ['id', 'upc', 'groupingId', 'sku', 'productId']) {
15208
+ const ids = [];
15209
+ // Set for faster property name lookups
15210
+ const propertySet = new Set(propertyNames);
15211
+ /**
15212
+ * Processes a value and extracts IDs if it matches criteria
15213
+ * @param value - The value to process
15214
+ * @param currentKey - The property name of the current value
15215
+ */
15216
+ const processValue = (value, currentKey) => {
15217
+ // Early exit for null/undefined values
15218
+ if (value == null)
15219
+ return;
15220
+ // If current key matches our target properties
15221
+ if (currentKey && propertySet.has(currentKey)) {
15222
+ if (Array.isArray(value)) {
15223
+ // Filter and push valid array values in one pass
15224
+ ids.push(...value.filter((item) => typeof item === 'string' || typeof item === 'number'));
15225
+ }
15226
+ else if (typeof value === 'string' || typeof value === 'number') {
15227
+ ids.push(value);
15228
+ }
15229
+ return; // Stop processing this branch after handling the ID
15230
+ }
15231
+ // Recursively process nested structures
15232
+ if (Array.isArray(value)) {
15233
+ value.forEach((item) => processValue(item));
15234
+ }
15235
+ else if (typeof value === 'object') {
15236
+ // Process all enumerable properties
15237
+ for (const [key, val] of Object.entries(value)) {
15238
+ processValue(val, key);
15239
+ }
15240
+ }
15241
+ };
15242
+ processValue(data);
15243
+ return ids; // No need to filter nulls as we handle that during collection
15244
+ }
15245
+
15167
15246
  class DataLayerMonitor {
15168
15247
  constructor() {
15169
15248
  if (!window.dataLayer) {
@@ -15185,11 +15264,25 @@ class DataLayerMonitor {
15185
15264
  const result = this.originalPush.apply(window.dataLayer, args);
15186
15265
  const pushedEvent = args[0];
15187
15266
  if (this.listener) {
15188
- this.listener(pushedEvent);
15267
+ const normalizedData = this.cleanEventData(pushedEvent);
15268
+ if (normalizedData) {
15269
+ this.listener(normalizedData);
15270
+ }
15189
15271
  }
15190
15272
  return result;
15191
15273
  };
15192
15274
  }
15275
+ cleanEventData(data) {
15276
+ const eventName = getEventTypeFromRawEvent(data.event);
15277
+ if (!eventName) {
15278
+ return null;
15279
+ }
15280
+ const productIds = extractDeepIds(data.value);
15281
+ return {
15282
+ event: eventName,
15283
+ productIds,
15284
+ };
15285
+ }
15193
15286
  stop() {
15194
15287
  if (this.originalPush) {
15195
15288
  window.dataLayer.push = this.originalPush;
@@ -15238,6 +15331,14 @@ class IntersectionObserverService {
15238
15331
  }
15239
15332
  }
15240
15333
 
15334
+ var ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX;
15335
+ (function (ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX) {
15336
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_ID"] = 0] = "SPOT_ID";
15337
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["SPOT_TYPE"] = 1] = "SPOT_TYPE";
15338
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["EVENTS"] = 2] = "EVENTS";
15339
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["PRODUCT_IDS"] = 3] = "PRODUCT_IDS";
15340
+ ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX["CREATED_AT"] = 4] = "CREATED_AT";
15341
+ })(ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX || (ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX = {}));
15241
15342
  class LocalStorage {
15242
15343
  constructor() {
15243
15344
  if (typeof window.localStorage === 'undefined') {
@@ -15263,7 +15364,11 @@ class LocalStorage {
15263
15364
  try {
15264
15365
  const parsedData = JSON.parse(localStorageData);
15265
15366
  if (parsedData && typeof parsedData === 'object') {
15266
- this.spots = this.objToMap(parsedData);
15367
+ const data = {};
15368
+ for (const [key, value] of Object.entries(parsedData)) {
15369
+ data[key] = this.arrayToObject(value);
15370
+ }
15371
+ this.spots = this.objectToMap(data);
15267
15372
  }
15268
15373
  else {
15269
15374
  this.clearLocalStorage();
@@ -15293,13 +15398,17 @@ class LocalStorage {
15293
15398
  getSpots() {
15294
15399
  if (!this.spots)
15295
15400
  return undefined;
15296
- return this.mapToObj(this.spots);
15401
+ return this.mapToObject(this.spots);
15297
15402
  }
15298
15403
  updateLocalStorage() {
15299
15404
  if (!this.spots)
15300
15405
  return undefined;
15301
- const data = this.mapToObj(this.spots);
15302
- localStorage.setItem(LocalStorage.localStorageKey, JSON.stringify(data));
15406
+ const data = this.mapToObject(this.spots);
15407
+ const dataArray = {};
15408
+ for (const [key, value] of Object.entries(data)) {
15409
+ dataArray[key] = this.objectToArray(value);
15410
+ }
15411
+ window.localStorage.setItem(LocalStorage.localStorageKey, JSON.stringify(dataArray));
15303
15412
  }
15304
15413
  clearLocalStorage() {
15305
15414
  window.localStorage.removeItem(LocalStorage.localStorageKey);
@@ -15315,12 +15424,24 @@ class LocalStorage {
15315
15424
  });
15316
15425
  this.updateLocalStorage();
15317
15426
  }
15318
- mapToObj(map) {
15427
+ mapToObject(map) {
15319
15428
  return Object.fromEntries(map);
15320
15429
  }
15321
- objToMap(obj) {
15430
+ objectToMap(obj) {
15322
15431
  return new Map(Object.entries(obj));
15323
15432
  }
15433
+ objectToArray(obj) {
15434
+ return [obj.spotId, obj.spotType, obj.events, obj.productIds, obj.createdAt];
15435
+ }
15436
+ arrayToObject(arr) {
15437
+ return {
15438
+ spotId: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_ID],
15439
+ spotType: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.SPOT_TYPE],
15440
+ events: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.EVENTS],
15441
+ productIds: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.PRODUCT_IDS],
15442
+ createdAt: arr[ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX.CREATED_AT],
15443
+ };
15444
+ }
15324
15445
  }
15325
15446
  LocalStorage.localStorageKey = 'lc_rmn';
15326
15447
  LocalStorage.spotExpirationTime = 1000 * 60 * 60 * 24 * 7; // 7 days
@@ -18014,7 +18135,7 @@ const SPOT_TEMPLATE_HTML_ELEMENT = (spot, config) => {
18014
18135
  /**
18015
18136
  * PubSub class
18016
18137
  * Manages event subscriptions and publications
18017
- * @template IEventMap A record type defining the structure of events and their data
18138
+ * @template IRmnEventMap A record type defining the structure of events and their data
18018
18139
  */
18019
18140
  class PubSub {
18020
18141
  constructor() {
@@ -18068,12 +18189,12 @@ class PubSub {
18068
18189
  /**
18069
18190
  * Usage Example:
18070
18191
  *
18071
- * interface IEventMap {
18192
+ * interface IRmnEventMap {
18072
18193
  * userLogin: { username: string; timestamp: number };
18073
18194
  * pageView: { url: string; timestamp: number };
18074
18195
  * }
18075
18196
  *
18076
- * const pubSub = new PubSub<IEventMap>();
18197
+ * const pubSub = new PubSub<IRmnEventMap>();
18077
18198
  *
18078
18199
  * // Subscribe to events
18079
18200
  * const unsubscribeLogin = pubSub.subscribe('userLogin', (data) => {
@@ -18104,7 +18225,6 @@ var AnalyticsTool;
18104
18225
  class UserMonitor {
18105
18226
  constructor() {
18106
18227
  const analyticsTool = this.detectAnalyticsTool();
18107
- console.info({ analyticsTool });
18108
18228
  switch (analyticsTool) {
18109
18229
  case AnalyticsTool.GoogleAnalytics:
18110
18230
  this.implementedMonitor = DataLayerMonitor.getInstance();
@@ -18128,13 +18248,19 @@ class UserMonitor {
18128
18248
  start() {
18129
18249
  if (!this.implementedMonitor)
18130
18250
  return;
18131
- this.implementedMonitor.setListener((pushedEvent) => {
18251
+ this.implementedMonitor.setListener((eventData) => {
18132
18252
  var _a;
18133
- console.info({ pushedEvent });
18134
- console.info({ spots: (_a = this.localStorage) === null || _a === void 0 ? void 0 : _a.getSpots() });
18253
+ this.matchAndFireEvent(eventData, (_a = this.localStorage) === null || _a === void 0 ? void 0 : _a.getSpots());
18135
18254
  });
18136
18255
  this.implementedMonitor.start();
18137
18256
  }
18257
+ matchAndFireEvent(
18258
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
18259
+ _eventData,
18260
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
18261
+ _spots) {
18262
+ // console.info({ eventData, spots });
18263
+ }
18138
18264
  detectAnalyticsTool() {
18139
18265
  let analyticsTool = AnalyticsTool.Other;
18140
18266
  // Check for Google Analytics
@@ -55,6 +55,7 @@ export declare enum RMN_SPOT_EVENT {
55
55
  CLICK = "CLICK",
56
56
  PURCHASE = "PURCHASE",
57
57
  ADD_TO_CART = "ADD_TO_CART",
58
+ REMOVE_FROM_CART = "REMOVE_FROM_CART",
58
59
  ADD_TO_WISHLIST = "ADD_TO_WISHLIST",
59
60
  BUY_NOW = "BUY_NOW"
60
61
  }
@@ -44,6 +44,10 @@ export interface IAddToCartEvent {
44
44
  placementId: string;
45
45
  spotId: string;
46
46
  }
47
+ export interface IRemoveFromCartEvent {
48
+ placementId: string;
49
+ spotId: string;
50
+ }
47
51
  export interface IAddToWishlistEvent {
48
52
  placementId: string;
49
53
  spotId: string;
@@ -61,6 +65,7 @@ export interface IRmnEventMap {
61
65
  [RMN_SPOT_EVENT.CLICK]: IClickEvent;
62
66
  [RMN_SPOT_EVENT.IMPRESSION]: IImpressionEvent;
63
67
  [RMN_SPOT_EVENT.ADD_TO_CART]: IAddToCartEvent;
68
+ [RMN_SPOT_EVENT.REMOVE_FROM_CART]: IRemoveFromCartEvent;
64
69
  [RMN_SPOT_EVENT.ADD_TO_WISHLIST]: IAddToWishlistEvent;
65
70
  [RMN_SPOT_EVENT.PURCHASE]: IPurchaseEvent;
66
71
  [RMN_SPOT_EVENT.BUY_NOW]: IBuyNowEvent;
@@ -1,10 +1,21 @@
1
+ import type { RMN_SPOT_EVENT } from 'enums';
2
+ export interface IDataLayerEvent {
3
+ event?: string;
4
+ value?: any[];
5
+ [key: string]: any;
6
+ }
7
+ export interface INormalizedEventData {
8
+ event: RMN_SPOT_EVENT;
9
+ productIds: Array<string | number>;
10
+ }
1
11
  export declare class DataLayerMonitor {
2
12
  private static instance;
3
13
  private readonly originalPush;
4
14
  private listener?;
5
15
  private constructor();
6
16
  static getInstance(): DataLayerMonitor;
7
- setListener(listener: (data: any) => void): void;
17
+ setListener(listener: (data: INormalizedEventData) => void): void;
8
18
  start(): void;
19
+ private cleanEventData;
9
20
  stop(): void;
10
21
  }
@@ -1,9 +1,5 @@
1
1
  import type { RMN_SPOT_TYPE } from 'enums';
2
2
  import type { ISpotEvent } from 'modules/selection';
3
- export type LocalStorageSpotsMapType = Map<string, // spotId
4
- ILocalStorageSpot>;
5
- export type LocalStorageSpotsObjType = Record<string, // spotId
6
- ILocalStorageSpot>;
7
3
  export interface ILocalStorageSpot {
8
4
  spotId: string;
9
5
  spotType: RMN_SPOT_TYPE;
@@ -11,6 +7,27 @@ export interface ILocalStorageSpot {
11
7
  productIds: Array<string | number>;
12
8
  createdAt?: number;
13
9
  }
10
+ export type LocalStorageSpotsMapType = Map<string, // spotId
11
+ ILocalStorageSpot>;
12
+ export type LocalStorageSpotsObjectType = Record<string, // spotId
13
+ ILocalStorageSpot>;
14
+ export type LocalStorageSpotArray = [
15
+ string,
16
+ RMN_SPOT_TYPE,
17
+ ISpotEvent[],
18
+ Array<string | number>,
19
+ // PRODUCT_IDS = 3
20
+ number | undefined
21
+ ];
22
+ export declare enum ENUM_LOCAL_STORAGE_SPOT_ARRAY_INDEX {
23
+ SPOT_ID = 0,
24
+ SPOT_TYPE = 1,
25
+ EVENTS = 2,
26
+ PRODUCT_IDS = 3,
27
+ CREATED_AT = 4
28
+ }
29
+ export type LocalStorageSpotsArrayType = Record<string, // spotId
30
+ LocalStorageSpotArray>;
14
31
  export declare class LocalStorage {
15
32
  private spots?;
16
33
  private static instance;
@@ -22,10 +39,12 @@ export declare class LocalStorage {
22
39
  setSpot(spotId: string, data: ILocalStorageSpot): void;
23
40
  removeSpot(spotId: string): void;
24
41
  getSpot(spotId: string): ILocalStorageSpot | undefined;
25
- getSpots(): LocalStorageSpotsObjType | undefined;
42
+ getSpots(): LocalStorageSpotsObjectType | undefined;
26
43
  private updateLocalStorage;
27
44
  private clearLocalStorage;
28
45
  private removeExpiredSpots;
29
- private mapToObj;
30
- private objToMap;
46
+ private mapToObject;
47
+ private objectToMap;
48
+ private objectToArray;
49
+ private arrayToObject;
31
50
  }
@@ -0,0 +1,24 @@
1
+ import { RMN_SPOT_EVENT } from 'enums';
2
+ export interface IExtractIdsProps {
3
+ id?: string | number;
4
+ upc?: string | number;
5
+ [key: string]: string | number | undefined;
6
+ }
7
+ export declare function getEventTypeFromRawEvent(event?: string): RMN_SPOT_EVENT | null;
8
+ /**
9
+ * Recursively extracts ID values from a nested data structure.
10
+ * Searches for specified property names and collects their primitive values (strings/numbers).
11
+ *
12
+ * @param data - The data structure to search through (can be nested objects/arrays)
13
+ * @param propertyNames - Array of property names to look for (defaults to ['id', 'upc', 'groupingId', 'sku', 'productId'])
14
+ * @returns Array of extracted ID values (strings/numbers only)
15
+ *
16
+ * @example
17
+ * const data = {
18
+ * id: [1, 2, 3],
19
+ * nested: { id: 'abc' },
20
+ * items: [{ id: 456 }]
21
+ * };
22
+ * extractDeepIds(data); // Returns [1, 2, 3, 'abc', 456]
23
+ */
24
+ export declare function extractDeepIds(data: any, propertyNames?: readonly string[]): Array<string | number>;
@@ -10,11 +10,11 @@ export type PubSubUnsubscribe = () => void;
10
10
  /**
11
11
  * PubSub class
12
12
  * Manages event subscriptions and publications
13
- * @template IEventMap A record type defining the structure of events and their data
13
+ * @template IRmnEventMap A record type defining the structure of events and their data
14
14
  */
15
- export declare class PubSub<IEventMap> {
15
+ export declare class PubSub<IRmnEventMap> {
16
16
  private static instance;
17
- static getInstance<IEventMap>(): PubSub<IEventMap>;
17
+ static getInstance<IRmnEventMap>(): PubSub<IRmnEventMap>;
18
18
  /**
19
19
  * Object to store subscribers for each event type
20
20
  */
@@ -30,7 +30,7 @@ export declare class PubSub<IEventMap> {
30
30
  * console.log(`User ${data.username} logged in`);
31
31
  * });
32
32
  */
33
- subscribe<K extends keyof IEventMap>(eventType: K, callback: PubSubCallback<IEventMap[K]>): PubSubUnsubscribe;
33
+ subscribe<K extends keyof IRmnEventMap>(eventType: K, callback: PubSubCallback<IRmnEventMap[K]>): PubSubUnsubscribe;
34
34
  /**
35
35
  * Publish an event
36
36
  * @param eventType - The type of event to publish
@@ -39,17 +39,17 @@ export declare class PubSub<IEventMap> {
39
39
  * @Example:
40
40
  * pubSub.publish('userLogin', { username: 'john_doe', timestamp: Date.now() });
41
41
  */
42
- publish<K extends keyof IEventMap>(eventType: K, data: IEventMap[K]): void;
42
+ publish<K extends keyof IRmnEventMap>(eventType: K, data: IRmnEventMap[K]): void;
43
43
  }
44
44
  /**
45
45
  * Usage Example:
46
46
  *
47
- * interface IEventMap {
47
+ * interface IRmnEventMap {
48
48
  * userLogin: { username: string; timestamp: number };
49
49
  * pageView: { url: string; timestamp: number };
50
50
  * }
51
51
  *
52
- * const pubSub = new PubSub<IEventMap>();
52
+ * const pubSub = new PubSub<IRmnEventMap>();
53
53
  *
54
54
  * // Subscribe to events
55
55
  * const unsubscribeLogin = pubSub.subscribe('userLogin', (data) => {
@@ -9,5 +9,6 @@ export declare class UserMonitor {
9
9
  private constructor();
10
10
  static getInstance(): UserMonitor;
11
11
  start(): void;
12
+ private matchAndFireEvent;
12
13
  private detectAnalyticsTool;
13
14
  }