@liquidcommercedev/rmn-sdk 1.5.0-beta.26 → 1.5.0-beta.27
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 +80 -225
- package/dist/index.esm.js +80 -225
- package/dist/types/modules/element/component/skeleton/skeleton.interface.d.ts +1 -0
- package/dist/types/modules/element/component/skeleton/skeleton.template.d.ts +1 -1
- package/dist/types/modules/monitor/monitor.interface.d.ts +11 -2
- package/dist/types/modules/monitor/monitors/datalayer.monitor.d.ts +3 -3
- package/package.json +1 -1
- package/umd/liquidcommerce-rmn-sdk.min.js +1 -1
package/dist/index.esm.js
CHANGED
@@ -6131,121 +6131,6 @@ function getEventTypeFromRawEvent(event) {
|
|
6131
6131
|
}
|
6132
6132
|
|
6133
6133
|
// Configuration object with target field names
|
6134
|
-
const extractorConfig = {
|
6135
|
-
ids: [
|
6136
|
-
// Ps: The function handles all the variations of keywords that end with "id" or "ids"
|
6137
|
-
// Universal product identifiers
|
6138
|
-
'gtin',
|
6139
|
-
'gtin8',
|
6140
|
-
'gtin12',
|
6141
|
-
'gtin13',
|
6142
|
-
'gtin14',
|
6143
|
-
'mpn',
|
6144
|
-
'sku',
|
6145
|
-
'upc',
|
6146
|
-
'ean',
|
6147
|
-
'isbn',
|
6148
|
-
'isbn10',
|
6149
|
-
'isbn13',
|
6150
|
-
'asin',
|
6151
|
-
// Product codes and references
|
6152
|
-
'coupon',
|
6153
|
-
'barcode',
|
6154
|
-
'product_code',
|
6155
|
-
'part_number',
|
6156
|
-
'model_number',
|
6157
|
-
'item_variant',
|
6158
|
-
'item_number',
|
6159
|
-
'article_number',
|
6160
|
-
'reference',
|
6161
|
-
'salsifyGrouping',
|
6162
|
-
'grouping',
|
6163
|
-
],
|
6164
|
-
price: [
|
6165
|
-
'price',
|
6166
|
-
'unitPrice',
|
6167
|
-
'cost',
|
6168
|
-
'current_price',
|
6169
|
-
'sale_price',
|
6170
|
-
'price_value',
|
6171
|
-
'sale_price_value',
|
6172
|
-
'regular_price',
|
6173
|
-
'discount_price',
|
6174
|
-
'unit_price',
|
6175
|
-
'original_price',
|
6176
|
-
'final_price',
|
6177
|
-
'retail_price',
|
6178
|
-
],
|
6179
|
-
quantity: ['quantity', 'qty'],
|
6180
|
-
};
|
6181
|
-
/**
|
6182
|
-
* Extracts deep values from an object based on specified target type
|
6183
|
-
* @param data - The source data object to extract values from
|
6184
|
-
* @param target - The type of values to extract ('ids' or 'price')
|
6185
|
-
* @param options - Optional configuration for the extraction process
|
6186
|
-
* @returns Array of extracted values or a single value if onlyFirst is true
|
6187
|
-
*/
|
6188
|
-
function extractDeepValues(data, target, options = {}) {
|
6189
|
-
const {
|
6190
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
6191
|
-
onlyFirst = false, shouldIncludeZero = false, } = options;
|
6192
|
-
const values = [];
|
6193
|
-
const targetProperties = new Set(extractorConfig[target].map((name) => name.toLowerCase()));
|
6194
|
-
/**
|
6195
|
-
* Checks if a property name matches the target criteria
|
6196
|
-
*/
|
6197
|
-
const isTargetField = (key) => {
|
6198
|
-
const normalizedKey = key.toLowerCase();
|
6199
|
-
const hasTarget = targetProperties.has(normalizedKey);
|
6200
|
-
if (target === 'ids') {
|
6201
|
-
return normalizedKey.endsWith('id') || normalizedKey.endsWith('ids') || hasTarget;
|
6202
|
-
}
|
6203
|
-
return hasTarget;
|
6204
|
-
};
|
6205
|
-
/**
|
6206
|
-
* Validates and normalizes extracted values
|
6207
|
-
*/
|
6208
|
-
const validateValue = (value) => {
|
6209
|
-
if (typeof value === 'string') {
|
6210
|
-
return value.trim().length > 0;
|
6211
|
-
}
|
6212
|
-
if (typeof value === 'number') {
|
6213
|
-
return !isNaN(value) && (shouldIncludeZero || value !== 0);
|
6214
|
-
}
|
6215
|
-
return false;
|
6216
|
-
};
|
6217
|
-
/**
|
6218
|
-
* Processes a value and extracts matching fields
|
6219
|
-
*/
|
6220
|
-
const processValue = (value, currentKey) => {
|
6221
|
-
// Early exit conditions
|
6222
|
-
if (value == null || (onlyFirst && values.length > 0))
|
6223
|
-
return;
|
6224
|
-
// Process current value if it matches target criteria
|
6225
|
-
if (currentKey && isTargetField(currentKey)) {
|
6226
|
-
if (Array.isArray(value)) {
|
6227
|
-
const validValues = value.filter(validateValue);
|
6228
|
-
values.push(...validValues);
|
6229
|
-
}
|
6230
|
-
else if (validateValue(value)) {
|
6231
|
-
values.push(value);
|
6232
|
-
}
|
6233
|
-
return;
|
6234
|
-
}
|
6235
|
-
// Recursive processing for nested structures
|
6236
|
-
if (Array.isArray(value)) {
|
6237
|
-
value.forEach((item) => processValue(item));
|
6238
|
-
}
|
6239
|
-
else if (typeof value === 'object') {
|
6240
|
-
Object.entries(value).forEach(([key, val]) => processValue(val, key));
|
6241
|
-
}
|
6242
|
-
};
|
6243
|
-
processValue(data);
|
6244
|
-
// Return based on options
|
6245
|
-
if (values.length === 0)
|
6246
|
-
return undefined;
|
6247
|
-
return onlyFirst ? values[0] : values;
|
6248
|
-
}
|
6249
6134
|
/**
|
6250
6135
|
* Cleans and normalizes an array of product IDs by:
|
6251
6136
|
* 1. Converting all IDs to strings
|
@@ -17198,7 +17083,8 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined
|
|
17198
17083
|
CarouselElement = CustomCarouselElement;
|
17199
17084
|
}
|
17200
17085
|
|
17201
|
-
function SkeletonTemplate({ fluid, width, height }) {
|
17086
|
+
function SkeletonTemplate({ fluid, width, height, spotType, }) {
|
17087
|
+
const isSmall = spotType === RMN_SPOT_TYPE.RB_IN_TEXT;
|
17202
17088
|
return `
|
17203
17089
|
<style>
|
17204
17090
|
:host {
|
@@ -17209,42 +17095,20 @@ function SkeletonTemplate({ fluid, width, height }) {
|
|
17209
17095
|
width: ${fluid ? '100%' : `${width}px`};
|
17210
17096
|
height: ${fluid ? '100%' : `${height}px`};
|
17211
17097
|
background: #ffffff;
|
17212
|
-
padding:
|
17098
|
+
padding: ${isSmall ? '0' : '1rem'};
|
17213
17099
|
border-radius: 5px;
|
17214
17100
|
}
|
17215
17101
|
|
17216
|
-
.
|
17217
|
-
height: 100%;
|
17218
|
-
display: flex;
|
17219
|
-
flex-direction: column;
|
17220
|
-
gap: 20px;
|
17221
|
-
}
|
17222
|
-
|
17223
|
-
.image-placeholder {
|
17102
|
+
.line {
|
17224
17103
|
width: 100%;
|
17225
17104
|
height: 100%;
|
17105
|
+
min-height: 15px;
|
17226
17106
|
background: #f0f0f0;
|
17227
|
-
border-radius:
|
17228
|
-
position: relative;
|
17229
|
-
overflow: hidden;
|
17230
|
-
}
|
17231
|
-
|
17232
|
-
.lines-container {
|
17233
|
-
display: flex;
|
17234
|
-
flex-direction: column;
|
17235
|
-
justify-content: flex-end;
|
17236
|
-
}
|
17237
|
-
|
17238
|
-
.line {
|
17239
|
-
height: 20px;
|
17240
|
-
background: #f0f0f0;
|
17241
|
-
border-radius: 4px;
|
17242
|
-
margin-bottom: 15px;
|
17107
|
+
border-radius: 5px;
|
17243
17108
|
position: relative;
|
17244
17109
|
overflow: hidden;
|
17245
17110
|
}
|
17246
17111
|
|
17247
|
-
.image-placeholder::after,
|
17248
17112
|
.line::after {
|
17249
17113
|
content: "";
|
17250
17114
|
position: absolute;
|
@@ -17261,18 +17125,6 @@ function SkeletonTemplate({ fluid, width, height }) {
|
|
17261
17125
|
animation: shimmer 1.5s infinite;
|
17262
17126
|
}
|
17263
17127
|
|
17264
|
-
.line.header {
|
17265
|
-
width: 25%;
|
17266
|
-
}
|
17267
|
-
|
17268
|
-
.line.description {
|
17269
|
-
width: 65%;
|
17270
|
-
}
|
17271
|
-
|
17272
|
-
.line.button {
|
17273
|
-
width: 40%;
|
17274
|
-
}
|
17275
|
-
|
17276
17128
|
@keyframes shimmer {
|
17277
17129
|
0% {
|
17278
17130
|
transform: translateX(-100%);
|
@@ -17283,14 +17135,7 @@ function SkeletonTemplate({ fluid, width, height }) {
|
|
17283
17135
|
}
|
17284
17136
|
</style>
|
17285
17137
|
|
17286
|
-
<div class="
|
17287
|
-
<div class="image-placeholder"></div>
|
17288
|
-
<div class="lines-container">
|
17289
|
-
<div class="line header"></div>
|
17290
|
-
<div class="line description"></div>
|
17291
|
-
<div class="line button"></div>
|
17292
|
-
</div>
|
17293
|
-
</div>
|
17138
|
+
<div class="line"></div>
|
17294
17139
|
`;
|
17295
17140
|
}
|
17296
17141
|
|
@@ -17469,6 +17314,7 @@ class ElementService {
|
|
17469
17314
|
const skeleton = document.createElement(SKELETON_ELEMENT_TAG);
|
17470
17315
|
const dimensions = SPOT_DIMENSIONS[params.spotType];
|
17471
17316
|
skeleton.data = {
|
17317
|
+
spotType: params.spotType,
|
17472
17318
|
fluid: params.fluid,
|
17473
17319
|
...dimensions,
|
17474
17320
|
};
|
@@ -19384,45 +19230,45 @@ class DataLayerMonitor {
|
|
19384
19230
|
return result;
|
19385
19231
|
}
|
19386
19232
|
for (const pushedEvent of args) {
|
19387
|
-
const
|
19388
|
-
if (
|
19389
|
-
|
19233
|
+
const eventName = getEventTypeFromRawEvent(pushedEvent.event);
|
19234
|
+
if (!eventName) {
|
19235
|
+
continue;
|
19236
|
+
}
|
19237
|
+
const productData = this.extractProductData(pushedEvent);
|
19238
|
+
const eventData = {
|
19239
|
+
event: eventName,
|
19240
|
+
products: productData,
|
19241
|
+
};
|
19242
|
+
if (productData) {
|
19243
|
+
this.listener(eventData);
|
19390
19244
|
}
|
19391
19245
|
}
|
19392
19246
|
return result;
|
19393
19247
|
};
|
19394
19248
|
}
|
19395
|
-
|
19396
|
-
|
19397
|
-
|
19398
|
-
|
19399
|
-
|
19400
|
-
|
19401
|
-
|
19402
|
-
|
19403
|
-
|
19404
|
-
|
19405
|
-
|
19406
|
-
|
19407
|
-
|
19408
|
-
|
19409
|
-
|
19410
|
-
|
19411
|
-
|
19412
|
-
|
19413
|
-
|
19414
|
-
|
19415
|
-
});
|
19416
|
-
const productQuantity = extractDeepValues(data, 'quantity', {
|
19417
|
-
onlyFirst: true,
|
19418
|
-
shouldIncludeZero: true,
|
19419
|
-
});
|
19420
|
-
if (productPrice) {
|
19421
|
-
normalizedData.productPrice = productPrice;
|
19422
|
-
normalizedData.productQuantity = productQuantity !== null && productQuantity !== void 0 ? productQuantity : 1;
|
19249
|
+
extractProductData(event) {
|
19250
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
19251
|
+
const items = ((_a = event === null || event === void 0 ? void 0 : event.value) === null || _a === void 0 ? void 0 : _a.items) ||
|
19252
|
+
((_b = event === null || event === void 0 ? void 0 : event.ecommerce) === null || _b === void 0 ? void 0 : _b.items) ||
|
19253
|
+
((_d = (_c = event === null || event === void 0 ? void 0 : event.ecommerce) === null || _c === void 0 ? void 0 : _c.detail) === null || _d === void 0 ? void 0 : _d.products) ||
|
19254
|
+
((_f = (_e = event === null || event === void 0 ? void 0 : event.ecommerce) === null || _e === void 0 ? void 0 : _e.checkout) === null || _f === void 0 ? void 0 : _f.products) ||
|
19255
|
+
((_h = (_g = event === null || event === void 0 ? void 0 : event.ecommerce) === null || _g === void 0 ? void 0 : _g.purchase) === null || _h === void 0 ? void 0 : _h.products) ||
|
19256
|
+
[];
|
19257
|
+
return items.map((item) => {
|
19258
|
+
const data = {
|
19259
|
+
id: item.item_id || item.id || '',
|
19260
|
+
name: item.item_name || item.name || '',
|
19261
|
+
brand: item.item_brand || item.brand || '',
|
19262
|
+
variant: item.item_variant || item.variant || '',
|
19263
|
+
price: Number(item.price) || 0,
|
19264
|
+
quantity: Number(item.quantity) || 1,
|
19265
|
+
discount: Number(item.discount) || 0,
|
19266
|
+
};
|
19267
|
+
if (!data.id) {
|
19268
|
+
return null;
|
19423
19269
|
}
|
19424
|
-
|
19425
|
-
|
19270
|
+
return data;
|
19271
|
+
});
|
19426
19272
|
}
|
19427
19273
|
stop() {
|
19428
19274
|
if (this.originalPush) {
|
@@ -19472,40 +19318,49 @@ class MonitorService {
|
|
19472
19318
|
var _a;
|
19473
19319
|
if (!spots)
|
19474
19320
|
return;
|
19475
|
-
const eventProductIds = new Set(cleanProductIds(eventData.productIds));
|
19476
19321
|
for (const spot of Object.values(spots)) {
|
19477
19322
|
if (!spot.productIds.length)
|
19478
19323
|
continue;
|
19479
|
-
const
|
19480
|
-
|
19481
|
-
|
19324
|
+
for (const data of eventData.products) {
|
19325
|
+
if (!Object.values(RMN_SPOT_EVENT).includes(eventData.event)) {
|
19326
|
+
continue;
|
19327
|
+
}
|
19328
|
+
const spotRelatedProductIdsSet = new Set(cleanProductIds(spot.productIds));
|
19329
|
+
const [eventProductId] = cleanProductIds([data.id]);
|
19330
|
+
const [eventProductBrand] = cleanProductIds([data.brand]);
|
19331
|
+
const [eventVariantBrand] = cleanProductIds([data.variant]);
|
19332
|
+
const isProductMatch = [eventProductId, eventProductBrand, eventVariantBrand].some((id) => spotRelatedProductIdsSet.has(id));
|
19333
|
+
if (!isProductMatch) {
|
19334
|
+
continue;
|
19335
|
+
}
|
19336
|
+
const eventPosition = spot.events.findIndex((event) => event.event === eventData.event);
|
19337
|
+
if (eventPosition === -1)
|
19338
|
+
continue;
|
19339
|
+
const eventUrl = spot.events[eventPosition].url;
|
19340
|
+
let additionalQueryParams = '';
|
19341
|
+
if (eventData.event === RMN_SPOT_EVENT.PURCHASE) {
|
19342
|
+
const gmv = data.price && data.quantity ? data.price * data.quantity : undefined;
|
19343
|
+
// gmv = gross merchandise value, it is calculated by multiplying the product price by the product quantity
|
19344
|
+
additionalQueryParams = objectToQueryParams({ gmv });
|
19345
|
+
}
|
19346
|
+
// Fire the event and publish it to the pubsub service
|
19347
|
+
await this.fireAndPublishSpotEvent({
|
19348
|
+
spotEvent: eventData.event,
|
19349
|
+
eventUrl: `${eventUrl}${additionalQueryParams ? `&${additionalQueryParams}` : ''}`,
|
19350
|
+
placementId: spot.placementId,
|
19351
|
+
spotId: spot.spotId,
|
19352
|
+
});
|
19353
|
+
// Remove the event url from the spot to prevent duplicate events
|
19354
|
+
spot.events[eventPosition].url = '';
|
19355
|
+
// Update the spots in the local storage
|
19356
|
+
(_a = this.localStorageService) === null || _a === void 0 ? void 0 : _a.setSpot(spot.spotId, {
|
19357
|
+
placementId: spot.placementId,
|
19358
|
+
spotId: spot.spotId,
|
19359
|
+
spotType: spot.spotType,
|
19360
|
+
events: spot.events,
|
19361
|
+
productIds: spot.productIds,
|
19362
|
+
});
|
19482
19363
|
}
|
19483
|
-
const eventPosition = spot.events.findIndex((event) => event.event === eventData.event);
|
19484
|
-
if (eventPosition === -1)
|
19485
|
-
continue;
|
19486
|
-
const eventUrl = spot.events[eventPosition].url;
|
19487
|
-
const gmv = eventData.productPrice && eventData.productQuantity
|
19488
|
-
? eventData.productPrice * eventData.productQuantity
|
19489
|
-
: undefined;
|
19490
|
-
// gmv = gross merchandise value, it is calculated by multiplying the product price by the product quantity
|
19491
|
-
const additionalQueryParams = objectToQueryParams({ gmv });
|
19492
|
-
// Fire the event and publish it to the pubsub service
|
19493
|
-
await this.fireAndPublishSpotEvent({
|
19494
|
-
spotEvent: eventData.event,
|
19495
|
-
eventUrl: `${eventUrl}${additionalQueryParams ? `&${additionalQueryParams}` : ''}`,
|
19496
|
-
placementId: spot.placementId,
|
19497
|
-
spotId: spot.spotId,
|
19498
|
-
});
|
19499
|
-
// Remove the event url from the spot to prevent duplicate events
|
19500
|
-
spot.events[eventPosition].url = '';
|
19501
|
-
// Update the spots in the local storage
|
19502
|
-
(_a = this.localStorageService) === null || _a === void 0 ? void 0 : _a.setSpot(spot.spotId, {
|
19503
|
-
placementId: spot.placementId,
|
19504
|
-
spotId: spot.spotId,
|
19505
|
-
spotType: spot.spotType,
|
19506
|
-
events: spot.events,
|
19507
|
-
productIds: spot.productIds,
|
19508
|
-
});
|
19509
19364
|
}
|
19510
19365
|
}
|
19511
19366
|
async fireAndPublishSpotEvent({ spotEvent, eventUrl, placementId, spotId, }) {
|
@@ -1,2 +1,2 @@
|
|
1
1
|
import type { ICustomSkeletonElementData } from './skeleton.interface';
|
2
|
-
export declare function SkeletonTemplate({ fluid, width, height }: ICustomSkeletonElementData): string;
|
2
|
+
export declare function SkeletonTemplate({ fluid, width, height, spotType, }: ICustomSkeletonElementData): string;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import type { RMN_SPOT_EVENT } from 'enums';
|
2
2
|
export interface IDataLayerEvent {
|
3
|
-
event:
|
4
|
-
|
3
|
+
event: RMN_SPOT_EVENT;
|
4
|
+
products: IProductData[];
|
5
5
|
}
|
6
6
|
export interface INormalizedEventData {
|
7
7
|
event: RMN_SPOT_EVENT;
|
@@ -15,3 +15,12 @@ export interface IFireAndPublishSpotEventParams {
|
|
15
15
|
placementId: string;
|
16
16
|
spotId: string;
|
17
17
|
}
|
18
|
+
export interface IProductData {
|
19
|
+
id: string | number;
|
20
|
+
name: string;
|
21
|
+
brand: string;
|
22
|
+
variant: string;
|
23
|
+
price: number;
|
24
|
+
quantity: number;
|
25
|
+
discount?: number;
|
26
|
+
}
|
@@ -1,12 +1,12 @@
|
|
1
|
-
import type {
|
1
|
+
import type { IDataLayerEvent } from '../monitor.interface';
|
2
2
|
export declare class DataLayerMonitor {
|
3
3
|
private static instance;
|
4
4
|
private readonly originalPush;
|
5
5
|
private listener?;
|
6
6
|
private constructor();
|
7
7
|
static getInstance(): DataLayerMonitor;
|
8
|
-
setListener(listener: (data:
|
8
|
+
setListener(listener: (data: IDataLayerEvent) => void): void;
|
9
9
|
start(): void;
|
10
|
-
private
|
10
|
+
private extractProductData;
|
11
11
|
stop(): void;
|
12
12
|
}
|
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.
|
5
|
+
"version": "1.5.0-beta.27",
|
6
6
|
"homepage": "https://docs.liquidcommerce.co/rmn-sdk",
|
7
7
|
"main": "./dist/index.cjs",
|
8
8
|
"module": "./dist/index.esm.js",
|