@liquidcommercedev/rmn-sdk 1.5.0-beta.20 → 1.5.0-beta.21

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.cjs CHANGED
@@ -20203,6 +20203,7 @@ function clearPlacement(placementId) {
20203
20203
  function prepareSpotPlacement(placement) {
20204
20204
  placement.removeAttribute('style');
20205
20205
  placement.removeAttribute('class');
20206
+ placement.setAttribute('data-spot-parent', 'true');
20206
20207
  const styles = {
20207
20208
  width: '100%',
20208
20209
  height: '100%',
@@ -20211,24 +20212,6 @@ function prepareSpotPlacement(placement) {
20211
20212
  };
20212
20213
  Object.assign(placement.style, styles);
20213
20214
  }
20214
- /**
20215
- * Waits for the DOM to be ready before continuing.
20216
- *
20217
- * @return {Promise<void>} - A promise that resolves when the DOM is ready.
20218
- */
20219
- async function waitForDOM() {
20220
- if (!isBrowserEnvironment()) {
20221
- return;
20222
- }
20223
- if (document.readyState === 'complete' || document.readyState === 'interactive') {
20224
- return;
20225
- }
20226
- return new Promise((resolve) => {
20227
- document.addEventListener('DOMContentLoaded', () => {
20228
- resolve();
20229
- });
20230
- });
20231
- }
20232
20215
  // Sets the id for the user who is browsing the website
20233
20216
  // This id is used to identify the user and provide personalized content
20234
20217
  function setUserId() {
@@ -20237,6 +20220,35 @@ function setUserId() {
20237
20220
  localStorageService.setUserId();
20238
20221
  }
20239
20222
  }
20223
+ function initDOMObserver(elementIds, callback) {
20224
+ const checkElement = (element) => {
20225
+ if (element.id &&
20226
+ elementIds.includes(element.id) &&
20227
+ !element.getAttribute('data-spot-parent')) {
20228
+ callback(element);
20229
+ }
20230
+ };
20231
+ const observer = new MutationObserver((mutations) => {
20232
+ mutations.forEach((mutation) => {
20233
+ if (mutation.type === 'childList') {
20234
+ mutation.addedNodes.forEach((node) => {
20235
+ if (node.nodeType === Node.ELEMENT_NODE) {
20236
+ checkElement(node);
20237
+ node
20238
+ .querySelectorAll('*')
20239
+ .forEach((el) => checkElement(el));
20240
+ }
20241
+ });
20242
+ }
20243
+ });
20244
+ });
20245
+ observer.observe(document.body, {
20246
+ childList: true,
20247
+ subtree: true,
20248
+ });
20249
+ document.querySelectorAll('*').forEach((el) => checkElement(el));
20250
+ return observer;
20251
+ }
20240
20252
 
20241
20253
  /**
20242
20254
  * LiquidCommerce Rmn Client
@@ -20270,9 +20282,6 @@ class LiquidCommerceRmnClient {
20270
20282
  * @return {Promise<void>} - A promise that resolves when the spot elements are injected.
20271
20283
  */
20272
20284
  async injectSpotElement(params) {
20273
- var _a;
20274
- // Wait for the DOM to be ready before continuing, to avoid issues with the spot placements
20275
- await waitForDOM();
20276
20285
  const config = params.config;
20277
20286
  // Handle no spots error state
20278
20287
  if (!params.inject.length) {
@@ -20285,41 +20294,42 @@ class LiquidCommerceRmnClient {
20285
20294
  }
20286
20295
  // Validate inject data
20287
20296
  const inject = validateInjectData(params.inject);
20288
- for (const item of inject) {
20289
- // Identify the spot element
20290
- this.eventService.handleSpotState(item.placementId, {
20291
- identifier: {
20292
- placementId: item.placementId,
20293
- spotType: item.spotType,
20294
- },
20295
- }, false);
20296
- const placement = document.getElementById(item.placementId);
20297
+ const placementElementShowedInDOM = (placement) => {
20298
+ var _a;
20299
+ const data = inject.find((item) => item.placementId === placement.id);
20297
20300
  // Handle placement not found error state
20298
- if (!placement) {
20299
- this.eventService.handleSpotState(item.placementId, {
20301
+ if (!data) {
20302
+ this.eventService.handleSpotState(placement.id, {
20300
20303
  state: {
20301
- error: `Placement not found for id "${item.placementId}".`,
20304
+ error: `Placement not found for id "${placement.id}".`,
20302
20305
  mounted: false,
20303
20306
  loading: false,
20304
20307
  },
20305
20308
  });
20306
- continue;
20309
+ return;
20307
20310
  }
20311
+ // Identify the spot element
20312
+ this.eventService.handleSpotState(data.placementId, {
20313
+ identifier: {
20314
+ placementId: data.placementId,
20315
+ spotType: data.spotType,
20316
+ },
20317
+ }, false);
20308
20318
  prepareSpotPlacement(placement);
20309
20319
  const skeletonElement = this.elementService.createSkeletonElement({
20310
20320
  fluid: (_a = config === null || config === void 0 ? void 0 : config.fluid) !== null && _a !== void 0 ? _a : false,
20311
- spotType: item.spotType,
20321
+ spotType: data.spotType,
20312
20322
  });
20313
20323
  // Handle skeleton loader error state
20314
20324
  if (!skeletonElement) {
20315
- this.eventService.handleSpotState(item.placementId, {
20325
+ this.eventService.handleSpotState(data.placementId, {
20316
20326
  state: {
20317
20327
  error: `Failed to create skeleton loader element.`,
20318
20328
  mounted: false,
20319
20329
  loading: true,
20320
20330
  },
20321
20331
  });
20322
- continue;
20332
+ return;
20323
20333
  }
20324
20334
  placement.replaceChildren(skeletonElement);
20325
20335
  const spotPlacementIsNearCallback = async () => {
@@ -20327,34 +20337,34 @@ class LiquidCommerceRmnClient {
20327
20337
  // Stop observing the placement, as we only need to do this once
20328
20338
  this.intersectionObserver.unobserve(placement);
20329
20339
  // Set the spot element to loading state
20330
- this.eventService.handleSpotState(item.placementId, { state: { loading: true } });
20340
+ this.eventService.handleSpotState(data.placementId, { state: { loading: true } });
20331
20341
  // Make the spot selection request
20332
- const response = await this.injectSpotSelectionRequest({ ...params, inject: [item] });
20342
+ const response = await this.injectSpotSelectionRequest({ ...params, inject: [data] });
20333
20343
  // const response = await useSpotSelectionExample(inject);
20334
20344
  // Handle request error state
20335
20345
  if (typeof response === 'object' && 'error' in response) {
20336
- this.eventService.handleSpotState(item.placementId, {
20346
+ this.eventService.handleSpotState(data.placementId, {
20337
20347
  state: {
20338
20348
  error: response.error,
20339
20349
  mounted: false,
20340
20350
  loading: false,
20341
20351
  },
20342
20352
  });
20343
- clearPlacement(item.placementId);
20353
+ clearPlacement(data.placementId);
20344
20354
  return;
20345
20355
  }
20346
- const itemConfig = (_a = item.config) !== null && _a !== void 0 ? _a : config;
20347
- const spots = response[item.placementId];
20356
+ const itemConfig = (_a = data.config) !== null && _a !== void 0 ? _a : config;
20357
+ const spots = response[data.placementId];
20348
20358
  // Handle no spots found error state
20349
20359
  if (!(spots === null || spots === void 0 ? void 0 : spots.length)) {
20350
- this.eventService.handleSpotState(item.placementId, {
20360
+ this.eventService.handleSpotState(data.placementId, {
20351
20361
  state: {
20352
- error: `No spots found for type "${item.spotType}".`,
20362
+ error: `No spots found for type "${data.spotType}".`,
20353
20363
  mounted: false,
20354
20364
  loading: false,
20355
20365
  },
20356
20366
  });
20357
- clearPlacement(item.placementId);
20367
+ clearPlacement(data.placementId);
20358
20368
  return;
20359
20369
  }
20360
20370
  // Handle single spot
@@ -20374,7 +20384,8 @@ class LiquidCommerceRmnClient {
20374
20384
  rootMargin: '1000px',
20375
20385
  threshold: 0,
20376
20386
  });
20377
- }
20387
+ };
20388
+ initDOMObserver(inject.map((item) => item.placementId), placementElementShowedInDOM);
20378
20389
  }
20379
20390
  /**
20380
20391
  * Injects a single spot element into the provided placement.
package/dist/index.esm.js CHANGED
@@ -20201,6 +20201,7 @@ function clearPlacement(placementId) {
20201
20201
  function prepareSpotPlacement(placement) {
20202
20202
  placement.removeAttribute('style');
20203
20203
  placement.removeAttribute('class');
20204
+ placement.setAttribute('data-spot-parent', 'true');
20204
20205
  const styles = {
20205
20206
  width: '100%',
20206
20207
  height: '100%',
@@ -20209,24 +20210,6 @@ function prepareSpotPlacement(placement) {
20209
20210
  };
20210
20211
  Object.assign(placement.style, styles);
20211
20212
  }
20212
- /**
20213
- * Waits for the DOM to be ready before continuing.
20214
- *
20215
- * @return {Promise<void>} - A promise that resolves when the DOM is ready.
20216
- */
20217
- async function waitForDOM() {
20218
- if (!isBrowserEnvironment()) {
20219
- return;
20220
- }
20221
- if (document.readyState === 'complete' || document.readyState === 'interactive') {
20222
- return;
20223
- }
20224
- return new Promise((resolve) => {
20225
- document.addEventListener('DOMContentLoaded', () => {
20226
- resolve();
20227
- });
20228
- });
20229
- }
20230
20213
  // Sets the id for the user who is browsing the website
20231
20214
  // This id is used to identify the user and provide personalized content
20232
20215
  function setUserId() {
@@ -20235,6 +20218,35 @@ function setUserId() {
20235
20218
  localStorageService.setUserId();
20236
20219
  }
20237
20220
  }
20221
+ function initDOMObserver(elementIds, callback) {
20222
+ const checkElement = (element) => {
20223
+ if (element.id &&
20224
+ elementIds.includes(element.id) &&
20225
+ !element.getAttribute('data-spot-parent')) {
20226
+ callback(element);
20227
+ }
20228
+ };
20229
+ const observer = new MutationObserver((mutations) => {
20230
+ mutations.forEach((mutation) => {
20231
+ if (mutation.type === 'childList') {
20232
+ mutation.addedNodes.forEach((node) => {
20233
+ if (node.nodeType === Node.ELEMENT_NODE) {
20234
+ checkElement(node);
20235
+ node
20236
+ .querySelectorAll('*')
20237
+ .forEach((el) => checkElement(el));
20238
+ }
20239
+ });
20240
+ }
20241
+ });
20242
+ });
20243
+ observer.observe(document.body, {
20244
+ childList: true,
20245
+ subtree: true,
20246
+ });
20247
+ document.querySelectorAll('*').forEach((el) => checkElement(el));
20248
+ return observer;
20249
+ }
20238
20250
 
20239
20251
  /**
20240
20252
  * LiquidCommerce Rmn Client
@@ -20268,9 +20280,6 @@ class LiquidCommerceRmnClient {
20268
20280
  * @return {Promise<void>} - A promise that resolves when the spot elements are injected.
20269
20281
  */
20270
20282
  async injectSpotElement(params) {
20271
- var _a;
20272
- // Wait for the DOM to be ready before continuing, to avoid issues with the spot placements
20273
- await waitForDOM();
20274
20283
  const config = params.config;
20275
20284
  // Handle no spots error state
20276
20285
  if (!params.inject.length) {
@@ -20283,41 +20292,42 @@ class LiquidCommerceRmnClient {
20283
20292
  }
20284
20293
  // Validate inject data
20285
20294
  const inject = validateInjectData(params.inject);
20286
- for (const item of inject) {
20287
- // Identify the spot element
20288
- this.eventService.handleSpotState(item.placementId, {
20289
- identifier: {
20290
- placementId: item.placementId,
20291
- spotType: item.spotType,
20292
- },
20293
- }, false);
20294
- const placement = document.getElementById(item.placementId);
20295
+ const placementElementShowedInDOM = (placement) => {
20296
+ var _a;
20297
+ const data = inject.find((item) => item.placementId === placement.id);
20295
20298
  // Handle placement not found error state
20296
- if (!placement) {
20297
- this.eventService.handleSpotState(item.placementId, {
20299
+ if (!data) {
20300
+ this.eventService.handleSpotState(placement.id, {
20298
20301
  state: {
20299
- error: `Placement not found for id "${item.placementId}".`,
20302
+ error: `Placement not found for id "${placement.id}".`,
20300
20303
  mounted: false,
20301
20304
  loading: false,
20302
20305
  },
20303
20306
  });
20304
- continue;
20307
+ return;
20305
20308
  }
20309
+ // Identify the spot element
20310
+ this.eventService.handleSpotState(data.placementId, {
20311
+ identifier: {
20312
+ placementId: data.placementId,
20313
+ spotType: data.spotType,
20314
+ },
20315
+ }, false);
20306
20316
  prepareSpotPlacement(placement);
20307
20317
  const skeletonElement = this.elementService.createSkeletonElement({
20308
20318
  fluid: (_a = config === null || config === void 0 ? void 0 : config.fluid) !== null && _a !== void 0 ? _a : false,
20309
- spotType: item.spotType,
20319
+ spotType: data.spotType,
20310
20320
  });
20311
20321
  // Handle skeleton loader error state
20312
20322
  if (!skeletonElement) {
20313
- this.eventService.handleSpotState(item.placementId, {
20323
+ this.eventService.handleSpotState(data.placementId, {
20314
20324
  state: {
20315
20325
  error: `Failed to create skeleton loader element.`,
20316
20326
  mounted: false,
20317
20327
  loading: true,
20318
20328
  },
20319
20329
  });
20320
- continue;
20330
+ return;
20321
20331
  }
20322
20332
  placement.replaceChildren(skeletonElement);
20323
20333
  const spotPlacementIsNearCallback = async () => {
@@ -20325,34 +20335,34 @@ class LiquidCommerceRmnClient {
20325
20335
  // Stop observing the placement, as we only need to do this once
20326
20336
  this.intersectionObserver.unobserve(placement);
20327
20337
  // Set the spot element to loading state
20328
- this.eventService.handleSpotState(item.placementId, { state: { loading: true } });
20338
+ this.eventService.handleSpotState(data.placementId, { state: { loading: true } });
20329
20339
  // Make the spot selection request
20330
- const response = await this.injectSpotSelectionRequest({ ...params, inject: [item] });
20340
+ const response = await this.injectSpotSelectionRequest({ ...params, inject: [data] });
20331
20341
  // const response = await useSpotSelectionExample(inject);
20332
20342
  // Handle request error state
20333
20343
  if (typeof response === 'object' && 'error' in response) {
20334
- this.eventService.handleSpotState(item.placementId, {
20344
+ this.eventService.handleSpotState(data.placementId, {
20335
20345
  state: {
20336
20346
  error: response.error,
20337
20347
  mounted: false,
20338
20348
  loading: false,
20339
20349
  },
20340
20350
  });
20341
- clearPlacement(item.placementId);
20351
+ clearPlacement(data.placementId);
20342
20352
  return;
20343
20353
  }
20344
- const itemConfig = (_a = item.config) !== null && _a !== void 0 ? _a : config;
20345
- const spots = response[item.placementId];
20354
+ const itemConfig = (_a = data.config) !== null && _a !== void 0 ? _a : config;
20355
+ const spots = response[data.placementId];
20346
20356
  // Handle no spots found error state
20347
20357
  if (!(spots === null || spots === void 0 ? void 0 : spots.length)) {
20348
- this.eventService.handleSpotState(item.placementId, {
20358
+ this.eventService.handleSpotState(data.placementId, {
20349
20359
  state: {
20350
- error: `No spots found for type "${item.spotType}".`,
20360
+ error: `No spots found for type "${data.spotType}".`,
20351
20361
  mounted: false,
20352
20362
  loading: false,
20353
20363
  },
20354
20364
  });
20355
- clearPlacement(item.placementId);
20365
+ clearPlacement(data.placementId);
20356
20366
  return;
20357
20367
  }
20358
20368
  // Handle single spot
@@ -20372,7 +20382,8 @@ class LiquidCommerceRmnClient {
20372
20382
  rootMargin: '1000px',
20373
20383
  threshold: 0,
20374
20384
  });
20375
- }
20385
+ };
20386
+ initDOMObserver(inject.map((item) => item.placementId), placementElementShowedInDOM);
20376
20387
  }
20377
20388
  /**
20378
20389
  * Injects a single spot element into the provided placement.
@@ -29,13 +29,8 @@ export declare function clearPlacement(placementId: string): void;
29
29
  * @return {void}
30
30
  */
31
31
  export declare function prepareSpotPlacement(placement: HTMLElement): void;
32
- /**
33
- * Waits for the DOM to be ready before continuing.
34
- *
35
- * @return {Promise<void>} - A promise that resolves when the DOM is ready.
36
- */
37
- export declare function waitForDOM(): Promise<void>;
38
32
  export declare function useSpotSelectionExample(inject: IInjectSpotElement[]): Promise<ISpots | {
39
33
  error: string;
40
34
  }>;
41
35
  export declare function setUserId(): void;
36
+ export declare function initDOMObserver(elementIds: string[], callback: (element: HTMLElement) => void): MutationObserver;
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.20",
5
+ "version": "1.5.0-beta.21",
6
6
  "homepage": "https://docs.liquidcommerce.co/rmn-sdk",
7
7
  "main": "./dist/index.cjs",
8
8
  "module": "./dist/index.esm.js",