@liquidcommercedev/rmn-sdk 1.5.0-beta.25 → 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 +88 -207
- package/dist/index.esm.js +88 -207
- package/dist/types/common/helpers/extract-deep.helper.d.ts +1 -1
- 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 +12 -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,120 +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
|
-
};
|
6180
|
-
/**
|
6181
|
-
* Extracts deep values from an object based on specified target type
|
6182
|
-
* @param data - The source data object to extract values from
|
6183
|
-
* @param target - The type of values to extract ('ids' or 'price')
|
6184
|
-
* @param options - Optional configuration for the extraction process
|
6185
|
-
* @returns Array of extracted values or a single value if onlyFirst is true
|
6186
|
-
*/
|
6187
|
-
function extractDeepValues(data, target, options = {}) {
|
6188
|
-
const {
|
6189
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
6190
|
-
onlyFirst = false, shouldIncludeZero = false, } = options;
|
6191
|
-
const values = [];
|
6192
|
-
const targetProperties = new Set(extractorConfig[target].map((name) => name.toLowerCase()));
|
6193
|
-
/**
|
6194
|
-
* Checks if a property name matches the target criteria
|
6195
|
-
*/
|
6196
|
-
const isTargetField = (key) => {
|
6197
|
-
const normalizedKey = key.toLowerCase();
|
6198
|
-
const hasTarget = targetProperties.has(normalizedKey);
|
6199
|
-
if (target === 'ids') {
|
6200
|
-
return normalizedKey.endsWith('id') || normalizedKey.endsWith('ids') || hasTarget;
|
6201
|
-
}
|
6202
|
-
return hasTarget;
|
6203
|
-
};
|
6204
|
-
/**
|
6205
|
-
* Validates and normalizes extracted values
|
6206
|
-
*/
|
6207
|
-
const validateValue = (value) => {
|
6208
|
-
if (typeof value === 'string') {
|
6209
|
-
return value.trim().length > 0;
|
6210
|
-
}
|
6211
|
-
if (typeof value === 'number') {
|
6212
|
-
return !isNaN(value) && (shouldIncludeZero || value !== 0);
|
6213
|
-
}
|
6214
|
-
return false;
|
6215
|
-
};
|
6216
|
-
/**
|
6217
|
-
* Processes a value and extracts matching fields
|
6218
|
-
*/
|
6219
|
-
const processValue = (value, currentKey) => {
|
6220
|
-
// Early exit conditions
|
6221
|
-
if (value == null || (onlyFirst && values.length > 0))
|
6222
|
-
return;
|
6223
|
-
// Process current value if it matches target criteria
|
6224
|
-
if (currentKey && isTargetField(currentKey)) {
|
6225
|
-
if (Array.isArray(value)) {
|
6226
|
-
const validValues = value.filter(validateValue);
|
6227
|
-
values.push(...validValues);
|
6228
|
-
}
|
6229
|
-
else if (validateValue(value)) {
|
6230
|
-
values.push(value);
|
6231
|
-
}
|
6232
|
-
return;
|
6233
|
-
}
|
6234
|
-
// Recursive processing for nested structures
|
6235
|
-
if (Array.isArray(value)) {
|
6236
|
-
value.forEach((item) => processValue(item));
|
6237
|
-
}
|
6238
|
-
else if (typeof value === 'object') {
|
6239
|
-
Object.entries(value).forEach(([key, val]) => processValue(val, key));
|
6240
|
-
}
|
6241
|
-
};
|
6242
|
-
processValue(data);
|
6243
|
-
// Return based on options
|
6244
|
-
if (values.length === 0)
|
6245
|
-
return undefined;
|
6246
|
-
return onlyFirst ? values[0] : values;
|
6247
|
-
}
|
6248
6134
|
/**
|
6249
6135
|
* Cleans and normalizes an array of product IDs by:
|
6250
6136
|
* 1. Converting all IDs to strings
|
@@ -16673,8 +16559,8 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined
|
|
16673
16559
|
// Map clone to original for event handling
|
16674
16560
|
this.cloneToOriginalMap.set(clonedSlide, this.slides[index]);
|
16675
16561
|
let isDragging = false;
|
16676
|
-
slideElement.addEventListener('mousedown', () => isDragging = false);
|
16677
|
-
slideElement.addEventListener('mousemove', () => isDragging = true);
|
16562
|
+
slideElement.addEventListener('mousedown', () => (isDragging = false));
|
16563
|
+
slideElement.addEventListener('mousemove', () => (isDragging = true));
|
16678
16564
|
// Add event delegation to the slide container
|
16679
16565
|
slideElement.addEventListener('click', (e) => {
|
16680
16566
|
if (isDragging) {
|
@@ -17197,7 +17083,8 @@ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined
|
|
17197
17083
|
CarouselElement = CustomCarouselElement;
|
17198
17084
|
}
|
17199
17085
|
|
17200
|
-
function SkeletonTemplate({ fluid, width, height }) {
|
17086
|
+
function SkeletonTemplate({ fluid, width, height, spotType, }) {
|
17087
|
+
const isSmall = spotType === RMN_SPOT_TYPE.RB_IN_TEXT;
|
17201
17088
|
return `
|
17202
17089
|
<style>
|
17203
17090
|
:host {
|
@@ -17208,42 +17095,20 @@ function SkeletonTemplate({ fluid, width, height }) {
|
|
17208
17095
|
width: ${fluid ? '100%' : `${width}px`};
|
17209
17096
|
height: ${fluid ? '100%' : `${height}px`};
|
17210
17097
|
background: #ffffff;
|
17211
|
-
padding:
|
17098
|
+
padding: ${isSmall ? '0' : '1rem'};
|
17212
17099
|
border-radius: 5px;
|
17213
17100
|
}
|
17214
17101
|
|
17215
|
-
.
|
17216
|
-
height: 100%;
|
17217
|
-
display: flex;
|
17218
|
-
flex-direction: column;
|
17219
|
-
gap: 20px;
|
17220
|
-
}
|
17221
|
-
|
17222
|
-
.image-placeholder {
|
17102
|
+
.line {
|
17223
17103
|
width: 100%;
|
17224
17104
|
height: 100%;
|
17105
|
+
min-height: 15px;
|
17225
17106
|
background: #f0f0f0;
|
17226
|
-
border-radius:
|
17227
|
-
position: relative;
|
17228
|
-
overflow: hidden;
|
17229
|
-
}
|
17230
|
-
|
17231
|
-
.lines-container {
|
17232
|
-
display: flex;
|
17233
|
-
flex-direction: column;
|
17234
|
-
justify-content: flex-end;
|
17235
|
-
}
|
17236
|
-
|
17237
|
-
.line {
|
17238
|
-
height: 20px;
|
17239
|
-
background: #f0f0f0;
|
17240
|
-
border-radius: 4px;
|
17241
|
-
margin-bottom: 15px;
|
17107
|
+
border-radius: 5px;
|
17242
17108
|
position: relative;
|
17243
17109
|
overflow: hidden;
|
17244
17110
|
}
|
17245
17111
|
|
17246
|
-
.image-placeholder::after,
|
17247
17112
|
.line::after {
|
17248
17113
|
content: "";
|
17249
17114
|
position: absolute;
|
@@ -17260,18 +17125,6 @@ function SkeletonTemplate({ fluid, width, height }) {
|
|
17260
17125
|
animation: shimmer 1.5s infinite;
|
17261
17126
|
}
|
17262
17127
|
|
17263
|
-
.line.header {
|
17264
|
-
width: 25%;
|
17265
|
-
}
|
17266
|
-
|
17267
|
-
.line.description {
|
17268
|
-
width: 65%;
|
17269
|
-
}
|
17270
|
-
|
17271
|
-
.line.button {
|
17272
|
-
width: 40%;
|
17273
|
-
}
|
17274
|
-
|
17275
17128
|
@keyframes shimmer {
|
17276
17129
|
0% {
|
17277
17130
|
transform: translateX(-100%);
|
@@ -17282,14 +17135,7 @@ function SkeletonTemplate({ fluid, width, height }) {
|
|
17282
17135
|
}
|
17283
17136
|
</style>
|
17284
17137
|
|
17285
|
-
<div class="
|
17286
|
-
<div class="image-placeholder"></div>
|
17287
|
-
<div class="lines-container">
|
17288
|
-
<div class="line header"></div>
|
17289
|
-
<div class="line description"></div>
|
17290
|
-
<div class="line button"></div>
|
17291
|
-
</div>
|
17292
|
-
</div>
|
17138
|
+
<div class="line"></div>
|
17293
17139
|
`;
|
17294
17140
|
}
|
17295
17141
|
|
@@ -17468,6 +17314,7 @@ class ElementService {
|
|
17468
17314
|
const skeleton = document.createElement(SKELETON_ELEMENT_TAG);
|
17469
17315
|
const dimensions = SPOT_DIMENSIONS[params.spotType];
|
17470
17316
|
skeleton.data = {
|
17317
|
+
spotType: params.spotType,
|
17471
17318
|
fluid: params.fluid,
|
17472
17319
|
...dimensions,
|
17473
17320
|
};
|
@@ -18909,7 +18756,7 @@ function rbHomepageHeroTwoTileTemplate(spot, config) {
|
|
18909
18756
|
`;
|
18910
18757
|
}
|
18911
18758
|
|
18912
|
-
const STYLES$4 = ({ textColor = '#
|
18759
|
+
const STYLES$4 = ({ textColor = '#212121', backgroundColor = 'transparent' }, { prefix }) => `
|
18913
18760
|
<style>
|
18914
18761
|
.${prefix} {
|
18915
18762
|
display: block;
|
@@ -18926,6 +18773,10 @@ const STYLES$4 = ({ textColor = '#ffffff', backgroundColor = 'transparent' }, {
|
|
18926
18773
|
font-family: "Source Sans 3", system-ui;
|
18927
18774
|
margin: 0;
|
18928
18775
|
}
|
18776
|
+
|
18777
|
+
.${prefix}__header:hover {
|
18778
|
+
color: #b5914a;
|
18779
|
+
}
|
18929
18780
|
</style>
|
18930
18781
|
`;
|
18931
18782
|
function rbInTextTemplate(spot, config) {
|
@@ -19379,40 +19230,45 @@ class DataLayerMonitor {
|
|
19379
19230
|
return result;
|
19380
19231
|
}
|
19381
19232
|
for (const pushedEvent of args) {
|
19382
|
-
const
|
19383
|
-
if (
|
19384
|
-
|
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);
|
19385
19244
|
}
|
19386
19245
|
}
|
19387
19246
|
return result;
|
19388
19247
|
};
|
19389
19248
|
}
|
19390
|
-
|
19391
|
-
|
19392
|
-
|
19393
|
-
|
19394
|
-
|
19395
|
-
|
19396
|
-
|
19397
|
-
|
19398
|
-
|
19399
|
-
|
19400
|
-
|
19401
|
-
|
19402
|
-
|
19403
|
-
|
19404
|
-
|
19405
|
-
|
19406
|
-
|
19407
|
-
|
19408
|
-
|
19409
|
-
|
19410
|
-
});
|
19411
|
-
if (productPrice) {
|
19412
|
-
normalizedData.productPrice = productPrice;
|
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;
|
19413
19269
|
}
|
19414
|
-
|
19415
|
-
|
19270
|
+
return data;
|
19271
|
+
});
|
19416
19272
|
}
|
19417
19273
|
stop() {
|
19418
19274
|
if (this.originalPush) {
|
@@ -19459,27 +19315,52 @@ class MonitorService {
|
|
19459
19315
|
this.implementedMonitor.start();
|
19460
19316
|
}
|
19461
19317
|
async matchAndFireEvent(eventData, spots) {
|
19462
|
-
var _a
|
19318
|
+
var _a;
|
19463
19319
|
if (!spots)
|
19464
19320
|
return;
|
19465
|
-
const eventProductIds = new Set(cleanProductIds(eventData.productIds));
|
19466
19321
|
for (const spot of Object.values(spots)) {
|
19467
19322
|
if (!spot.productIds.length)
|
19468
19323
|
continue;
|
19469
|
-
const
|
19470
|
-
|
19471
|
-
|
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
|
+
});
|
19472
19363
|
}
|
19473
|
-
const eventUrl = (_b = (_a = spot.events.find((event) => event.event === eventData.event)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '';
|
19474
|
-
const additionalQueryParams = objectToQueryParams({
|
19475
|
-
override: eventData.productPrice,
|
19476
|
-
});
|
19477
|
-
await this.fireAndPublishSpotEvent({
|
19478
|
-
spotEvent: eventData.event,
|
19479
|
-
eventUrl: `${eventUrl}${additionalQueryParams ? `&${additionalQueryParams}` : ''}`,
|
19480
|
-
placementId: spot.placementId,
|
19481
|
-
spotId: spot.spotId,
|
19482
|
-
});
|
19483
19364
|
}
|
19484
19365
|
}
|
19485
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,12 +1,13 @@
|
|
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;
|
8
8
|
productIds: Array<string | number>;
|
9
9
|
productPrice?: number;
|
10
|
+
productQuantity?: number;
|
10
11
|
}
|
11
12
|
export interface IFireAndPublishSpotEventParams {
|
12
13
|
spotEvent: RMN_SPOT_EVENT;
|
@@ -14,3 +15,12 @@ export interface IFireAndPublishSpotEventParams {
|
|
14
15
|
placementId: string;
|
15
16
|
spotId: string;
|
16
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",
|