@useinsider/guido 3.4.1-beta.6ed05e2 → 3.4.1-beta.8f6f02b

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.
@@ -1,33 +1,33 @@
1
- var k = Object.defineProperty;
2
- var B = (a, i, t) => i in a ? k(a, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[i] = t;
3
- var d = (a, i, t) => B(a, typeof i != "symbol" ? i + "" : i, t);
4
- import { BlockId as _ } from "../../../enums/block.js";
5
- import { getMigrationBannerHtml as C } from "../../../utils/migrationBannerHtml.js";
6
- import { Block as b, BlockCompositionType as R, ModificationDescription as y } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
7
- import { regenerateMobileProductRows as A } from "./controls/main/utils.js";
8
- import { ensureMobileCssRulesExist as p, setMobileLayoutOptOut as f, hasMobileLayoutOptOut as N } from "./controls/mobileLayout/cssRules.js";
1
+ var B = Object.defineProperty;
2
+ var C = (a, s, t) => s in a ? B(a, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[s] = t;
3
+ var p = (a, s, t) => C(a, typeof s != "symbol" ? s + "" : s, t);
4
+ import { BlockId as R } from "../../../enums/block.js";
5
+ import { getMigrationBannerHtml as b } from "../../../utils/migrationBannerHtml.js";
6
+ import { Block as A, BlockCompositionType as y, ModificationDescription as f } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
7
+ import { regenerateMobileProductRows as D } from "./controls/main/utils.js";
8
+ import { ensureMobileCssRulesExist as h, setMobileLayoutOptOut as I, hasMobileLayoutOptOut as E } from "./controls/mobileLayout/cssRules.js";
9
9
  import { RecommendationConfigService as c } from "./services/configService.js";
10
- import { useRecommendationExtensionStore as m } from "./store/recommendation.js";
11
- import { getDefaultTemplate as D } from "./templates/grid/template.js";
12
- const h = _.Recommendation, u = "recommendation-block-v2", l = "recommendation-id";
13
- let I = !1;
14
- class q extends b {
10
+ import { useRecommendationExtensionStore as g } from "./store/recommendation.js";
11
+ import { getDefaultTemplate as N } from "./templates/grid/template.js";
12
+ const k = R.Recommendation, m = "recommendation-block-v2", u = "recommendation-id";
13
+ let _ = !1;
14
+ class q extends A {
15
15
  constructor() {
16
16
  super();
17
17
  /**
18
18
  * Stores the ID generated in getTemplate() so onCreated() can reuse it.
19
19
  * This avoids generating a new (different) ID in onCreated().
20
20
  */
21
- d(this, "_pendingBlockId", null);
21
+ p(this, "_pendingBlockId", null);
22
22
  }
23
23
  getId() {
24
- return h;
24
+ return k;
25
25
  }
26
26
  getIcon() {
27
27
  return "recommendation-icon";
28
28
  }
29
29
  getBlockCompositionType() {
30
- return R.CONTAINER;
30
+ return y.CONTAINER;
31
31
  }
32
32
  getName() {
33
33
  return this.api.translate("Recommendation Block");
@@ -38,8 +38,8 @@ class q extends b {
38
38
  );
39
39
  }
40
40
  getSettingsPanelTitleHtml() {
41
- return C(
42
- h,
41
+ return b(
42
+ k,
43
43
  this.api.translate("Recommendation Block"),
44
44
  this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
45
45
  );
@@ -59,7 +59,7 @@ class q extends b {
59
59
  */
60
60
  getTemplate() {
61
61
  const t = this._generateNextId();
62
- return this._pendingBlockId = t, D(t);
62
+ return this._pendingBlockId = t, N(t);
63
63
  }
64
64
  /**
65
65
  * Called when a new block is dropped into the template
@@ -70,19 +70,21 @@ class q extends b {
70
70
  */
71
71
  onCreated(t) {
72
72
  const e = this._getRecommendationId(t);
73
- if (e !== null && e > 0)
73
+ if (e !== null && e > 0) {
74
+ this._detectDuplicate(e) && this._handleDuplicate(t, e);
74
75
  return;
75
- const o = this._pendingBlockId ?? this._generateNextId();
76
- this._pendingBlockId = null, this._assignRecommendationId(t, o);
77
- const { config: n, wasFreshDrop: s } = c.initializeConfig(
76
+ }
77
+ const i = this._pendingBlockId ?? this._generateNextId();
78
+ this._pendingBlockId = null, this._assignRecommendationId(t, i);
79
+ const { config: n, wasFreshDrop: o } = c.initializeConfig(
78
80
  this.api,
79
81
  t,
80
- { recommendationId: o }
81
- ), r = m();
82
- if (r.setCurrentBlock(o), s) {
83
- p(this.api);
84
- const g = this._getBlockElement(t);
85
- g && (f(this.api, g, !0), A({
82
+ { recommendationId: i }
83
+ ), r = g();
84
+ if (r.setCurrentBlock(i), o) {
85
+ h(this.api);
86
+ const l = this._getBlockElement(t);
87
+ l && (I(this.api, l, !0), D({
86
88
  currentNode: t,
87
89
  documentModifier: this.api.getDocumentModifier()
88
90
  }));
@@ -109,11 +111,11 @@ class q extends b {
109
111
  }
110
112
  c.needsMigration(t) && this._migrateFromLegacy(t);
111
113
  try {
112
- I || (p(this.api), I = !0);
113
- const e = c.getConfig(t), o = this._getBlockElement(t);
114
- if (o) {
114
+ _ || (h(this.api), _ = !0);
115
+ const e = c.getConfig(t), i = this._getBlockElement(t);
116
+ if (i) {
115
117
  const n = !e.mobileLayoutEnabled;
116
- N(o) !== n && f(this.api, o, n);
118
+ E(i) !== n && I(this.api, i, n);
117
119
  }
118
120
  } catch {
119
121
  }
@@ -127,26 +129,7 @@ class q extends b {
127
129
  */
128
130
  onDelete(t) {
129
131
  const e = this._getRecommendationId(t);
130
- e && m().removeBlockState(e);
131
- }
132
- /**
133
- * Lifecycle hook fired when Stripo's UI Duplicate button copies a block.
134
- * Stripo passes an `HtmlNodeModifier` already targeting the cloned node;
135
- * its mutations are committed when this method returns. We stamp a fresh
136
- * `recommendation-id` on the clone and seed its blockStates entry from
137
- * the source so the duplicate enters the DOM as a fully independent block
138
- * — no shared id, no shared store, no API refetch flash.
139
- *
140
- * Stripo does NOT fire `onCreated` for blocks created via duplicate
141
- * (per Block.d.ts:54-69 — `onCreated` is drag-and-drop only), so this
142
- * hook is the sole production path for clone id assignment.
143
- */
144
- onCopy(t) {
145
- const e = t.getTargetNode(), o = this._getRecommendationId(e), n = this._generateNextId(), s = c.getConfig(e);
146
- if (t.setAttribute(l, n.toString()).setNodeConfig({ ...s, recommendationId: n }), o !== null && o > 0) {
147
- const r = m();
148
- r.cloneBlockState(o, n), r.setCurrentBlock(n);
149
- }
132
+ e && g().removeBlockState(e);
150
133
  }
151
134
  /**
152
135
  * Generates the next unique recommendation ID by scanning all existing blocks
@@ -156,9 +139,9 @@ class q extends b {
156
139
  let t = 0;
157
140
  try {
158
141
  const e = this.api.getDocumentRoot();
159
- e && "querySelectorAll" in e && e.querySelectorAll(`.${u}`).forEach((n) => {
142
+ e && "querySelectorAll" in e && e.querySelectorAll(`.${m}`).forEach((n) => {
160
143
  if ("getAttribute" in n) {
161
- const s = n.getAttribute(l), r = s ? parseInt(s) : 0;
144
+ const o = n.getAttribute(u), r = o ? parseInt(o) : 0;
162
145
  r > t && (t = r);
163
146
  }
164
147
  });
@@ -166,6 +149,49 @@ class q extends b {
166
149
  }
167
150
  return t + 1;
168
151
  }
152
+ /** True when another block already holds the same id — Stripo's duplication signal. */
153
+ _detectDuplicate(t) {
154
+ try {
155
+ const e = this.api.getDocumentRoot();
156
+ if (e && "querySelectorAll" in e)
157
+ return e.querySelectorAll(
158
+ `.${m}[${u}="${t}"]`
159
+ ).length > 1;
160
+ } catch {
161
+ }
162
+ return !1;
163
+ }
164
+ /** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
165
+ _handleDuplicate(t, e) {
166
+ const i = this._generateNextId(), n = this._getBlockElement(t);
167
+ this._assignRecommendationId(t, i), n && this._reassignInstanceClass(n, e, i), c.hasConfig(t) && c.updateConfig(
168
+ this.api,
169
+ t,
170
+ { recommendationId: i },
171
+ `Reassign recommendation ID on duplicate (was ${e})`
172
+ );
173
+ const o = g();
174
+ o.cloneBlockState(e, i), o.setCurrentBlock(i);
175
+ }
176
+ /**
177
+ * Rewrites `ins-recommendation-v3-block-{id}` on the clone — the instance
178
+ * class scopes per-block CSS rules, so leaving the source's class would
179
+ * make stylistic edits leak between source and clone.
180
+ */
181
+ _reassignInstanceClass(t, e, i) {
182
+ if (!("getAttribute" in t))
183
+ return;
184
+ const n = t.getAttribute("class");
185
+ if (!n)
186
+ return;
187
+ const o = `ins-recommendation-v3-block-${e}`, r = `ins-recommendation-v3-block-${i}`;
188
+ if (!n.includes(o))
189
+ return;
190
+ const l = n.replace(o, r), d = this.api.getDocumentModifier();
191
+ d.modifyHtml(t).setAttribute("class", l), d.apply(new f(
192
+ `Reassign recommendation instance class ${o} -> ${r}`
193
+ ));
194
+ }
169
195
  /**
170
196
  * Assigns a recommendation-id attribute to the block element.
171
197
  * The instance class (ins-recommendation-v3-block-{id}) is embedded in the template
@@ -173,11 +199,11 @@ class q extends b {
173
199
  * added classes via setAttribute.
174
200
  */
175
201
  _assignRecommendationId(t, e) {
176
- const o = this._getBlockElement(t);
177
- if (!o)
202
+ const i = this._getBlockElement(t);
203
+ if (!i)
178
204
  return;
179
205
  const n = this.api.getDocumentModifier();
180
- n.modifyHtml(o).setAttribute(l, e.toString()), n.apply(new y(`Assign recommendation ID ${e}`));
206
+ n.modifyHtml(i).setAttribute(u, e.toString()), n.apply(new f(`Assign recommendation ID ${e}`));
181
207
  }
182
208
  /**
183
209
  * Gets the recommendation-id from a block node
@@ -186,10 +212,10 @@ class q extends b {
186
212
  const e = this._getBlockElement(t);
187
213
  if (!e || !("getAttribute" in e))
188
214
  return null;
189
- const o = e.getAttribute(l);
190
- if (!o)
215
+ const i = e.getAttribute(u);
216
+ if (!i)
191
217
  return null;
192
- const n = parseInt(o);
218
+ const n = parseInt(i);
193
219
  return Number.isNaN(n) ? null : n;
194
220
  }
195
221
  /**
@@ -198,10 +224,10 @@ class q extends b {
198
224
  _getBlockElement(t) {
199
225
  if ("getAttribute" in t) {
200
226
  const e = t.getAttribute("class");
201
- if (e && e.includes(u))
227
+ if (e && e.includes(m))
202
228
  return t;
203
229
  }
204
- return "querySelector" in t ? t.querySelector(`.${u}`) ?? null : null;
230
+ return "querySelector" in t ? t.querySelector(`.${m}`) ?? null : null;
205
231
  }
206
232
  /**
207
233
  * Migrate configuration from legacy format
@@ -211,6 +237,6 @@ class q extends b {
211
237
  }
212
238
  }
213
239
  export {
214
- h as BLOCK_ID,
240
+ k as BLOCK_ID,
215
241
  q as RecommendationBlock
216
242
  };
@@ -1,18 +1,18 @@
1
- import { getRecommendationFeedSourceMaps as S, getOperatorOptions as R, PriceAttributes as C } from "../../../../enums/extensions/recommendationBlock.js";
1
+ import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as C } from "../../../../enums/extensions/recommendationBlock.js";
2
2
  import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
3
3
  import { useConfigStore as G } from "../../../../stores/config.js";
4
4
  import { defineStore as P } from "pinia";
5
- import { DEFAULT_CARDS_IN_ROW as D } from "../constants/layout.js";
6
- import { EXCLUDED_ALGORITHM_IDS as F } from "../constants/defaultConfig.js";
7
- import { getDefaultProducts as g } from "../templates/utils.js";
5
+ import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
6
+ import { EXCLUDED_ALGORITHM_IDS as D } from "../constants/defaultConfig.js";
7
+ import { getDefaultProducts as S } from "../templates/utils.js";
8
8
  import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
9
- import { isFilterValid as w } from "../validation/filterSchema.js";
10
- import { isConfigValid as v } from "../validation/requiredFields.js";
9
+ import { isFilterValid as v } from "../validation/filterSchema.js";
10
+ import { isConfigValid as w } from "../validation/requiredFields.js";
11
11
  const h = y();
12
12
  let m = null, u = null, d = null;
13
- function k() {
13
+ function I() {
14
14
  return {
15
- cardsInRow: D,
15
+ cardsInRow: F,
16
16
  currencySettings: {
17
17
  name: "USD",
18
18
  value: "USD",
@@ -38,9 +38,9 @@ function k() {
38
38
  customAttributes: []
39
39
  };
40
40
  }
41
- function I() {
41
+ function k() {
42
42
  return {
43
- recommendationConfigs: k(),
43
+ recommendationConfigs: I(),
44
44
  recommendationProducts: [],
45
45
  filterStatus: !1,
46
46
  filterSelectionDrawerStatus: !1,
@@ -69,7 +69,7 @@ const N = () => ({
69
69
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
70
70
  */
71
71
  recommendationConfigs(t) {
72
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : k();
72
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : I();
73
73
  },
74
74
  /**
75
75
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
@@ -114,8 +114,8 @@ const N = () => ({
114
114
  return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
115
115
  },
116
116
  getActivePredictiveAlgorithms: (t) => {
117
- const e = S(), r = [];
118
- return t.activePredictiveAlgorithms.filter((n) => !F.includes(n)).forEach((n) => {
117
+ const e = g(), r = [];
118
+ return t.activePredictiveAlgorithms.filter((n) => !D.includes(n)).forEach((n) => {
119
119
  r.push(...e.filter((c) => c.id === n));
120
120
  }), r.map((n) => ({
121
121
  text: n.name,
@@ -155,7 +155,7 @@ const N = () => ({
155
155
  setCurrentBlock(t) {
156
156
  this.blockStates[t] || (this.blockStates = {
157
157
  ...this.blockStates,
158
- [t]: I()
158
+ [t]: k()
159
159
  }), this.currentRecommendationId = t;
160
160
  },
161
161
  /**
@@ -175,31 +175,22 @@ const N = () => ({
175
175
  }
176
176
  },
177
177
  /**
178
- * Copies blockStates[fromId] into a new blockStates[toId] entry so a
179
- * duplicated block immediately renders the source's products/filters
180
- * without re-fetching from the API (SD-142352). No-op when the source
181
- * was never selected (no entry in blockStates) — the caller falls back
182
- * to setCurrentBlock's default initialization.
178
+ * Deep-clones a block's state and mirrors its campaign URL under a new id.
179
+ * Invoked from `onCreated` when a duplicate is detected (SD-142352).
183
180
  */
184
181
  cloneBlockState(t, e) {
185
182
  const r = this.blockStates[t];
186
- !r || this.blockStates[e] || (this.blockStates = {
187
- ...this.blockStates,
188
- [e]: {
189
- ...r,
190
- recommendationProducts: [...r.recommendationProducts],
191
- recommendationConfigs: {
192
- ...r.recommendationConfigs,
193
- id: e,
194
- filters: r.recommendationConfigs.filters.map((n) => ({ ...n })),
195
- productIds: [...r.recommendationConfigs.productIds],
196
- customAttributes: [...r.recommendationConfigs.customAttributes],
197
- recommendedProducts: [...r.recommendationConfigs.recommendedProducts],
198
- currencySettings: { ...r.recommendationConfigs.currencySettings }
199
- },
200
- filterSnapshot: null,
201
- filterSelectionDrawerStatus: !1
202
- }
183
+ if (r) {
184
+ const o = structuredClone(r);
185
+ o.recommendationConfigs.id = e, this.blockStates = {
186
+ ...this.blockStates,
187
+ [e]: o
188
+ };
189
+ }
190
+ const n = t.toString(), c = e.toString(), i = this.recommendationCampaignUrls[n];
191
+ i && (this.recommendationCampaignUrls = {
192
+ ...this.recommendationCampaignUrls,
193
+ [c]: i
203
194
  });
204
195
  },
205
196
  /**
@@ -232,7 +223,7 @@ const N = () => ({
232
223
  decimalCount: String(e.currencyDecimalCount),
233
224
  decimalSeparator: r(e.currencyDecimalSeparator, ","),
234
225
  thousandSeparator: r(e.currencyThousandSeparator, ".")
235
- }, c = !this.blockStates[t], i = c ? I() : this.blockStates[t];
226
+ }, c = !this.blockStates[t], i = c ? k() : this.blockStates[t];
236
227
  i.recommendationConfigs = {
237
228
  ...i.recommendationConfigs,
238
229
  strategy: e.strategy,
@@ -387,7 +378,7 @@ const N = () => ({
387
378
  const n = [...e.recommendationConfigs.filters];
388
379
  n[r] = {
389
380
  ...t,
390
- isValid: w(t)
381
+ isValid: v(t)
391
382
  }, e.recommendationConfigs.filters = n;
392
383
  }
393
384
  },
@@ -433,7 +424,7 @@ const N = () => ({
433
424
  * every block's recommendationConfigs across user edits.
434
425
  */
435
426
  hasInvalidBlock() {
436
- return Object.values(this.blockStates).some((t) => !v(t.recommendationConfigs, this));
427
+ return Object.values(this.blockStates).some((t) => !w(t.recommendationConfigs, this));
437
428
  },
438
429
  // ====================================================================
439
430
  // Per-Block Product Fetching
@@ -454,7 +445,7 @@ const N = () => ({
454
445
  },
455
446
  async _doFetchProducts() {
456
447
  var p;
457
- const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = r.filters.filter((l) => l.isValid), c = b(n), i = ((p = S().find((l) => l.key === r.strategy)) == null ? void 0 : p.path) || "", o = G(), s = parseInt(r.size) || 6, a = {
448
+ const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = r.filters.filter((l) => l.isValid), c = b(n), i = ((p = g().find((l) => l.key === r.strategy)) == null ? void 0 : p.path) || "", o = G(), s = parseInt(r.size) || 6, a = {
458
449
  locale: r.language,
459
450
  currency: r.currencySettings.value,
460
451
  partnerName: o.partnerName,
@@ -470,10 +461,10 @@ const N = () => ({
470
461
  f = [];
471
462
  }
472
463
  if (this.blockStates[t]) {
473
- const l = f.length > 0 ? f : g(s);
464
+ const l = f.length > 0 ? f : S(s);
474
465
  l.length < s ? this.blockStates[t].recommendationProducts = [
475
466
  ...l,
476
- ...g(s - l.length)
467
+ ...S(s - l.length)
477
468
  ] : l.length > s ? this.blockStates[t].recommendationProducts = l.slice(0, s) : this.blockStates[t].recommendationProducts = l;
478
469
  }
479
470
  }
@@ -6,7 +6,7 @@
6
6
  * Supports multiple block instances with unique recommendation-id attributes.
7
7
  */
8
8
  import type { BlockId } from '@@/Types/extensions/block';
9
- import type { HtmlNodeModifier, ImmutableHtmlNode } from '@stripoinc/ui-editor-extensions';
9
+ import type { ImmutableHtmlNode } from '@stripoinc/ui-editor-extensions';
10
10
  import { Block, BlockCompositionType } from '@stripoinc/ui-editor-extensions';
11
11
  export declare const BLOCK_ID: BlockId;
12
12
  export declare class RecommendationBlock extends Block {
@@ -55,24 +55,21 @@ export declare class RecommendationBlock extends Block {
55
55
  * @param node - The block node being deleted
56
56
  */
57
57
  onDelete(node: ImmutableHtmlNode): void;
58
- /**
59
- * Lifecycle hook fired when Stripo's UI Duplicate button copies a block.
60
- * Stripo passes an `HtmlNodeModifier` already targeting the cloned node;
61
- * its mutations are committed when this method returns. We stamp a fresh
62
- * `recommendation-id` on the clone and seed its blockStates entry from
63
- * the source so the duplicate enters the DOM as a fully independent block
64
- * — no shared id, no shared store, no API refetch flash.
65
- *
66
- * Stripo does NOT fire `onCreated` for blocks created via duplicate
67
- * (per Block.d.ts:54-69 — `onCreated` is drag-and-drop only), so this
68
- * hook is the sole production path for clone id assignment.
69
- */
70
- onCopy(modifier: HtmlNodeModifier): void;
71
58
  /**
72
59
  * Generates the next unique recommendation ID by scanning all existing blocks
73
60
  * in the document and finding the maximum existing ID + 1.
74
61
  */
75
62
  private _generateNextId;
63
+ /** True when another block already holds the same id — Stripo's duplication signal. */
64
+ private _detectDuplicate;
65
+ /** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
66
+ private _handleDuplicate;
67
+ /**
68
+ * Rewrites `ins-recommendation-v3-block-{id}` on the clone — the instance
69
+ * class scopes per-block CSS rules, so leaving the source's class would
70
+ * make stylistic edits leak between source and clone.
71
+ */
72
+ private _reassignInstanceClass;
76
73
  /**
77
74
  * Assigns a recommendation-id attribute to the block element.
78
75
  * The instance class (ins-recommendation-v3-block-{id}) is embedded in the template
@@ -217,13 +217,10 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
217
217
  */
218
218
  removeBlockState(id: number): void;
219
219
  /**
220
- * Copies blockStates[fromId] into a new blockStates[toId] entry so a
221
- * duplicated block immediately renders the source's products/filters
222
- * without re-fetching from the API (SD-142352). No-op when the source
223
- * was never selected (no entry in blockStates) — the caller falls back
224
- * to setCurrentBlock's default initialization.
220
+ * Deep-clones a block's state and mirrors its campaign URL under a new id.
221
+ * Invoked from `onCreated` when a duplicate is detected (SD-142352).
225
222
  */
226
- cloneBlockState(fromId: number, toId: number): void;
223
+ cloneBlockState(sourceId: number, newId: number): void;
227
224
  /**
228
225
  * Marks a block as initialized (initial API data has been fetched).
229
226
  * Automatically cleaned up when removeBlockState deletes the block entry.
@@ -1,106 +1,101 @@
1
- import { useActionsApi as E } from "../composables/useActionsApi.js";
2
- import { useHtmlCompiler as P } from "../composables/useHtmlCompiler.js";
3
- import { DEFAULT_CURRENCY as p, DEFAULT_NODE_CONFIG as u } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
4
- import { BLOCK_ROOT_SELECTOR as R, CONTAINER_SELECTOR as N } from "../extensions/Blocks/Recommendation/constants/selectors.js";
1
+ import { useActionsApi as C } from "../composables/useActionsApi.js";
2
+ import { useHtmlCompiler as T } from "../composables/useHtmlCompiler.js";
3
+ import { DEFAULT_CURRENCY as d, DEFAULT_NODE_CONFIG as s } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
5
4
  import { useRecommendationExtensionStore as b } from "../extensions/Blocks/Recommendation/store/recommendation.js";
6
- import { DATA_ATTRIBUTES as y } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
7
- import { parsePageList as O } from "../extensions/Blocks/Unsubscribe/utils/utils.js";
8
- import { useDynamicContentStore as L } from "../stores/dynamic-content.js";
9
- import { useUnsubscribeStore as F } from "../stores/unsubscribe.js";
10
- function I(s, t) {
11
- const n = new DOMParser().parseFromString(s, "text/html").querySelectorAll(`[${y.PAGE_LIST}]`), c = [];
12
- return n.forEach((r) => {
13
- const o = r.getAttribute(y.PAGE_LIST);
14
- o && c.push(...O(o));
15
- }), t.filter((r) => c.includes(r));
5
+ import { DATA_ATTRIBUTES as S } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
6
+ import { parsePageList as D } from "../extensions/Blocks/Unsubscribe/utils/utils.js";
7
+ import { useDynamicContentStore as P } from "../stores/dynamic-content.js";
8
+ import { useUnsubscribeStore as w } from "../stores/unsubscribe.js";
9
+ function E(i, o) {
10
+ const t = new DOMParser().parseFromString(i, "text/html").querySelectorAll(`[${S.PAGE_LIST}]`), c = [];
11
+ return t.forEach((r) => {
12
+ const a = r.getAttribute(S.PAGE_LIST);
13
+ a && c.push(...D(a));
14
+ }), o.filter((r) => c.includes(r));
16
15
  }
17
- function w(s) {
18
- var c, r;
19
- const t = (r = (c = document.querySelector("ui-editor")) == null ? void 0 : c.shadowRoot) == null ? void 0 : r.querySelector("iframe"), m = (t == null ? void 0 : t.contentDocument) ?? new DOMParser().parseFromString(s, "text/html"), n = /* @__PURE__ */ new Set();
20
- return m.querySelectorAll(R).forEach((o) => {
21
- if (!o.querySelector(N))
22
- return;
23
- const e = Number(o.getAttribute("recommendation-id"));
24
- Number.isFinite(e) && e > 0 && n.add(e);
25
- }), n;
26
- }
27
- function x(s) {
28
- const a = new DOMParser().parseFromString(s, "text/html").querySelectorAll(".recommendation-block-v2");
29
- if (a.length === 0)
16
+ async function U(i) {
17
+ const m = new DOMParser().parseFromString(i, "text/html").querySelectorAll(".recommendation-block-v2");
18
+ if (m.length === 0)
30
19
  return;
31
- const m = b();
32
- a.forEach((n) => {
33
- var f, g, d, i, S;
34
- const c = n.getAttribute("recommendation-id"), r = c ? Number(c) : NaN;
20
+ const l = b();
21
+ m.forEach((t) => {
22
+ var g, f, u, n, y;
23
+ const c = t.getAttribute("recommendation-id"), r = c ? Number(c) : NaN;
35
24
  if (!Number.isFinite(r))
36
25
  return;
37
- const o = n.getAttribute("esd-ext-config");
38
- if (!o)
26
+ const a = t.getAttribute("esd-ext-config");
27
+ if (!a)
39
28
  return;
40
29
  let e;
41
30
  try {
42
- e = JSON.parse(o);
31
+ e = JSON.parse(a);
43
32
  } catch {
44
33
  return;
45
34
  }
46
35
  if (!e || typeof e != "object" || Array.isArray(e))
47
36
  return;
48
- const l = {
49
- strategy: e.strategy ?? u.strategy,
50
- language: e.language ?? u.language,
51
- size: e.size ?? u.size,
37
+ const p = {
38
+ strategy: e.strategy ?? s.strategy,
39
+ language: e.language ?? s.language,
40
+ size: e.size ?? s.size,
52
41
  // Spread the default arrays so each block gets a fresh reference
53
42
  // instead of sharing the singleton in DEFAULT_NODE_CONFIG.
54
- productIds: e.productIds ?? [...u.productIds],
55
- filters: e.filters ?? [...u.filters],
56
- shuffleProducts: e.shuffleProducts ?? u.shuffleProducts,
57
- currencyCode: ((f = e.currency) == null ? void 0 : f.code) ?? p.code,
58
- currencyAlignment: ((g = e.currency) == null ? void 0 : g.alignment) ?? p.alignment,
59
- currencyDecimalCount: ((d = e.currency) == null ? void 0 : d.decimalCount) ?? p.decimalCount,
60
- currencyDecimalSeparator: ((i = e.currency) == null ? void 0 : i.decimalSeparator) ?? p.decimalSeparator,
61
- currencyThousandSeparator: ((S = e.currency) == null ? void 0 : S.thousandSeparator) ?? p.thousandSeparator
43
+ productIds: e.productIds ?? [...s.productIds],
44
+ filters: e.filters ?? [...s.filters],
45
+ shuffleProducts: e.shuffleProducts ?? s.shuffleProducts,
46
+ currencyCode: ((g = e.currency) == null ? void 0 : g.code) ?? d.code,
47
+ currencyAlignment: ((f = e.currency) == null ? void 0 : f.alignment) ?? d.alignment,
48
+ currencyDecimalCount: ((u = e.currency) == null ? void 0 : u.decimalCount) ?? d.decimalCount,
49
+ currencyDecimalSeparator: ((n = e.currency) == null ? void 0 : n.decimalSeparator) ?? d.decimalSeparator,
50
+ currencyThousandSeparator: ((y = e.currency) == null ? void 0 : y.thousandSeparator) ?? d.thousandSeparator
62
51
  };
63
- m.seedBlockUrlConfig(r, l);
52
+ l.seedBlockUrlConfig(r, p);
64
53
  });
54
+ try {
55
+ await l.fetchRecommendationCreateData();
56
+ } catch (t) {
57
+ console.warn(
58
+ "Recommendation reference data pre-load failed; validator will skip the availability check.",
59
+ t
60
+ );
61
+ }
65
62
  }
66
- const G = () => {
67
- const s = L(), t = F(), { getCompiledEmail: a, getTemplateData: m } = E(), { compileHtml: n } = P();
63
+ const _ = () => {
64
+ const i = P(), o = w(), { getCompiledEmail: m, getTemplateData: l } = C(), { compileHtml: t } = T();
68
65
  return {
69
66
  prepareTemplateDetails: async () => {
70
- const { html: r, ampHtml: o = "", ampErrors: e = [] } = await a({
67
+ const { html: r, ampHtml: a = "", ampErrors: e = [] } = await m({
71
68
  minimize: !0,
72
69
  resetDataSavedFlag: !1
73
- }), { html: l, css: f, syncModulesIds: g = [] } = await m();
74
- t.selectedUnsubscribePages.length && await t.fetchTemplates(), x(l);
75
- const { compiledHtml: d, stats: i, appliedRules: S } = n(r), h = s.getSelectedDynamicContentList, A = b(), T = w(l), C = Object.fromEntries(
76
- Object.entries(A.recommendationCampaignUrls).filter(([D]) => T.has(Number(D)))
77
- );
70
+ }), { html: p, css: g, syncModulesIds: f = [] } = await l();
71
+ o.selectedUnsubscribePages.length && await o.fetchTemplates(), await U(p);
72
+ const { compiledHtml: u, stats: n, appliedRules: y } = t(r), h = i.getSelectedDynamicContentList, A = b();
78
73
  return console.debug("HTML Compilation Stats:", {
79
- originalSize: i.originalSize,
80
- compiledSize: i.compiledSize,
81
- reduction: `${i.reductionPercentage.toFixed(2)}%`,
82
- appliedRules: S,
83
- executionTime: `${i.executionTime.toFixed(2)}ms`
74
+ originalSize: n.originalSize,
75
+ compiledSize: n.compiledSize,
76
+ reduction: `${n.reductionPercentage.toFixed(2)}%`,
77
+ appliedRules: y,
78
+ executionTime: `${n.executionTime.toFixed(2)}ms`
84
79
  }), {
85
80
  dynamicContentList: h,
86
- compiledHtml: d,
87
- rawHtml: l,
88
- css: f,
89
- ampHtml: o,
81
+ compiledHtml: u,
82
+ rawHtml: p,
83
+ css: g,
84
+ ampHtml: a,
90
85
  ampErrors: e,
91
- modules: g.map(Number),
86
+ modules: f.map(Number),
92
87
  recommendation: {
93
- campaignUrls: C,
88
+ campaignUrls: A.recommendationCampaignUrls,
94
89
  configs: {}
95
90
  },
96
91
  unsubscribe: {
97
- status: t.unsubscribePagesStatus,
98
- config: I(d, t.selectedUnsubscribePages)
92
+ status: o.unsubscribePagesStatus,
93
+ config: E(u, o.selectedUnsubscribePages)
99
94
  }
100
95
  };
101
96
  }
102
97
  };
103
98
  };
104
99
  export {
105
- G as useTemplatePreparation
100
+ _ as useTemplatePreparation
106
101
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.4.1-beta.6ed05e2",
3
+ "version": "3.4.1-beta.8f6f02b",
4
4
  "description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
5
5
  "main": "./dist/guido.umd.cjs",
6
6
  "module": "./dist/library.js",