@useinsider/guido 3.18.2 → 3.19.0-beta.019f238

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 (92) hide show
  1. package/README.md +41 -3
  2. package/dist/@types/config/schemas.js +59 -51
  3. package/dist/components/Guido.vue.js +4 -4
  4. package/dist/components/Guido.vue2.js +70 -68
  5. package/dist/components/organisms/base/Toaster.vue2.js +13 -12
  6. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +13 -11
  7. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +78 -57
  8. package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.js +18 -0
  9. package/dist/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue2.js +25 -0
  10. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +28 -42
  11. package/dist/components/organisms/header/EditorActions.vue.js +4 -4
  12. package/dist/components/organisms/header/EditorActions.vue2.js +23 -25
  13. package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +28 -24
  14. package/dist/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue.js +21 -0
  15. package/dist/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue2.js +46 -0
  16. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +21 -0
  17. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +47 -0
  18. package/dist/components/organisms/save-as-template/SaveAsTemplateDrawer.vue2.js +34 -34
  19. package/dist/composables/useActionsApi.js +52 -47
  20. package/dist/composables/useCodeEditorApi.js +23 -9
  21. package/dist/composables/useCustomInterfaceAppearance.js +65 -51
  22. package/dist/composables/useGuidoStateBridge.js +29 -24
  23. package/dist/composables/useHtmlValidator.js +87 -82
  24. package/dist/composables/useHttp.js +24 -22
  25. package/dist/composables/useLegacyStrategyConversion.js +61 -0
  26. package/dist/composables/useRecommendation.js +40 -35
  27. package/dist/composables/useStripo.js +29 -29
  28. package/dist/composables/useToaster.js +14 -20
  29. package/dist/composables/useTranslations.js +3 -2
  30. package/dist/composables/useVersionHistoryApi.js +33 -24
  31. package/dist/enums/extensions/recommendationBlock.js +49 -33
  32. package/dist/extensions/Blocks/Recommendation/block.js +61 -42
  33. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +21 -20
  34. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +4 -4
  35. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +100 -94
  36. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +130 -55
  37. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +74 -74
  38. package/dist/extensions/Blocks/Recommendation/recommendation.css.js +6 -3
  39. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +273 -92
  40. package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js +42 -0
  41. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +26 -16
  42. package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +24 -0
  43. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +21 -12
  44. package/dist/guido.css +1 -1
  45. package/dist/library.js +15 -13
  46. package/dist/package.json.js +1 -1
  47. package/dist/public/editorState.js +4 -0
  48. package/dist/services/recommendationApi.js +46 -37
  49. package/dist/services/templateLibraryApi.js +17 -14
  50. package/dist/src/@types/config/schemas.d.ts +16 -0
  51. package/dist/src/components/organisms/extensions/recommendation/LegacyStrategyUpdatedModal.vue.d.ts +2 -0
  52. package/dist/src/components/organisms/onboarding/RecommendationLegacyStrategyOnboarding.vue.d.ts +2 -0
  53. package/dist/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +2 -0
  54. package/dist/src/composables/useConfig.d.ts +4 -0
  55. package/dist/src/composables/useGuidoStateBridge.d.ts +11 -7
  56. package/dist/src/composables/useLegacyStrategyConversion.d.ts +3 -0
  57. package/dist/src/enums/extensions/recommendationBlock.d.ts +7 -1
  58. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +10 -0
  59. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +1 -0
  60. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  61. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +2 -0
  62. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +10 -0
  63. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +7 -2
  64. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +162 -1
  65. package/dist/src/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.d.ts +32 -0
  66. package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +14 -0
  67. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +4 -0
  68. package/dist/src/library.d.ts +2 -0
  69. package/dist/src/public/editorState.d.ts +14 -0
  70. package/dist/src/public/trackingIds.d.ts +6 -2
  71. package/dist/src/services/recommendationApi.d.ts +2 -1
  72. package/dist/src/stores/config.d.ts +322 -0
  73. package/dist/src/stores/editor.d.ts +25 -0
  74. package/dist/src/stores/guido-email-editor.d.ts +27 -27
  75. package/dist/src/stores/onboarding.d.ts +808 -10
  76. package/dist/src/utils/genericUtil.d.ts +6 -0
  77. package/dist/src/utils/liquidDynamicContent.d.ts +20 -0
  78. package/dist/src/utils/stripoEditorApi.d.ts +4 -0
  79. package/dist/static/assets/icons/filled-arrow-rising.svg.js +5 -0
  80. package/dist/static/assets/icons/line-info.svg.js +5 -0
  81. package/dist/static/styles/components/recommendation-strategy.css.js +104 -9
  82. package/dist/static/styles/components/skeleton.css.js +23 -0
  83. package/dist/stores/config.js +74 -60
  84. package/dist/stores/editor.js +4 -0
  85. package/dist/stores/guido-email-editor.js +0 -4
  86. package/dist/stores/onboarding.js +46 -36
  87. package/dist/stores/unsubscribe.js +3 -3
  88. package/dist/utils/genericUtil.js +63 -54
  89. package/dist/utils/liquidDynamicContent.js +15 -0
  90. package/dist/utils/stripoEditorApi.js +11 -0
  91. package/dist/utils/templatePreparation.js +61 -60
  92. package/package.json +10 -6
@@ -1,13 +1,13 @@
1
- import { DEFAULT_COLUMN_SPACING as R, DEFAULT_ROW_SPACING as s, DEFAULT_MOBILE_ROW_SPACING as n, DEFAULT_MOBILE_COLUMN_SPACING as O, DEFAULT_MOBILE_CARDS_IN_ROW as e, DEFAULT_CARDS_IN_ROW as C } from "./layout.js";
2
- import { ATTR_PRODUCT_IMAGE as o, ATTR_PRODUCT_NAME as t, ATTR_PRODUCT_OLD_PRICE as _, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_OMNIBUS_PRICE as r, ATTR_PRODUCT_OMNIBUS_DISCOUNT as I, ATTR_PRODUCT_BUTTON as i, ATTR_RECOMMENDATION_TITLE as U } from "./selectors.js";
3
- const A = 1, u = 2, D = {
1
+ import { DEFAULT_COLUMN_SPACING as i, DEFAULT_ROW_SPACING as s, DEFAULT_MOBILE_ROW_SPACING as n, DEFAULT_MOBILE_COLUMN_SPACING as O, DEFAULT_MOBILE_CARDS_IN_ROW as e, DEFAULT_CARDS_IN_ROW as C } from "./layout.js";
2
+ import { ATTR_PRODUCT_IMAGE as o, ATTR_PRODUCT_NAME as t, ATTR_PRODUCT_OLD_PRICE as _, ATTR_PRODUCT_PRICE as T, ATTR_PRODUCT_OMNIBUS_PRICE as I, ATTR_PRODUCT_OMNIBUS_DISCOUNT as R, ATTR_PRODUCT_BUTTON as r, ATTR_RECOMMENDATION_TITLE as E } from "./selectors.js";
3
+ const U = 1, u = 2, m = 2, A = {
4
4
  code: "USD",
5
5
  symbol: "USD",
6
6
  alignment: "after",
7
7
  decimalCount: 2,
8
8
  decimalSeparator: ".",
9
9
  thousandSeparator: ","
10
- }, E = {
10
+ }, D = {
11
11
  textBefore: "",
12
12
  textAfter: ""
13
13
  }, a = {
@@ -18,26 +18,26 @@ const A = 1, u = 2, D = {
18
18
  t,
19
19
  _,
20
20
  T,
21
- r,
22
21
  I,
23
- i
22
+ R,
23
+ r
24
24
  ], N = {
25
- [U]: !0,
25
+ [E]: !0,
26
26
  [o]: !0,
27
27
  [t]: !0,
28
28
  [T]: !0,
29
29
  [_]: !0,
30
- [r]: !1,
31
30
  [I]: !1,
32
- [i]: !0
33
- }, m = {
31
+ [R]: !1,
32
+ [r]: !0
33
+ }, L = {
34
34
  // Settings
35
35
  strategy: "mostPopular",
36
36
  productIds: [],
37
37
  size: "6",
38
38
  shuffleProducts: !1,
39
39
  language: "en_US",
40
- currency: D,
40
+ currency: A,
41
41
  filters: [],
42
42
  strategyId: "",
43
43
  // Layout
@@ -46,7 +46,7 @@ const A = 1, u = 2, D = {
46
46
  mobileCardsInRow: e,
47
47
  mobileLayoutEnabled: !1,
48
48
  previousMobileCardsInRow: e,
49
- columnSpacing: R,
49
+ columnSpacing: i,
50
50
  rowSpacing: s,
51
51
  mobileColumnSpacing: O,
52
52
  mobileRowSpacing: n,
@@ -55,7 +55,7 @@ const A = 1, u = 2, D = {
55
55
  visibility: N,
56
56
  previousTitleHtml: "",
57
57
  // Element settings
58
- omnibusPrice: E,
58
+ omnibusPrice: D,
59
59
  omnibusDiscount: a,
60
60
  textTrimming: !1,
61
61
  // Price placement (block-level, affects all cards)
@@ -66,17 +66,18 @@ const A = 1, u = 2, D = {
66
66
  // of "false" (the actual hiding happens server-side at send).
67
67
  priceHideIfSameAsDiscounted: !1,
68
68
  // Meta
69
- configVersion: A,
69
+ configVersion: U,
70
70
  recommendationId: 0
71
- }, L = [11, 12];
71
+ }, P = [11, 12];
72
72
  export {
73
73
  u as CURRENT_CONFIG_VERSION,
74
74
  c as DEFAULT_COMPOSITION,
75
- D as DEFAULT_CURRENCY,
76
- m as DEFAULT_NODE_CONFIG,
75
+ A as DEFAULT_CURRENCY,
76
+ L as DEFAULT_NODE_CONFIG,
77
77
  a as DEFAULT_OMNIBUS_DISCOUNT,
78
- E as DEFAULT_OMNIBUS_PRICE,
78
+ D as DEFAULT_OMNIBUS_PRICE,
79
79
  N as DEFAULT_VISIBILITY,
80
- L as EXCLUDED_ALGORITHM_IDS,
81
- A as PRE_RRS_CONFIG_VERSION
80
+ P as EXCLUDED_ALGORITHM_IDS,
81
+ U as PRE_RRS_CONFIG_VERSION,
82
+ m as RRS_CONFIG_VERSION
82
83
  };
@@ -67,7 +67,7 @@ class se extends ut {
67
67
  (d, c) => `
68
68
  <div data-reorder-icon-key="${P}${c}" style="display: none;">
69
69
  <${_.BUTTON}
70
- class="drag-handle-btn flat-inline flat-white"
70
+ class="guido-drag-handle-btn flat-inline flat-white"
71
71
  ${O.BUTTON.name}="${P}${c}"
72
72
  >
73
73
  <${_.ICON}
@@ -328,7 +328,7 @@ class se extends ut {
328
328
  _createBuiltInItemHtml(t, e) {
329
329
  return `
330
330
  <div class="orderable-item" draggable="true" data-key="${t.key}">
331
- <span class="drag-handle" data-reorder-icon-slot="${e}"></span>
331
+ <span class="guido-drag-handle" data-reorder-icon-slot="${e}"></span>
332
332
  <span class="item-label">${this.api.translate(t.label)}</span>
333
333
  <div class="item-action" data-action-for="${t.key}"></div>
334
334
  </div>
@@ -353,7 +353,7 @@ class se extends ut {
353
353
  <div class="orderable-item price-group-item" draggable="true"
354
354
  data-key="${C}" data-group="prices">
355
355
  <div class="price-group-header">
356
- <span class="drag-handle" data-reorder-icon-slot="${t}"></span>
356
+ <span class="guido-drag-handle" data-reorder-icon-slot="${t}"></span>
357
357
  <span class="item-label">${this.api.translate("Product Prices")}</span>
358
358
  <div class="item-action" data-action-for="${C}"></div>
359
359
  </div>
@@ -365,7 +365,7 @@ class se extends ut {
365
365
  return `
366
366
  <div class="orderable-item" draggable="true"
367
367
  data-key="${t}" data-custom-index="${e}">
368
- <span class="drag-handle" data-reorder-icon-slot="${r}"></span>
368
+ <span class="guido-drag-handle" data-reorder-icon-slot="${r}"></span>
369
369
  <div class="custom-attr-select-wrap"
370
370
  data-custom-select-slot="${e}"></div>
371
371
  <div class="item-action"
@@ -1,27 +1,27 @@
1
1
  var m = Object.defineProperty;
2
- var C = (h, l, t) => l in h ? m(h, l, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[l] = t;
3
- var n = (h, l, t) => C(h, typeof l != "symbol" ? l + "" : l, t);
2
+ var C = (g, c, t) => c in g ? m(g, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : g[c] = t;
3
+ var i = (g, c, t) => C(g, typeof c != "symbol" ? c + "" : c, t);
4
4
  import { useConfig as p } from "../../../../../composables/useConfig.js";
5
5
  import { ModificationDescription as y } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
6
6
  import { CommonControl as N } from "../../../common-control.js";
7
- import { CURRENT_CONFIG_VERSION as _, DEFAULT_NODE_CONFIG as a } from "../../constants/defaultConfig.js";
7
+ import { RRS_CONFIG_VERSION as _, DEFAULT_NODE_CONFIG as a } from "../../constants/defaultConfig.js";
8
8
  import { RECOMMENDATION_ID_ATTR as I } from "../../constants/selectors.js";
9
- import { RecommendationConfigService as c } from "../../services/configService.js";
9
+ import { RecommendationConfigService as l } from "../../services/configService.js";
10
10
  import { useRecommendationExtensionStore as R } from "../../store/recommendation.js";
11
11
  import { registerNodeConfigWriter as b } from "../../utils/nodeConfigWriter.js";
12
12
  import { AlgorithmControl as T } from "./algorithm.js";
13
- import { ALGORITHM_CONTROL_ID as ut } from "./algorithm.js";
13
+ import { ALGORITHM_CONTROL_ID as dt } from "./algorithm.js";
14
14
  import { CurrencyControl as P } from "./currency.js";
15
- import { CURRENCY_CONTROL_ID as ht } from "./currency.js";
15
+ import { CURRENCY_CONTROL_ID as gt } from "./currency.js";
16
16
  import { FiltersControl as S } from "./filters.js";
17
- import { FILTERS_CONTROL_ID as gt } from "./filters.js";
17
+ import { FILTERS_CONTROL_ID as ft } from "./filters.js";
18
18
  import { LayoutOrientationControl as O } from "./layoutOrientation.js";
19
19
  import { LAYOUT_ORIENTATION_CONTROL_ID as Ct } from "./layoutOrientation.js";
20
20
  import { LocaleControl as L } from "./locale.js";
21
21
  import { LOCALE_CONTROL_ID as yt } from "./locale.js";
22
- import { PricePlacementControl as E } from "./pricePlacement.js";
22
+ import { PricePlacementControl as k } from "./pricePlacement.js";
23
23
  import { PRICE_PLACEMENT_CONTROL_ID as _t } from "./pricePlacement.js";
24
- import { ProductCountControl as k } from "./productCount.js";
24
+ import { ProductCountControl as E } from "./productCount.js";
25
25
  import { PRODUCT_COUNT_CONTROL_ID as Rt } from "./productCount.js";
26
26
  import { ProductLayoutControl as F } from "./productLayout.js";
27
27
  import { PRODUCT_LAYOUT_CONTROL_ID as Tt } from "./productLayout.js";
@@ -29,36 +29,36 @@ import { ShuffleControl as D } from "./shuffle.js";
29
29
  import { SHUFFLE_CONTROL_ID as St } from "./shuffle.js";
30
30
  import { StrategyControl as w } from "./strategy.js";
31
31
  import { STRATEGY_CONTROL_ID as Lt } from "./strategy.js";
32
- import { setCurrencyAttributes as A, getBlockElement as v, isPartnerManagedBlock as x, updateProductContentInPlace as B, regenerateProductRowsWithStyles as U } from "./utils.js";
33
- import { adjustProductsToSize as kt, formatProductPrice as Ft, getCardComposition as Dt, getCurrentLayout as wt, getMainContainerTbody as At, regenerateMobileProductRows as vt, updatePricesInPlace as xt, updateSingleProductContent as Bt } from "./utils.js";
34
- import { useDebounceFn as f } from "../../../../../node_modules/@vueuse/shared/index.js";
35
- const $ = "ui-elements-recommendation-block";
32
+ import { setCurrencyAttributes as A, getBlockElement as B, isPartnerManagedBlock as v, updateProductContentInPlace as x, regenerateProductRowsWithStyles as U } from "./utils.js";
33
+ import { adjustProductsToSize as Et, formatProductPrice as Ft, getCardComposition as Dt, getCurrentLayout as wt, getMainContainerTbody as At, regenerateMobileProductRows as Bt, updatePricesInPlace as vt, updateSingleProductContent as xt } from "./utils.js";
34
+ import { useDebounceFn as h } from "../../../../../node_modules/@vueuse/shared/index.js";
35
+ const W = "ui-elements-recommendation-block";
36
36
  class at extends N {
37
37
  constructor() {
38
38
  super(...arguments);
39
- n(this, "store", R());
40
- n(this, "storeUnsubscription", () => {
39
+ i(this, "store", R());
40
+ i(this, "storeUnsubscription", () => {
41
41
  });
42
42
  // A config change waiting to reach the node config. Deferred so it can ride the
43
43
  // re-render's single apply() — one user action must cost one undo press.
44
- n(this, "pendingNodeConfigWrite", null);
45
- n(this, "pendingConfigFlushTimer", null);
44
+ i(this, "pendingNodeConfigWrite", null);
45
+ i(this, "pendingConfigFlushTimer", null);
46
46
  // Sub-control instances for lifecycle management
47
- n(this, "algorithmControl", null);
48
- n(this, "localeControl", null);
49
- n(this, "currencyControl", null);
50
- n(this, "productCountControl", null);
51
- n(this, "productLayoutControl", null);
52
- n(this, "filtersControl", null);
53
- n(this, "shuffleControl", null);
54
- n(this, "pricePlacementControl", null);
55
- n(this, "layoutOrientationControl", null);
56
- n(this, "strategyControl", null);
57
- n(this, "rrsEnabled", !1);
47
+ i(this, "algorithmControl", null);
48
+ i(this, "localeControl", null);
49
+ i(this, "currencyControl", null);
50
+ i(this, "productCountControl", null);
51
+ i(this, "productLayoutControl", null);
52
+ i(this, "filtersControl", null);
53
+ i(this, "shuffleControl", null);
54
+ i(this, "pricePlacementControl", null);
55
+ i(this, "layoutOrientationControl", null);
56
+ i(this, "strategyControl", null);
57
+ i(this, "rrsEnabled", !1);
58
58
  /**
59
59
  * Debounced product fetch to prevent rapid API calls during config changes
60
60
  */
61
- n(this, "_debouncedFetchProducts", f(async () => {
61
+ i(this, "_debouncedFetchProducts", h(async () => {
62
62
  try {
63
63
  await this.store.fetchRecommendationProducts();
64
64
  } finally {
@@ -76,16 +76,16 @@ class at extends N {
76
76
  * count. The store pads products to the configured size, so in-place only
77
77
  * fails when the size actually changed.
78
78
  */
79
- n(this, "_debouncedRegenerateWithProducts", f(() => {
79
+ i(this, "_debouncedRegenerateWithProducts", h(() => {
80
80
  const t = this.store.recommendationProducts;
81
81
  if (!this.currentNode || !this.api)
82
82
  return;
83
83
  const e = this.api.getDocumentModifier(), o = this._stagePendingNodeConfig(e);
84
- if (x(this.currentNode)) {
84
+ if (v(this.currentNode)) {
85
85
  o && (e.apply(new y("Update recommendation configuration")), this.pendingNodeConfigWrite = null, this._clearConfigFlush());
86
86
  return;
87
87
  }
88
- B({
88
+ x({
89
89
  currentNode: this.currentNode,
90
90
  documentModifier: e,
91
91
  products: t
@@ -97,7 +97,7 @@ class at extends N {
97
97
  }, 100));
98
98
  }
99
99
  getId() {
100
- return $;
100
+ return W;
101
101
  }
102
102
  get _subControls() {
103
103
  return [
@@ -118,7 +118,7 @@ class at extends N {
118
118
  return this.rrsEnabled = p().isFeatureEnabled("reusableRecommendationStrategy"), this._subControls.forEach((e) => {
119
119
  var o;
120
120
  return (o = e == null ? void 0 : e.onDestroy) == null ? void 0 : o.call(e);
121
- }), this.algorithmControl = new T(), this.localeControl = new L(), this.currencyControl = new P(), this.productCountControl = new k(), this.productLayoutControl = new F(), this.filtersControl = new S(), this.shuffleControl = new D(), this.pricePlacementControl = new E(), this.layoutOrientationControl = new O(), this.strategyControl = this.rrsEnabled ? new w() : null, this._subControls.forEach((e) => {
121
+ }), this.algorithmControl = new T(), this.localeControl = new L(), this.currencyControl = new P(), this.productCountControl = new E(), this.productLayoutControl = new F(), this.filtersControl = new S(), this.shuffleControl = new D(), this.pricePlacementControl = new k(), this.layoutOrientationControl = new O(), this.strategyControl = this.rrsEnabled ? new w() : null, this._subControls.forEach((e) => {
122
122
  e && (e.api = this.api);
123
123
  }), `
124
124
  <div class="recommendation-controls-container">
@@ -136,18 +136,18 @@ class at extends N {
136
136
  `;
137
137
  }
138
138
  _showControlsForBlock(t) {
139
- var i;
140
- const e = (i = this.getContainer()) == null ? void 0 : i.querySelector(".recommendation-controls-container");
139
+ var r;
140
+ const e = (r = this.getContainer()) == null ? void 0 : r.querySelector(".recommendation-controls-container");
141
141
  if (!e)
142
142
  return;
143
- const o = this._getRecommendationIdFromNode(t) === null ? null : c.getConfig(t), r = this.rrsEnabled && !!o && (!!(o != null && o.strategyId) || ((o == null ? void 0 : o.configVersion) ?? 0) >= _);
144
- e.classList.toggle("strategy-block", r);
143
+ const o = this._getRecommendationIdFromNode(t) === null ? null : l.getConfig(t), n = this.rrsEnabled && !!o && (!!(o != null && o.strategyId) || ((o == null ? void 0 : o.configVersion) ?? 0) >= _), s = this.rrsEnabled && !!o && !n;
144
+ e.classList.toggle("strategy-block", n), e.classList.toggle("legacy-strategy-block", s);
145
145
  }
146
146
  async onRender() {
147
147
  var o;
148
148
  b(this.api);
149
149
  const t = this._getRecommendationIdFromNode(this.currentNode), e = t ?? this.store.currentRecommendationId;
150
- if (e !== null && this.store.setCurrentBlock(e), t !== null && this._syncNodeConfigIfChanged(t), this._listenStateUpdates(), this._showControlsForBlock(this.currentNode), e !== null && ((o = this.store.blockStates[e]) != null && o.isInitialized)) {
150
+ if (e !== null && this.store.setCurrentBlock(e), t !== null && this._syncNodeConfigIfChanged(t), this._listenStateUpdates(), this._showControlsForBlock(this.currentNode), t !== null && this.strategyControl && (this.strategyControl.api = this.api, this.strategyControl.currentNode = this.currentNode, this.strategyControl.onRender()), e !== null && ((o = this.store.blockStates[e]) != null && o.isInitialized)) {
151
151
  this._initializeSubControls();
152
152
  return;
153
153
  }
@@ -159,9 +159,9 @@ class at extends N {
159
159
  const e = this._getRecommendationIdFromNode(t);
160
160
  e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && this._syncNodeConfigIfChanged(e), this._showControlsForBlock(t), e !== null && !((o = this.store.blockStates[e]) != null && o.isInitialized) && this._fetchBlockData(e).then(() => {
161
161
  this._initializeSubControls();
162
- }), this._subControls.forEach((r) => {
163
- var i;
164
- r != null && r.api && (r.currentNode = t, (i = r.onTemplateNodeUpdated) == null || i.call(r, t));
162
+ }), this._subControls.forEach((n) => {
163
+ var s;
164
+ n != null && n.api && (n.currentNode = t, (s = n.onTemplateNodeUpdated) == null || s.call(n, t));
165
165
  });
166
166
  }
167
167
  onDestroy() {
@@ -209,18 +209,23 @@ class at extends N {
209
209
  const e = this.store.blockStates[t];
210
210
  if (!e)
211
211
  return;
212
- const o = JSON.stringify(c.getConfig(this.currentNode)), r = e.syncedConfigFingerprint;
213
- e.syncedConfigFingerprint = o, r !== o && (this.pendingNodeConfigWrite || this._syncNodeConfigToStore());
212
+ const o = JSON.stringify(l.getConfig(this.currentNode)), n = e.syncedConfigFingerprint;
213
+ e.syncedConfigFingerprint = o, n !== o && (this.pendingNodeConfigWrite || this._syncNodeConfigToStore());
214
+ }
215
+ /** Whether the deferred write would move the node's strategyId — see the caller (SD-149916). */
216
+ _isPendingStrategyIdChange() {
217
+ const t = this.pendingNodeConfigWrite;
218
+ return t ? l.getConfig(this.currentNode).strategyId !== t.updates.strategyId : !1;
214
219
  }
215
220
  _capturePendingNodeConfigWrite() {
216
221
  const t = this.store.currentRecommendationId;
217
222
  if (!this.currentNode || !this.api || t === null)
218
223
  return;
219
- const { filters: e, strategyId: o, size: r } = this.store.recommendationConfigs;
224
+ const { filters: e, strategy: o, strategyId: n, size: s, nodeConfigVersion: r } = this.store.recommendationConfigs;
220
225
  this.pendingNodeConfigWrite = {
221
226
  blockId: t,
222
227
  node: this.currentNode,
223
- updates: { filters: e, strategyId: o, size: r }
228
+ updates: { filters: e, strategy: o, strategyId: n, size: s, configVersion: r }
224
229
  };
225
230
  }
226
231
  /**
@@ -235,7 +240,7 @@ class at extends N {
235
240
  */
236
241
  _stagePendingNodeConfig(t) {
237
242
  const e = this.pendingNodeConfigWrite;
238
- return !e || !this.currentNode ? !1 : (c.stageConfig(t, this.currentNode, e.updates), !0);
243
+ return !e || !this.currentNode ? !1 : (l.stageConfig(t, this.currentNode, e.updates), !0);
239
244
  }
240
245
  /**
241
246
  * Arms the guaranteed fallback write, once the product fetch has settled. The
@@ -259,15 +264,16 @@ class at extends N {
259
264
  const t = this.pendingNodeConfigWrite;
260
265
  if (this.pendingNodeConfigWrite = null, this._clearConfigFlush(), !t || !this.api)
261
266
  return;
262
- const e = t.blockId === this.store.currentRecommendationId && this.currentNode ? this.currentNode : t.node, o = c.getConfig(e);
263
- JSON.stringify(o.filters) === JSON.stringify(t.updates.filters) && o.strategyId === t.updates.strategyId && o.size === t.updates.size || c.updateConfig(this.api, e, t.updates, "Update recommendation filters");
267
+ const e = t.blockId === this.store.currentRecommendationId && this.currentNode ? this.currentNode : t.node, o = l.getConfig(e);
268
+ JSON.stringify(o.filters) === JSON.stringify(t.updates.filters) && o.strategy === t.updates.strategy && o.strategyId === t.updates.strategyId && o.size === t.updates.size || l.updateConfig(this.api, e, t.updates, "Update recommendation filters");
264
269
  }
265
270
  _syncNodeConfigToStore() {
266
- var r;
267
- const t = c.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((r = this.store.blockStates[e]) == null ? void 0 : r.isInitialized);
271
+ var n;
272
+ const t = l.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((n = this.store.blockStates[e]) == null ? void 0 : n.isInitialized);
268
273
  this.store.patchCurrentBlockConfig({
269
274
  strategy: t.strategy,
270
275
  strategyId: t.strategyId,
276
+ nodeConfigVersion: t.configVersion,
271
277
  language: t.language,
272
278
  size: t.size,
273
279
  productIds: t.productIds,
@@ -306,8 +312,8 @@ class at extends N {
306
312
  t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
307
313
  this.store.fetchRecommendationCreateData(),
308
314
  this.store.fetchRecommendationFilters()
309
- ])).forEach((o, r) => {
310
- o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][r]} failed`, o.reason);
315
+ ])).forEach((o, n) => {
316
+ o.status === "rejected" && console.warn(`Recommendation block: ${["fetchRecommendationCreateData", "fetchRecommendationFilters"][n]} failed`, o.reason);
311
317
  }), this._applySmartDefaults();
312
318
  try {
313
319
  await this.store.fetchRecommendationProducts();
@@ -328,31 +334,31 @@ class at extends N {
328
334
  _applySmartDefaults() {
329
335
  if (!this.currentNode || !this.api)
330
336
  return;
331
- const t = c.getConfig(this.currentNode), e = {};
332
- let o = null, r = null, i = null;
337
+ const t = l.getConfig(this.currentNode), e = {};
338
+ let o = null, n = null, s = null;
333
339
  if (t.currency.code === a.currency.code) {
334
- const { currencyList: s } = this.store;
335
- s.length > 0 && (s.some(
336
- (d) => d.value === `price.${a.currency.code}`
337
- ) || (o = s[0].value.replace("price.", ""), e.currency = {
340
+ const { currencyList: r } = this.store;
341
+ r.length > 0 && (r.some(
342
+ (u) => u.value === `price.${a.currency.code}`
343
+ ) || (o = r[0].value.replace("price.", ""), e.currency = {
338
344
  ...a.currency,
339
345
  code: o,
340
346
  symbol: o
341
347
  }));
342
348
  }
343
349
  if (t.strategy === a.strategy) {
344
- const s = this.store.getActivePredictiveAlgorithms;
345
- s.length > 0 && (s.some(
346
- (d) => d.value === a.strategy
347
- ) || (r = s[0].value, e.strategy = r));
350
+ const r = this.store.getActivePredictiveAlgorithms;
351
+ r.length > 0 && (r.some(
352
+ (u) => u.value === a.strategy
353
+ ) || (n = r[0].value, e.strategy = n));
348
354
  }
349
355
  if (t.language === a.language) {
350
- const s = this.store.getLanguages;
351
- s.length > 0 && (s.some(
352
- (d) => d.value === a.language
353
- ) || (i = s[0].value, e.language = i));
356
+ const r = this.store.getLanguages;
357
+ r.length > 0 && (r.some(
358
+ (u) => u.value === a.language
359
+ ) || (s = r[0].value, e.language = s));
354
360
  }
355
- !o && !r && !i || (c.updateConfig(
361
+ !o && !n && !s || (l.updateConfig(
356
362
  this.api,
357
363
  this.currentNode,
358
364
  e,
@@ -373,22 +379,22 @@ class at extends N {
373
379
  thousandSeparator: a.currency.thousandSeparator
374
380
  }
375
381
  } : {},
376
- ...r ? { strategy: r } : {},
377
- ...i ? { language: i } : {}
382
+ ...n ? { strategy: n } : {},
383
+ ...s ? { language: s } : {}
378
384
  }, { triggerRefetch: !1 }));
379
385
  }
380
386
  /**
381
387
  * Reads the recommendation-id attribute from the block element within the node
382
388
  */
383
389
  _getRecommendationIdFromNode(t) {
384
- const e = v(t);
390
+ const e = B(t);
385
391
  if (!e || !("getAttribute" in e))
386
392
  return null;
387
393
  const o = e.getAttribute(I);
388
394
  if (!o)
389
395
  return null;
390
- const r = parseInt(o);
391
- return Number.isNaN(r) ? null : r;
396
+ const n = parseInt(o);
397
+ return Number.isNaN(n) ? null : n;
392
398
  }
393
399
  /**
394
400
  * Listen to store changes that require product refresh or regeneration.
@@ -405,27 +411,27 @@ class at extends N {
405
411
  */
406
412
  _listenStateUpdates() {
407
413
  const { store: t } = this;
408
- let e = t.recommendationProducts, o = t.$state.configVersion, r = t.currentRecommendationId;
414
+ let e = t.recommendationProducts, o = t.$state.configVersion, n = t.currentRecommendationId;
409
415
  this.storeUnsubscription = t.$subscribe(() => {
410
- const i = t.currentRecommendationId;
411
- if (i !== r) {
412
- r = i, e = t.recommendationProducts, o = t.$state.configVersion;
416
+ const s = t.currentRecommendationId;
417
+ if (s !== n) {
418
+ n = s, e = t.recommendationProducts, o = t.$state.configVersion;
413
419
  return;
414
420
  }
415
- const s = t.$state.configVersion;
416
- s !== o && (o = s, this._capturePendingNodeConfigWrite(), this._debouncedFetchProducts());
417
- const u = t.recommendationProducts, d = u !== e, g = Array.isArray(u) && u.length > 0;
418
- d && g && (e = u, this._debouncedRegenerateWithProducts());
421
+ const r = t.$state.configVersion;
422
+ r !== o && (o = r, this._capturePendingNodeConfigWrite(), this._isPendingStrategyIdChange() && this._flushPendingNodeConfig(), this._debouncedFetchProducts());
423
+ const d = t.recommendationProducts, u = d !== e, f = Array.isArray(d) && d.length > 0;
424
+ u && f && (e = d, this._debouncedRegenerateWithProducts());
419
425
  });
420
426
  }
421
427
  }
422
428
  export {
423
- ut as ALGORITHM_CONTROL_ID,
429
+ dt as ALGORITHM_CONTROL_ID,
424
430
  T as AlgorithmControl,
425
- $ as CONTROL_BLOCK_ID,
426
- ht as CURRENCY_CONTROL_ID,
431
+ W as CONTROL_BLOCK_ID,
432
+ gt as CURRENCY_CONTROL_ID,
427
433
  P as CurrencyControl,
428
- gt as FILTERS_CONTROL_ID,
434
+ ft as FILTERS_CONTROL_ID,
429
435
  S as FiltersControl,
430
436
  Ct as LAYOUT_ORIENTATION_CONTROL_ID,
431
437
  yt as LOCALE_CONTROL_ID,
@@ -434,25 +440,25 @@ export {
434
440
  _t as PRICE_PLACEMENT_CONTROL_ID,
435
441
  Rt as PRODUCT_COUNT_CONTROL_ID,
436
442
  Tt as PRODUCT_LAYOUT_CONTROL_ID,
437
- E as PricePlacementControl,
438
- k as ProductCountControl,
443
+ k as PricePlacementControl,
444
+ E as ProductCountControl,
439
445
  F as ProductLayoutControl,
440
446
  at as RecommendationBlockControl,
441
447
  St as SHUFFLE_CONTROL_ID,
442
448
  Lt as STRATEGY_CONTROL_ID,
443
449
  D as ShuffleControl,
444
450
  w as StrategyControl,
445
- kt as adjustProductsToSize,
451
+ Et as adjustProductsToSize,
446
452
  Ft as formatProductPrice,
447
- v as getBlockElement,
453
+ B as getBlockElement,
448
454
  Dt as getCardComposition,
449
455
  wt as getCurrentLayout,
450
456
  At as getMainContainerTbody,
451
- x as isPartnerManagedBlock,
452
- vt as regenerateMobileProductRows,
457
+ v as isPartnerManagedBlock,
458
+ Bt as regenerateMobileProductRows,
453
459
  U as regenerateProductRowsWithStyles,
454
460
  A as setCurrencyAttributes,
455
- xt as updatePricesInPlace,
456
- B as updateProductContentInPlace,
457
- Bt as updateSingleProductContent
461
+ vt as updatePricesInPlace,
462
+ x as updateProductContentInPlace,
463
+ xt as updateSingleProductContent
458
464
  };