@useinsider/guido 3.20.1 → 3.21.0

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.
Files changed (56) hide show
  1. package/dist/components/Guido.vue.js +1 -1
  2. package/dist/components/Guido.vue2.js +65 -64
  3. package/dist/components/organisms/AutoSaveController.vue2.js +10 -9
  4. package/dist/components/organisms/header/EditorActions.vue.js +4 -4
  5. package/dist/components/organisms/header/EditorActions.vue2.js +53 -51
  6. package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +3 -3
  7. package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +23 -22
  8. package/dist/composables/useAutoSave.js +46 -44
  9. package/dist/composables/useLegacyStrategyConversion.js +16 -16
  10. package/dist/composables/useSave.js +26 -23
  11. package/dist/composables/useSaveValidation.js +113 -114
  12. package/dist/composables/useSaveValidationRollout.js +17 -6
  13. package/dist/composables/useStripo.js +4 -3
  14. package/dist/extensions/Blocks/Items/block.js +43 -42
  15. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +296 -223
  16. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +221 -203
  17. package/dist/extensions/Blocks/Recommendation/utils/blockRefresh.js +19 -0
  18. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +51 -36
  19. package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +31 -35
  20. package/dist/extensions/Blocks/Unsubscribe/block.js +70 -75
  21. package/dist/guido.css +1 -1
  22. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +271 -192
  23. package/dist/package.json.js +1 -1
  24. package/dist/services/settingsApi.js +11 -0
  25. package/dist/src/components/Guido.vue.d.ts +1 -1
  26. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  27. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  28. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  29. package/dist/src/composables/useAutoSave.d.ts +4 -1
  30. package/dist/src/composables/useSaveValidationRollout.d.ts +1 -0
  31. package/dist/src/extensions/Blocks/Checkbox/controls/blockBackground/index.d.ts +1 -0
  32. package/dist/src/extensions/Blocks/CouponBlock/controls/index.d.ts +8 -0
  33. package/dist/src/extensions/Blocks/Items/controls/index.d.ts +40 -0
  34. package/dist/src/extensions/Blocks/RadioButton/controls/blockBackground/index.d.ts +1 -0
  35. package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +1 -0
  36. package/dist/src/extensions/Blocks/Recommendation/controls/button/index.d.ts +11 -0
  37. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +7 -0
  38. package/dist/src/extensions/Blocks/Recommendation/controls/image/index.d.ts +2 -0
  39. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +18 -3
  40. package/dist/src/extensions/Blocks/Recommendation/controls/name/index.d.ts +7 -0
  41. package/dist/src/extensions/Blocks/Recommendation/controls/oldPrice/index.d.ts +7 -0
  42. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.d.ts +7 -0
  43. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/index.d.ts +7 -0
  44. package/dist/src/extensions/Blocks/Recommendation/controls/price/index.d.ts +7 -0
  45. package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +7 -0
  46. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +9 -1
  47. package/dist/src/extensions/Blocks/Recommendation/utils/blockRefresh.d.ts +17 -0
  48. package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +7 -0
  49. package/dist/src/extensions/Blocks/Unsubscribe/block.d.ts +1 -6
  50. package/dist/src/extensions/Blocks/_Boilerplate/controls/blockBackground/index.d.ts +1 -0
  51. package/dist/src/extensions/Blocks/controlFactories.d.ts +22 -0
  52. package/dist/src/services/settingsApi.d.ts +6 -0
  53. package/dist/src/stores/setup-settings.d.ts +4 -0
  54. package/dist/static/styles/components/button.css.js +5 -0
  55. package/dist/stores/setup-settings.js +10 -0
  56. package/package.json +4 -4
@@ -1,31 +1,36 @@
1
- import { useToaster as U } from "../../../../composables/useToaster.js";
2
- import { useTranslations as M } from "../../../../composables/useTranslations.js";
3
- import { getRecommendationFeedSourceMaps as w, strategyEditPath as N, strategyCreatePath as B, getOperatorOptions as z, PriceAttributes as E } from "../../../../enums/extensions/recommendationBlock.js";
4
- import { ToasterTypeOptions as O } from "../../../../enums/toaster.js";
5
- import { useRecommendationApi as A } from "../../../../services/recommendationApi.js";
1
+ import { useToaster as L } from "../../../../composables/useToaster.js";
2
+ import { useTranslations as U } from "../../../../composables/useTranslations.js";
3
+ import { getRecommendationFeedSourceMaps as F, strategyEditPath as z, strategyCreatePath as B, getOperatorOptions as M, PriceAttributes as N } from "../../../../enums/extensions/recommendationBlock.js";
4
+ import { ToasterTypeOptions as E } from "../../../../enums/toaster.js";
5
+ import { useRecommendationApi as O } from "../../../../services/recommendationApi.js";
6
6
  import { useConfigStore as R } from "../../../../stores/config.js";
7
- import { defineStore as x } from "pinia";
7
+ import { defineStore as V } from "pinia";
8
8
  import "../constants/selectors.js";
9
- import { DEFAULT_MOBILE_CARDS_IN_ROW as T, DEFAULT_CARDS_IN_ROW as V } from "../constants/layout.js";
10
- import { CURRENT_CONFIG_VERSION as C, DEFAULT_NODE_CONFIG as j, EXCLUDED_ALGORITHM_IDS as $ } from "../constants/defaultConfig.js";
11
- import { getDefaultProducts as P } from "../templates/utils.js";
12
- import { generateCompleteFilterQuery as G } from "../utils/filterUtil.js";
13
- import { isLegacyStrategyConfig as q } from "../utils/legacyStrategyMigration.js";
14
- import { getPartnerRecommendationParams as K } from "../utils/partnerCustomizations.js";
15
- import { sanitizeProductIds as H } from "../utils/productIds.js";
16
- import { isFilterValid as J } from "../validation/filterSchema.js";
17
- import { getInvalidFields as Q, isConfigValid as W } from "../validation/requiredFields.js";
18
- const u = A();
19
- let S = null, y = null, p = null, I = "", k = null, b = 0;
20
- const m = /* @__PURE__ */ new Map(), D = /* @__PURE__ */ new Map();
21
- function X(t) {
22
- const e = D.get(t);
23
- return e && e.token === m.get(t) ? e.outcome : !1;
9
+ import { DEFAULT_MOBILE_CARDS_IN_ROW as A, DEFAULT_CARDS_IN_ROW as x } from "../constants/layout.js";
10
+ import { CURRENT_CONFIG_VERSION as C, DEFAULT_NODE_CONFIG as T, EXCLUDED_ALGORITHM_IDS as j } from "../constants/defaultConfig.js";
11
+ import { getDefaultProducts as w } from "../templates/utils.js";
12
+ import { generateCompleteFilterQuery as P } from "../utils/filterUtil.js";
13
+ import { isLegacyStrategyConfig as $ } from "../utils/legacyStrategyMigration.js";
14
+ import { getPartnerRecommendationParams as q } from "../utils/partnerCustomizations.js";
15
+ import { sanitizeProductIds as K } from "../utils/productIds.js";
16
+ import { isFilterValid as H } from "../validation/filterSchema.js";
17
+ import { getInvalidFields as J, isConfigValid as Q } from "../validation/requiredFields.js";
18
+ const m = O();
19
+ let p = null, y = null;
20
+ const I = /* @__PURE__ */ new Map();
21
+ let k = null, b = 0;
22
+ const u = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map();
23
+ function W(t) {
24
+ const e = _.get(t);
25
+ return e && e.token === u.get(t) ? e.outcome : !1;
24
26
  }
25
27
  let l = null;
26
- function L() {
28
+ const X = () => {
29
+ l == null || l();
30
+ };
31
+ function D() {
27
32
  return {
28
- cardsInRow: V,
33
+ cardsInRow: x,
29
34
  currencySettings: {
30
35
  name: "USD",
31
36
  value: "USD",
@@ -39,7 +44,7 @@ function L() {
39
44
  productIds: [],
40
45
  id: 1,
41
46
  language: "en_US",
42
- mobileCardsInRow: T,
47
+ mobileCardsInRow: A,
43
48
  mobileLayoutEnabled: !1,
44
49
  orientation: "grid",
45
50
  recommendedProducts: [],
@@ -60,9 +65,9 @@ function L() {
60
65
  priceHideIfSameAsDiscounted: !1
61
66
  };
62
67
  }
63
- function _() {
68
+ function G() {
64
69
  return {
65
- recommendationConfigs: L(),
70
+ recommendationConfigs: D(),
66
71
  recommendationProducts: [],
67
72
  filterStatus: !1,
68
73
  filterSelectionDrawerStatus: !1,
@@ -73,7 +78,9 @@ function _() {
73
78
  isInitialized: !1,
74
79
  filterSnapshot: null,
75
80
  syncedConfigFingerprint: null,
76
- legacyConversionLoading: !1
81
+ legacyConversionLoading: !1,
82
+ configVersion: 0,
83
+ adoptedSizeVersion: 0
77
84
  };
78
85
  }
79
86
  const Y = () => ({
@@ -91,7 +98,7 @@ const Y = () => ({
91
98
  currentRecommendationId: null,
92
99
  strategyPanelOpen: !1,
93
100
  configVersion: 0
94
- }), St = x("guidoRecommendationExtension", {
101
+ }), St = V("guidoRecommendationExtension", {
95
102
  state: () => Y(),
96
103
  getters: {
97
104
  // ====================================================================
@@ -102,7 +109,7 @@ const Y = () => ({
102
109
  * This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
103
110
  */
104
111
  recommendationConfigs(t) {
105
- return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : L();
112
+ return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : D();
106
113
  },
107
114
  /**
108
115
  * Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
@@ -123,7 +130,7 @@ const Y = () => ({
123
130
  return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].removeStrategyModalStatus : !1;
124
131
  },
125
132
  isLegacyStrategyBlock() {
126
- return R().isFeatureEnabled("reusableRecommendationStrategy") && q(this.recommendationConfigs);
133
+ return R().isFeatureEnabled("reusableRecommendationStrategy") && $(this.recommendationConfigs);
127
134
  },
128
135
  legacyConversionLoading(t) {
129
136
  return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].legacyConversionLoading ?? !1 : !1;
@@ -133,7 +140,7 @@ const Y = () => ({
133
140
  },
134
141
  assignedStrategy(t) {
135
142
  const { strategyId: e } = this.recommendationConfigs;
136
- return e ? t.strategies.find((r) => String(r.strategy_id) === e) ?? null : null;
143
+ return e ? t.strategies.find((n) => String(n.strategy_id) === e) ?? null : null;
137
144
  },
138
145
  /**
139
146
  * Proxy getter: delegates to blockStates[currentRecommendationId].filterStatus
@@ -163,19 +170,19 @@ const Y = () => ({
163
170
  },
164
171
  getUniqueFilterGroups() {
165
172
  const { filters: t } = this.recommendationConfigs;
166
- return [...new Set(t.map((e) => e.filterGroup))].sort((e, r) => e - r);
173
+ return [...new Set(t.map((e) => e.filterGroup))].sort((e, n) => e - n);
167
174
  },
168
175
  getActivePredictiveAlgorithms: (t) => {
169
- const e = w(), r = [];
170
- return t.activePredictiveAlgorithms.filter((n) => !$.includes(n)).forEach((n) => {
171
- r.push(...e.filter((s) => s.id === n));
172
- }), r.map((n) => ({
173
- text: n.name,
174
- value: n.key
176
+ const e = F(), n = [];
177
+ return t.activePredictiveAlgorithms.filter((r) => !j.includes(r)).forEach((r) => {
178
+ n.push(...e.filter((o) => o.id === r));
179
+ }), n.map((r) => ({
180
+ text: r.name,
181
+ value: r.key
175
182
  }));
176
183
  },
177
- getLanguages: (t) => Object.entries(t.languages).map(([e, r]) => ({
178
- text: r,
184
+ getLanguages: (t) => Object.entries(t.languages).map(([e, n]) => ({
185
+ text: n,
179
186
  value: e
180
187
  })),
181
188
  getCurrencySymbolList: (t) => t.currencyList.map((e) => ({
@@ -185,7 +192,7 @@ const Y = () => ({
185
192
  getFilterList() {
186
193
  return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
187
194
  let e;
188
- return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : E.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
195
+ return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : N.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
189
196
  text: t.displayName,
190
197
  value: e,
191
198
  type: t.attributeType
@@ -207,7 +214,7 @@ const Y = () => ({
207
214
  setCurrentBlock(t) {
208
215
  this.blockStates[t] || (this.blockStates = {
209
216
  ...this.blockStates,
210
- [t]: _()
217
+ [t]: G()
211
218
  }), this.currentRecommendationId = t;
212
219
  },
213
220
  /**
@@ -217,13 +224,13 @@ const Y = () => ({
217
224
  removeBlockState(t) {
218
225
  const e = t.toString();
219
226
  if (this.recommendationCampaignUrls[e]) {
220
- const n = { ...this.recommendationCampaignUrls };
221
- delete n[e], this.recommendationCampaignUrls = n;
227
+ const r = { ...this.recommendationCampaignUrls };
228
+ delete r[e], this.recommendationCampaignUrls = r;
222
229
  }
223
- const r = { ...this.blockStates };
224
- if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
225
- const n = Object.keys(this.blockStates).map(Number);
226
- this.currentRecommendationId = n.length > 0 ? n[0] : null;
230
+ const n = { ...this.blockStates };
231
+ if (delete n[t], this.blockStates = n, this.currentRecommendationId === t) {
232
+ const r = Object.keys(this.blockStates).map(Number);
233
+ this.currentRecommendationId = r.length > 0 ? r[0] : null;
227
234
  }
228
235
  },
229
236
  /**
@@ -235,18 +242,18 @@ const Y = () => ({
235
242
  * (SD-149916).
236
243
  */
237
244
  cloneBlockState(t, e) {
238
- const r = this.blockStates[t];
239
- if (r) {
240
- const o = structuredClone(r);
241
- o.recommendationConfigs.id = e, o.recommendationConfigs.strategyId && R().isFeatureEnabled("reusableRecommendationStrategy") && (o.isInitialized = !1, o.syncedConfigFingerprint = null), this.blockStates = {
245
+ const n = this.blockStates[t];
246
+ if (n) {
247
+ const s = structuredClone(n);
248
+ s.recommendationConfigs.id = e, s.recommendationConfigs.strategyId && R().isFeatureEnabled("reusableRecommendationStrategy") && (s.isInitialized = !1, s.syncedConfigFingerprint = null), this.blockStates = {
242
249
  ...this.blockStates,
243
- [e]: o
250
+ [e]: s
244
251
  };
245
252
  }
246
- const n = t.toString(), s = e.toString(), i = this.recommendationCampaignUrls[n];
253
+ const r = t.toString(), o = e.toString(), i = this.recommendationCampaignUrls[r];
247
254
  i && (this.recommendationCampaignUrls = {
248
255
  ...this.recommendationCampaignUrls,
249
- [s]: i
256
+ [o]: i
250
257
  });
251
258
  },
252
259
  /**
@@ -271,15 +278,15 @@ const Y = () => ({
271
278
  * `isInitialized`) alone.
272
279
  */
273
280
  seedBlockUrlConfig(t, e) {
274
- const r = (o, a) => o === "." || o === "," || o === " " ? o : a, n = {
281
+ const n = (s, a) => s === "." || s === "," || s === " " ? s : a, r = {
275
282
  name: e.currencyCode,
276
283
  value: e.currencyCode,
277
284
  symbol: e.currencySymbol,
278
285
  alignment: e.currencyAlignment === "before" ? "0" : "1",
279
286
  decimalCount: String(e.currencyDecimalCount),
280
- decimalSeparator: r(e.currencyDecimalSeparator, ","),
281
- thousandSeparator: r(e.currencyThousandSeparator, ".")
282
- }, s = !this.blockStates[t], i = s ? _() : this.blockStates[t];
287
+ decimalSeparator: n(e.currencyDecimalSeparator, ","),
288
+ thousandSeparator: n(e.currencyThousandSeparator, ".")
289
+ }, o = !this.blockStates[t], i = o ? G() : this.blockStates[t];
283
290
  i.recommendationConfigs = {
284
291
  ...i.recommendationConfigs,
285
292
  strategy: e.strategy,
@@ -289,8 +296,8 @@ const Y = () => ({
289
296
  productIds: e.productIds,
290
297
  filters: e.filters,
291
298
  shuffleProducts: e.shuffleProducts,
292
- currencySettings: n
293
- }, s && (this.blockStates = {
299
+ currencySettings: r
300
+ }, o && (this.blockStates = {
294
301
  ...this.blockStates,
295
302
  [t]: i
296
303
  });
@@ -302,27 +309,27 @@ const Y = () => ({
302
309
  patchCurrentBlockConfig(t, e = {}) {
303
310
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
304
311
  return;
305
- const r = this.blockStates[this.currentRecommendationId];
306
- r.recommendationConfigs = {
307
- ...r.recommendationConfigs,
312
+ const n = this.blockStates[this.currentRecommendationId];
313
+ n.recommendationConfigs = {
314
+ ...n.recommendationConfigs,
308
315
  ...t,
309
316
  currencySettings: {
310
- ...r.recommendationConfigs.currencySettings,
317
+ ...n.recommendationConfigs.currencySettings,
311
318
  ...t.currencySettings || {}
312
319
  }
313
320
  };
314
- const { triggerRefetch: n = !0 } = e;
315
- n && this.configVersion++;
321
+ const { triggerRefetch: r = !0 } = e;
322
+ r && (n.configVersion++, this.configVersion++);
316
323
  },
317
324
  /**
318
325
  * Creates a filter with the first available attribute and operator pre-selected.
319
326
  */
320
327
  createDefaultFilter(t, e) {
321
- const [r] = this.getFilterList, [n] = z(r == null ? void 0 : r.type);
328
+ const [n] = this.getFilterList, [r] = M(n == null ? void 0 : n.type);
322
329
  return {
323
330
  type: "standardFilter",
324
- attribute: (r == null ? void 0 : r.value) ?? "",
325
- operator: (n == null ? void 0 : n.value) ?? "",
331
+ attribute: (n == null ? void 0 : n.value) ?? "",
332
+ operator: (r == null ? void 0 : r.value) ?? "",
326
333
  innerGroupOperator: "*",
327
334
  outerGroupOperator: "*",
328
335
  filterNumber: e,
@@ -394,10 +401,10 @@ const Y = () => ({
394
401
  const t = b, e = (async () => {
395
402
  this.strategiesLoading = !0;
396
403
  try {
397
- const r = await u.fetchRecommendationStrategies();
404
+ const n = await m.fetchRecommendationStrategies();
398
405
  if (t !== b)
399
406
  return;
400
- this.strategies = r, this.strategiesFetched = !0;
407
+ this.strategies = n, this.strategiesFetched = !0;
401
408
  } finally {
402
409
  this.strategiesLoading = !1, t === b && (this.strategiesSettled = !0);
403
410
  }
@@ -438,20 +445,20 @@ const Y = () => ({
438
445
  _armStrategyPageReturn(t) {
439
446
  const e = window.open(t, "_blank");
440
447
  if (!e)
441
- return U().showToaster({
442
- type: O.Error,
443
- message: M()("discovery-strategy.error-description")
448
+ return L().showToaster({
449
+ type: E.Error,
450
+ message: U()("discovery-strategy.error-description")
444
451
  }), !1;
445
452
  e.opener = null, l == null || l();
446
- let r = !1;
447
- const n = () => {
448
- document.hidden || r || (e != null && e.closed && (l == null || l()), r = !0, this.invalidateStrategies(), this.fetchStrategies().then(() => this._refreshAssignedStrategyProducts()).catch(() => {
453
+ let n = !1;
454
+ const r = () => {
455
+ document.hidden || n || (e != null && e.closed && (l == null || l()), n = !0, this.invalidateStrategies(), this.fetchStrategies().then(() => this._refreshAssignedStrategyProducts()).catch(() => {
449
456
  }).finally(() => {
450
- r = !1;
457
+ n = !1;
451
458
  }));
452
459
  };
453
- return document.addEventListener("visibilitychange", n), l = () => {
454
- document.removeEventListener("visibilitychange", n), l = null;
460
+ return document.addEventListener("visibilitychange", r), l = () => {
461
+ document.removeEventListener("visibilitychange", r), l = null;
455
462
  }, !0;
456
463
  },
457
464
  /**
@@ -468,7 +475,7 @@ const Y = () => ({
468
475
  },
469
476
  /** Lets the editor tear the return listeners down when it unmounts. */
470
477
  disposeStrategyPageReturn() {
471
- l == null || l();
478
+ X();
472
479
  },
473
480
  /**
474
481
  * Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
@@ -482,16 +489,16 @@ const Y = () => ({
482
489
  * edited configuration.
483
490
  */
484
491
  openStrategyEdit(t) {
485
- return this._armStrategyPageReturn(N(t));
492
+ return this._armStrategyPageReturn(z(t));
486
493
  },
487
494
  async resolveStrategyUrlTemplate(t, e) {
488
- const r = typeof t.updated_at == "string" ? t.updated_at : "", n = r ? `${t.strategy_id}:${r}:${e}` : "", s = n ? this.strategyUrlTemplates[n] : void 0;
489
- if (s)
490
- return s;
491
- const { full_path: i = "" } = await u.generateStrategyEndpoint(t, e) ?? {};
492
- return n && i && (this.strategyUrlTemplates = {
495
+ const n = typeof t.updated_at == "string" ? t.updated_at : "", r = n ? `${t.strategy_id}:${n}:${e}` : "", o = r ? this.strategyUrlTemplates[r] : void 0;
496
+ if (o)
497
+ return o;
498
+ const { full_path: i = "" } = await m.generateStrategyEndpoint(t, e) ?? {};
499
+ return r && i && (this.strategyUrlTemplates = {
493
500
  ...this.strategyUrlTemplates,
494
- [n]: i
501
+ [r]: i
495
502
  }), i;
496
503
  },
497
504
  assignStrategy(t) {
@@ -501,27 +508,27 @@ const Y = () => ({
501
508
  });
502
509
  },
503
510
  async convertLegacyStrategy(t, e = { scope: "campaign" }) {
504
- const r = this.currentRecommendationId;
505
- if (r === null || !this.blockStates[r])
511
+ const n = this.currentRecommendationId;
512
+ if (n === null || !this.blockStates[n])
506
513
  throw new Error("[Guido] convertLegacyStrategy called without an active block");
507
- this.blockStates[r].legacyConversionLoading = !0;
514
+ this.blockStates[n].legacyConversionLoading = !0;
508
515
  try {
509
- const n = await u.migrateLegacyStrategy(t, e);
516
+ const r = await m.migrateLegacyStrategy(t, e);
510
517
  this.invalidateStrategies();
511
518
  try {
512
519
  await this.fetchStrategies();
513
- } catch (o) {
514
- console.error("[Guido] strategy listing refresh after conversion failed", o);
520
+ } catch (s) {
521
+ console.error("[Guido] strategy listing refresh after conversion failed", s);
515
522
  }
516
- const s = this.strategies.find((o) => String(o.strategy_id) === n), i = this.blockStates[r];
523
+ const o = this.strategies.find((s) => String(s.strategy_id) === r), i = this.blockStates[n];
517
524
  return i && (i.recommendationConfigs = {
518
525
  ...i.recommendationConfigs,
519
- strategyId: n,
526
+ strategyId: r,
520
527
  nodeConfigVersion: C,
521
- ...(s == null ? void 0 : s.size) !== void 0 ? { size: String(s.size) } : {}
522
- }), this.currentRecommendationId === r && this.configVersion++, n;
528
+ ...(o == null ? void 0 : o.size) !== void 0 ? { size: String(o.size) } : {}
529
+ }, i.configVersion++), this.currentRecommendationId === n && this.configVersion++, r;
523
530
  } finally {
524
- this.blockStates[r] && (this.blockStates[r].legacyConversionLoading = !1);
531
+ this.blockStates[n] && (this.blockStates[n].legacyConversionLoading = !1);
525
532
  }
526
533
  },
527
534
  /**
@@ -530,14 +537,14 @@ const Y = () => ({
530
537
  * the document never received.
531
538
  */
532
539
  revertLegacyConversion(t, e) {
533
- const r = this.blockStates[t];
534
- r && (r.recommendationConfigs = { ...r.recommendationConfigs, ...e }, this.currentRecommendationId === t && this.configVersion++);
540
+ const n = this.blockStates[t];
541
+ n && (n.recommendationConfigs = { ...n.recommendationConfigs, ...e }, n.configVersion++, this.currentRecommendationId === t && this.configVersion++);
535
542
  },
536
543
  removeStrategy() {
537
544
  this.patchCurrentBlockConfig({
538
545
  strategyId: "",
539
546
  strategy: "",
540
- size: j.size,
547
+ size: T.size,
541
548
  nodeConfigVersion: C
542
549
  });
543
550
  },
@@ -546,26 +553,26 @@ const Y = () => ({
546
553
  // ====================================================================
547
554
  async fetchRecommendationCreateData() {
548
555
  if (!this.activePredictiveAlgorithms.length) {
549
- if (S) {
550
- await S;
556
+ if (p) {
557
+ await p;
551
558
  return;
552
559
  }
553
- S = (async () => {
560
+ p = (async () => {
554
561
  const {
555
562
  activePredictiveAlgorithms: t,
556
563
  languages: e,
557
- currencies: r
558
- } = await u.fetchRecommendationCreateData();
564
+ currencies: n
565
+ } = await m.fetchRecommendationCreateData();
559
566
  if (this.activePredictiveAlgorithms = t, this.languages = e, this.currentRecommendationId !== null && this.blockStates[this.currentRecommendationId]) {
560
- const n = this.blockStates[this.currentRecommendationId];
561
- n.filterStatus = !!n.recommendationConfigs.filters.length;
567
+ const r = this.blockStates[this.currentRecommendationId];
568
+ r.filterStatus = !!r.recommendationConfigs.filters.length;
562
569
  }
563
- this.currencyList = r;
570
+ this.currencyList = n;
564
571
  })();
565
572
  try {
566
- await S;
573
+ await p;
567
574
  } finally {
568
- S = null;
575
+ p = null;
569
576
  }
570
577
  }
571
578
  },
@@ -576,7 +583,7 @@ const Y = () => ({
576
583
  return;
577
584
  }
578
585
  y = (async () => {
579
- const t = await u.fetchRecommendationFilters();
586
+ const t = await m.fetchRecommendationFilters();
580
587
  this.filterList = t;
581
588
  })();
582
589
  try {
@@ -597,59 +604,59 @@ const Y = () => ({
597
604
  deleteFilterGroup(t) {
598
605
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
599
606
  return;
600
- const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), n = [...new Set(r.map((i) => i.filterGroup))].sort((i, o) => i - o), s = new Map(n.map((i, o) => [i, o + 1]));
601
- e.recommendationConfigs.filters = r.map((i) => ({
607
+ const e = this.blockStates[this.currentRecommendationId], n = e.recommendationConfigs.filters.filter((i) => i.filterGroup !== t), r = [...new Set(n.map((i) => i.filterGroup))].sort((i, s) => i - s), o = new Map(r.map((i, s) => [i, s + 1]));
608
+ e.recommendationConfigs.filters = n.map((i) => ({
602
609
  ...i,
603
- filterGroup: s.get(i.filterGroup) ?? i.filterGroup
610
+ filterGroup: o.get(i.filterGroup) ?? i.filterGroup
604
611
  }));
605
612
  },
606
613
  updateFilter(t) {
607
614
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
608
615
  return;
609
- const e = this.blockStates[this.currentRecommendationId], r = e.recommendationConfigs.filters.findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
610
- if (r !== -1) {
611
- const n = [...e.recommendationConfigs.filters];
612
- n[r] = {
616
+ const e = this.blockStates[this.currentRecommendationId], n = e.recommendationConfigs.filters.findIndex((r) => r.filterNumber === t.filterNumber && r.filterGroup === t.filterGroup);
617
+ if (n !== -1) {
618
+ const r = [...e.recommendationConfigs.filters];
619
+ r[n] = {
613
620
  ...t,
614
- isValid: J(t)
615
- }, e.recommendationConfigs.filters = n;
621
+ isValid: H(t)
622
+ }, e.recommendationConfigs.filters = r;
616
623
  }
617
624
  },
618
625
  deleteFilter(t) {
619
626
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
620
627
  return;
621
- const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters].findIndex((n) => n.filterNumber === t.filterNumber && n.filterGroup === t.filterGroup);
622
- if (r !== -1) {
623
- let n = [...e.recommendationConfigs.filters];
624
- if (n.splice(r, 1), n.some((i) => i.filterGroup === t.filterGroup)) {
628
+ const e = this.blockStates[this.currentRecommendationId], n = [...e.recommendationConfigs.filters].findIndex((r) => r.filterNumber === t.filterNumber && r.filterGroup === t.filterGroup);
629
+ if (n !== -1) {
630
+ let r = [...e.recommendationConfigs.filters];
631
+ if (r.splice(n, 1), r.some((i) => i.filterGroup === t.filterGroup)) {
625
632
  let i = 1;
626
- n = n.map((o) => o.filterGroup === t.filterGroup ? { ...o, filterNumber: i++ } : o);
633
+ r = r.map((s) => s.filterGroup === t.filterGroup ? { ...s, filterNumber: i++ } : s);
627
634
  } else {
628
- const i = [...new Set(n.map((a) => a.filterGroup))].sort((a, f) => a - f), o = new Map(i.map((a, f) => [a, f + 1]));
629
- n = n.map((a) => ({
635
+ const i = [...new Set(r.map((a) => a.filterGroup))].sort((a, d) => a - d), s = new Map(i.map((a, d) => [a, d + 1]));
636
+ r = r.map((a) => ({
630
637
  ...a,
631
- filterGroup: o.get(a.filterGroup) ?? a.filterGroup
638
+ filterGroup: s.get(a.filterGroup) ?? a.filterGroup
632
639
  }));
633
640
  }
634
- e.recommendationConfigs.filters = n;
641
+ e.recommendationConfigs.filters = r;
635
642
  }
636
643
  },
637
644
  addFilter(t) {
638
645
  if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
639
646
  return;
640
- const e = this.blockStates[this.currentRecommendationId], r = [...e.recommendationConfigs.filters], s = r.filter(
641
- (o) => o.filterGroup === t.filterGroup
642
- ).length + 1, i = r.findLastIndex((o) => o.filterGroup === t.filterGroup);
643
- i !== -1 ? r.splice(i + 1, 0, {
647
+ const e = this.blockStates[this.currentRecommendationId], n = [...e.recommendationConfigs.filters], o = n.filter(
648
+ (s) => s.filterGroup === t.filterGroup
649
+ ).length + 1, i = n.findLastIndex((s) => s.filterGroup === t.filterGroup);
650
+ i !== -1 ? n.splice(i + 1, 0, {
644
651
  ...t,
645
- filterNumber: s
646
- }) : r.push({
652
+ filterNumber: o
653
+ }) : n.push({
647
654
  ...t,
648
- filterNumber: s
649
- }), e.recommendationConfigs.filters = r;
655
+ filterNumber: o
656
+ }), e.recommendationConfigs.filters = n;
650
657
  },
651
658
  generateFilterQuery() {
652
- return G(this.recommendationConfigs.filters);
659
+ return P(this.recommendationConfigs.filters);
653
660
  },
654
661
  /**
655
662
  * Validation-only check invoked at save-CTA time. Defined as an action
@@ -657,70 +664,77 @@ const Y = () => ({
657
664
  * every block's recommendationConfigs across user edits.
658
665
  */
659
666
  hasInvalidBlock() {
660
- return Object.values(this.blockStates).some((t) => !W(t.recommendationConfigs, this));
667
+ return Object.values(this.blockStates).some((t) => !Q(t.recommendationConfigs, this));
661
668
  },
662
669
  /**
663
670
  * Which required fields are missing across the design's blocks, so the save
664
671
  * toaster can name the cause instead of always showing the generic message.
665
672
  */
666
673
  invalidBlockFields() {
667
- return Object.values(this.blockStates).flatMap((t) => Q(t.recommendationConfigs, this));
674
+ return Object.values(this.blockStates).flatMap((t) => J(t.recommendationConfigs, this));
668
675
  },
669
676
  // ====================================================================
670
677
  // Per-Block Product Fetching
671
678
  // ====================================================================
672
679
  async fetchRecommendationProducts() {
673
- if (this.currentRecommendationId === null || !this.blockStates[this.currentRecommendationId])
680
+ this.currentRecommendationId !== null && await this.fetchRecommendationProductsForBlock(this.currentRecommendationId);
681
+ },
682
+ /**
683
+ * Fetches one block's products whether or not it is selected: the panel teardown and the
684
+ * strategy drawer refresh the block they were handed after the user may have moved on.
685
+ */
686
+ async fetchRecommendationProductsForBlock(t) {
687
+ var i;
688
+ const e = this.blockStates[t];
689
+ if (!e)
674
690
  return;
675
- const t = [
676
- this.currentRecommendationId,
677
- this.configVersion,
678
- b
679
- ].join(":");
680
- if (p && I === t) {
681
- await p;
691
+ const n = [e.configVersion, e.adoptedSizeVersion, b].join(":"), r = I.get(t);
692
+ if ((r == null ? void 0 : r.key) === n) {
693
+ await r.promise;
682
694
  return;
683
695
  }
684
- I = t, p = this._doFetchProducts();
696
+ const o = this._doFetchProducts(t);
697
+ I.set(t, { key: n, promise: o });
685
698
  try {
686
- await p;
699
+ await o;
687
700
  } finally {
688
- I === t && (p = null, I = "");
701
+ ((i = I.get(t)) == null ? void 0 : i.promise) === o && I.delete(t);
689
702
  }
690
703
  },
691
- async _doFetchProducts() {
692
- var h;
693
- const t = this.currentRecommendationId, e = this.blockStates[t], { recommendationConfigs: r } = e, n = R();
694
- if (r.strategyId && n.isFeatureEnabled("reusableRecommendationStrategy")) {
695
- await this._doFetchStrategyProducts(t);
704
+ // Captures the block ID up front so the write lands on it even if the user switches.
705
+ async _doFetchProducts(t) {
706
+ var S;
707
+ const e = t ?? this.currentRecommendationId, n = this.blockStates[e], { recommendationConfigs: r } = n, o = R();
708
+ if (r.strategyId && o.isFeatureEnabled("reusableRecommendationStrategy")) {
709
+ await this._doFetchStrategyProducts(e);
696
710
  return;
697
711
  }
698
- const s = (m.get(t) ?? 0) + 1;
699
- m.set(t, s);
700
- const i = parseInt(r.size) || 6;
712
+ const i = (u.get(e) ?? 0) + 1;
713
+ u.set(e, i);
714
+ const s = parseInt(r.size) || 6;
701
715
  if (!r.strategy) {
702
- this._setBlockProducts(t, [], i);
716
+ this._setBlockProducts(e, [], s);
703
717
  return;
704
718
  }
705
- const o = r.filters.filter((g) => g.isValid), a = G(o), f = ((h = w().find((g) => g.key === r.strategy)) == null ? void 0 : h.path) || "", c = {
719
+ const a = r.filters.filter((h) => h.isValid), d = P(a), f = ((S = F().find((h) => h.key === r.strategy)) == null ? void 0 : S.path) || "", c = {
706
720
  locale: r.language,
707
721
  currency: r.currencySettings.value,
708
- partnerName: n.partnerName,
722
+ partnerName: o.partnerName,
709
723
  size: r.size,
710
724
  details: !0,
711
- campaignId: n.variationId
725
+ campaignId: o.variationId
712
726
  };
713
- r.strategy === "manualMerchandising" ? c.productId = H(r.productIds) : r.strategy === "similarViewed" && (c.productId = "{itemId}"), r.strategy === "userBased" && (c.userId = "{user_id}"), a && (c.filter = a), r.shuffleProducts && (c.shuffle = !0), Object.assign(
727
+ r.strategy === "manualMerchandising" ? c.productId = K(r.productIds) : r.strategy === "similarViewed" && (c.productId = "{itemId}"), r.strategy === "userBased" && (c.userId = "{user_id}"), d && (c.filter = d), r.shuffleProducts && (c.shuffle = !0), Object.assign(
714
728
  c,
715
- K(n.partnerName, r.strategy)
729
+ q(o.partnerName, r.strategy)
716
730
  );
717
- let d;
731
+ let g;
718
732
  try {
719
- d = await u.fetchRecommendationProducts(f, c);
733
+ g = await m.fetchRecommendationProducts(f, c);
720
734
  } catch {
721
- d = [];
735
+ g = [];
722
736
  }
723
- m.get(t) === s && this._setBlockProducts(t, d, i);
737
+ u.get(e) === i && this._setBlockProducts(e, g, s);
724
738
  },
725
739
  /**
726
740
  * Block-scoped counterpart of `fetchRecommendationProducts`, which only serves the selected block:
@@ -728,8 +742,8 @@ const Y = () => ({
728
742
  * @returns whether real products arrived
729
743
  */
730
744
  async fetchStrategyProductsForBlock(t, e = {}) {
731
- var r;
732
- return (r = this.blockStates[t]) != null && r.recommendationConfigs.strategyId ? this._doFetchStrategyProducts(t, e) : !1;
745
+ var n;
746
+ return (n = this.blockStates[t]) != null && n.recommendationConfigs.strategyId ? this._doFetchStrategyProducts(t, e) : !1;
733
747
  },
734
748
  /**
735
749
  * Reloads a block's products and adopts its strategy's current size, which may have
@@ -737,8 +751,8 @@ const Y = () => ({
737
751
  * @returns whether a fresh listing holds the strategy and its products arrived
738
752
  */
739
753
  async refreshStrategyBlock(t) {
740
- var s;
741
- const e = (s = this.blockStates[t]) == null ? void 0 : s.recommendationConfigs.strategyId;
754
+ var o;
755
+ const e = (o = this.blockStates[t]) == null ? void 0 : o.recommendationConfigs.strategyId;
742
756
  if (!e)
743
757
  return !1;
744
758
  try {
@@ -746,50 +760,54 @@ const Y = () => ({
746
760
  } catch {
747
761
  return !1;
748
762
  }
749
- const r = this.strategiesFetched ? this.strategies.find((i) => String(i.strategy_id) === e) : void 0;
750
- if (!r || !await this.fetchStrategyProductsForBlock(t, { keepOnFailure: !0 }))
763
+ const n = this.strategiesFetched ? this.strategies.find((i) => String(i.strategy_id) === e) : void 0;
764
+ if (!n || !await this.fetchStrategyProductsForBlock(t, { keepOnFailure: !0 }))
751
765
  return !1;
752
- const n = this.blockStates[t];
753
- return (n == null ? void 0 : n.recommendationConfigs.strategyId) !== e ? !1 : (r.size !== void 0 && (n.recommendationConfigs = {
754
- ...n.recommendationConfigs,
755
- size: String(r.size)
756
- }), !0);
766
+ const r = this.blockStates[t];
767
+ if ((r == null ? void 0 : r.recommendationConfigs.strategyId) !== e)
768
+ return !1;
769
+ if (n.size !== void 0) {
770
+ const i = String(n.size);
771
+ r.recommendationConfigs.size !== i && r.adoptedSizeVersion++, r.recommendationConfigs = { ...r.recommendationConfigs, size: i };
772
+ }
773
+ return !0;
757
774
  },
758
775
  _doFetchStrategyProducts(t, e = {}) {
759
- const r = (m.get(t) ?? 0) + 1;
760
- m.set(t, r);
761
- const n = this._loadStrategyProducts(t, r, e);
762
- return D.set(t, { token: r, outcome: n }), n;
763
- },
764
- async _loadStrategyProducts(t, e, { keepOnFailure: r = !1 }) {
765
- const { recommendationConfigs: n } = this.blockStates[t];
766
- let s = [], i = parseInt(n.size) || 6;
776
+ const n = (u.get(t) ?? 0) + 1;
777
+ u.set(t, n);
778
+ const r = this._loadStrategyProducts(t, n, e);
779
+ return _.set(t, { token: n, outcome: r }), r;
780
+ },
781
+ async _loadStrategyProducts(t, e, { keepOnFailure: n = !1 }) {
782
+ const { recommendationConfigs: r } = this.blockStates[t];
783
+ let o = [], i = parseInt(r.size) || 6;
767
784
  try {
768
785
  await this.fetchStrategies();
769
- const o = this.strategies.find(
770
- (a) => String(a.strategy_id) === n.strategyId
786
+ const s = this.strategies.find(
787
+ (a) => String(a.strategy_id) === r.strategyId
771
788
  );
772
- if (o) {
773
- i = parseInt(String(o.size ?? "")) || i;
774
- const a = n.currencySettings.value, c = (await this.resolveStrategyUrlTemplate(o, a)).replaceAll("{locale}", n.language).replaceAll("{currency}", a), d = c.indexOf("?"), h = d === -1 ? c : c.slice(0, d), g = (d === -1 ? "" : c.slice(d + 1)).split("&").filter((F) => F && !F.startsWith("user_id=")), v = g.length ? `${h}?${g.join("&")}` : h;
775
- v && (s = await u.fetchRecommendationProductsByUrl(v));
789
+ if (s) {
790
+ i = parseInt(String(s.size ?? "")) || i;
791
+ const a = r.currencySettings.value, f = (await this.resolveStrategyUrlTemplate(s, a)).replaceAll("{locale}", r.language).replaceAll("{currency}", a), c = f.indexOf("?"), g = c === -1 ? f : f.slice(0, c), S = (c === -1 ? "" : f.slice(c + 1)).split("&").filter((v) => v && !v.startsWith("user_id=")), h = S.length ? `${g}?${S.join("&")}` : g;
792
+ h && (o = await m.fetchRecommendationProductsByUrl(h));
776
793
  }
777
794
  } catch {
778
- s = [];
795
+ o = [];
779
796
  }
780
- return m.get(t) !== e ? X(t) : !s.length && r ? !1 : (this._setBlockProducts(t, s, i), s.length > 0);
797
+ return u.get(t) !== e ? W(t) : !o.length && n ? !1 : (this._setBlockProducts(t, o, i), o.length > 0);
781
798
  },
782
- _setBlockProducts(t, e, r) {
799
+ _setBlockProducts(t, e, n) {
783
800
  if (!this.blockStates[t])
784
801
  return;
785
- const n = e.length > 0 ? e : P(r);
802
+ const r = e.length > 0 ? e : w(n);
786
803
  this.blockStates[t].recommendationProducts = [
787
- ...n.slice(0, r),
788
- ...P(Math.max(0, r - n.length))
804
+ ...r.slice(0, n),
805
+ ...w(Math.max(0, n - r.length))
789
806
  ];
790
807
  }
791
808
  }
792
809
  });
793
810
  export {
811
+ X as disposeStrategyPageReturnListeners,
794
812
  St as useRecommendationExtensionStore
795
813
  };