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

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
@@ -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
  }