@useinsider/guido 3.19.0-beta.f0d5980 → 3.19.0-beta.f328a8a

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 (25) hide show
  1. package/dist/composables/useAutoSave.js +11 -11
  2. package/dist/config/migrator/itemsBlockMigrator.js +236 -248
  3. package/dist/config/migrator/recommendationMigrator.js +28 -21
  4. package/dist/config/migrator/recommendationPartnerMigrator.js +36 -30
  5. package/dist/extensions/Blocks/Items/constants/cardLayout.js +20 -0
  6. package/dist/extensions/Blocks/Items/controls/name/trimming.js +18 -17
  7. package/dist/extensions/Blocks/Items/controls/settingsControl.js +114 -105
  8. package/dist/extensions/Blocks/Items/enums/productEnums.js +14 -9
  9. package/dist/extensions/Blocks/Items/layouts/horizontal.html.js +11 -9
  10. package/dist/extensions/Blocks/Items/template.js +219 -204
  11. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +246 -203
  12. package/dist/src/composables/useGuidoActions.d.ts +2 -0
  13. package/dist/src/extensions/Blocks/Items/constants/cardLayout.d.ts +44 -0
  14. package/dist/src/extensions/Blocks/Items/enums/productEnums.d.ts +3 -0
  15. package/dist/src/extensions/Blocks/Items/template.d.ts +19 -0
  16. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +8 -0
  17. package/dist/src/mock/cortexChatStore.d.ts +12 -0
  18. package/dist/src/stores/onboarding.d.ts +4 -0
  19. package/dist/src/stores/recommendation.d.ts +5 -0
  20. package/dist/src/utils/dateUtil.d.ts +10 -0
  21. package/dist/src/utils/genericUtil.d.ts +3 -0
  22. package/dist/static/styles/components/version-history.css.js +2 -6
  23. package/dist/stores/onboarding.js +4 -0
  24. package/dist/utils/pairProductVariables.js +71 -71
  25. package/package.json +1 -1
@@ -1,66 +1,72 @@
1
1
  var C = Object.defineProperty;
2
- var p = (g, u, t) => u in g ? C(g, u, { enumerable: !0, configurable: !0, writable: !0, value: t }) : g[u] = t;
3
- var i = (g, u, t) => p(g, typeof u != "symbol" ? u + "" : u, t);
4
- import { useConfig as h } from "../../../../../composables/useConfig.js";
2
+ var p = (h, u, e) => u in h ? C(h, u, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[u] = e;
3
+ var r = (h, u, e) => p(h, typeof u != "symbol" ? u + "" : u, e);
4
+ import { useConfig as f } 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 { RRS_CONFIG_VERSION as _, DEFAULT_NODE_CONFIG as a } from "../../constants/defaultConfig.js";
7
+ import { RRS_CONFIG_VERSION as _, DEFAULT_NODE_CONFIG as c } 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 d } from "../../services/configService.js";
10
10
  import { useRecommendationExtensionStore as R } from "../../store/recommendation.js";
11
- import { registerNodeConfigWriter as b } from "../../utils/nodeConfigWriter.js";
12
- import { AlgorithmControl as T } from "./algorithm.js";
13
- import { ALGORITHM_CONTROL_ID as ut } from "./algorithm.js";
14
- import { CurrencyControl as P } from "./currency.js";
15
- import { CURRENCY_CONTROL_ID as gt } from "./currency.js";
16
- import { FiltersControl as S } from "./filters.js";
17
- import { FILTERS_CONTROL_ID as ft } from "./filters.js";
18
- import { LayoutOrientationControl as O } from "./layoutOrientation.js";
19
- import { LAYOUT_ORIENTATION_CONTROL_ID as Ct } from "./layoutOrientation.js";
11
+ import { registerNodeConfigWriter as b, commitBlockChangeOutsidePanel as P } from "../../utils/nodeConfigWriter.js";
12
+ import { AlgorithmControl as S } from "./algorithm.js";
13
+ import { ALGORITHM_CONTROL_ID as ue } from "./algorithm.js";
14
+ import { CurrencyControl as T } from "./currency.js";
15
+ import { CURRENCY_CONTROL_ID as ge } from "./currency.js";
16
+ import { FiltersControl as O } from "./filters.js";
17
+ import { FILTERS_CONTROL_ID as me } from "./filters.js";
18
+ import { LayoutOrientationControl as k } from "./layoutOrientation.js";
19
+ import { LAYOUT_ORIENTATION_CONTROL_ID as pe } from "./layoutOrientation.js";
20
20
  import { LocaleControl as L } from "./locale.js";
21
- import { LOCALE_CONTROL_ID as yt } from "./locale.js";
22
- import { PricePlacementControl as k } from "./pricePlacement.js";
23
- import { PRICE_PLACEMENT_CONTROL_ID as _t } from "./pricePlacement.js";
24
- import { ProductCountControl as E } from "./productCount.js";
25
- import { PRODUCT_COUNT_CONTROL_ID as Rt } from "./productCount.js";
26
- import { ProductLayoutControl as F } from "./productLayout.js";
27
- import { PRODUCT_LAYOUT_CONTROL_ID as Tt } from "./productLayout.js";
28
- import { ShuffleControl as D } from "./shuffle.js";
29
- import { SHUFFLE_CONTROL_ID as St } from "./shuffle.js";
30
- import { StrategyControl as w } from "./strategy.js";
31
- import { STRATEGY_CONTROL_ID as Lt } from "./strategy.js";
32
- import { setCurrencyAttributes as v, getBlockElement as A, isPartnerManagedBlock as B, 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 vt, regenerateMobileProductRows as At, updatePricesInPlace as Bt, updateSingleProductContent as xt } from "./utils.js";
34
- import { useDebounceFn as f } from "../../../../../node_modules/@vueuse/shared/index.js";
21
+ import { LOCALE_CONTROL_ID as Ne } from "./locale.js";
22
+ import { PricePlacementControl as E } from "./pricePlacement.js";
23
+ import { PRICE_PLACEMENT_CONTROL_ID as Ie } from "./pricePlacement.js";
24
+ import { ProductCountControl as F } from "./productCount.js";
25
+ import { PRODUCT_COUNT_CONTROL_ID as be } from "./productCount.js";
26
+ import { ProductLayoutControl as D } from "./productLayout.js";
27
+ import { PRODUCT_LAYOUT_CONTROL_ID as Se } from "./productLayout.js";
28
+ import { ShuffleControl as w } from "./shuffle.js";
29
+ import { SHUFFLE_CONTROL_ID as Oe } from "./shuffle.js";
30
+ import { StrategyControl as B } from "./strategy.js";
31
+ import { STRATEGY_CONTROL_ID as Le } from "./strategy.js";
32
+ import { setCurrencyAttributes as U, getBlockElement as v, isPartnerManagedBlock as A, updateProductContentInPlace as x, regenerateProductRowsWithStyles as V } from "./utils.js";
33
+ import { adjustProductsToSize as Fe, formatProductPrice as De, getCardComposition as we, getCurrentLayout as Be, getMainContainerTbody as Ue, regenerateMobileProductRows as ve, updatePricesInPlace as Ae, updateSingleProductContent as xe } from "./utils.js";
34
+ import { useDebounceFn as m } from "../../../../../node_modules/@vueuse/shared/index.js";
35
35
  const W = "ui-elements-recommendation-block";
36
- class at extends N {
36
+ class ce extends N {
37
37
  constructor() {
38
38
  super(...arguments);
39
- i(this, "store", R());
40
- i(this, "storeUnsubscription", () => {
39
+ r(this, "store", R());
40
+ r(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
- i(this, "pendingNodeConfigWrite", null);
45
- i(this, "pendingConfigFlushTimer", null);
44
+ r(this, "pendingNodeConfigWrite", null);
45
+ r(this, "pendingConfigFlushTimer", null);
46
+ // Last configVersion the subscription handled, and whether its products still
47
+ // have to reach the canvas — both read on destroy to finish that work.
48
+ r(this, "seenConfigVersion", 0);
49
+ r(this, "fetchedConfigVersion", 0);
50
+ r(this, "hasUnappliedConfigChange", !1);
46
51
  // Sub-control instances for lifecycle management
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);
52
+ r(this, "algorithmControl", null);
53
+ r(this, "localeControl", null);
54
+ r(this, "currencyControl", null);
55
+ r(this, "productCountControl", null);
56
+ r(this, "productLayoutControl", null);
57
+ r(this, "filtersControl", null);
58
+ r(this, "shuffleControl", null);
59
+ r(this, "pricePlacementControl", null);
60
+ r(this, "layoutOrientationControl", null);
61
+ r(this, "strategyControl", null);
62
+ r(this, "rrsEnabled", !1);
58
63
  /**
59
64
  * Debounced product fetch to prevent rapid API calls during config changes
60
65
  */
61
- i(this, "_debouncedFetchProducts", f(async () => {
66
+ r(this, "_debouncedFetchProducts", m(async () => {
67
+ const { configVersion: e } = this.store.$state;
62
68
  try {
63
- await this.store.fetchRecommendationProducts();
69
+ await this.store.fetchRecommendationProducts(), this.fetchedConfigVersion = e;
64
70
  } finally {
65
71
  this._scheduleConfigFlush();
66
72
  }
@@ -76,23 +82,24 @@ class at extends N {
76
82
  * count. The store pads products to the configured size, so in-place only
77
83
  * fails when the size actually changed.
78
84
  */
79
- i(this, "_debouncedRegenerateWithProducts", f(() => {
80
- const t = this.store.recommendationProducts;
85
+ r(this, "_debouncedRegenerateWithProducts", m(() => {
86
+ const e = this.store.recommendationProducts;
81
87
  if (!this.currentNode || !this.api)
82
88
  return;
83
- const e = this.api.getDocumentModifier(), o = this._stagePendingNodeConfig(e);
84
- if (B(this.currentNode)) {
85
- o && (e.apply(new y("Update recommendation configuration")), this.pendingNodeConfigWrite = null, this._clearConfigFlush());
89
+ this.fetchedConfigVersion === this.seenConfigVersion && (this.hasUnappliedConfigChange = !1);
90
+ const t = this.api.getDocumentModifier(), o = this._stagePendingNodeConfig(t);
91
+ if (A(this.currentNode)) {
92
+ o && (t.apply(new y("Update recommendation configuration")), this.pendingNodeConfigWrite = null, this._clearConfigFlush());
86
93
  return;
87
94
  }
88
95
  x({
89
96
  currentNode: this.currentNode,
90
- documentModifier: e,
91
- products: t
92
- }) || U({
97
+ documentModifier: t,
98
+ products: e
99
+ }) || V({
93
100
  currentNode: this.currentNode,
94
- documentModifier: e,
95
- products: t
101
+ documentModifier: t,
102
+ products: e
96
103
  });
97
104
  }, 100));
98
105
  }
@@ -114,15 +121,15 @@ class at extends N {
114
121
  ];
115
122
  }
116
123
  getTemplate() {
117
- var t;
118
- return this.rrsEnabled = h().isFeatureEnabled("reusableRecommendationStrategy"), this._subControls.forEach((e) => {
124
+ var e;
125
+ return this.rrsEnabled = f().isFeatureEnabled("reusableRecommendationStrategy"), this._subControls.forEach((t) => {
119
126
  var o;
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 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
- e && (e.api = this.api);
127
+ return (o = t == null ? void 0 : t.onDestroy) == null ? void 0 : o.call(t);
128
+ }), this.algorithmControl = new S(), this.localeControl = new L(), this.currencyControl = new T(), this.productCountControl = new F(), this.productLayoutControl = new D(), this.filtersControl = new O(), this.shuffleControl = new w(), this.pricePlacementControl = new E(), this.layoutOrientationControl = new k(), this.strategyControl = this.rrsEnabled ? new B() : null, this._subControls.forEach((t) => {
129
+ t && (t.api = this.api);
123
130
  }), `
124
131
  <div class="recommendation-controls-container">
125
- ${((t = this.strategyControl) == null ? void 0 : t.getTemplate()) ?? ""}
132
+ ${((e = this.strategyControl) == null ? void 0 : e.getTemplate()) ?? ""}
126
133
  ${this.layoutOrientationControl.getTemplate()}
127
134
  ${this.productCountControl.getTemplate()}
128
135
  ${this.productLayoutControl.getTemplate()}
@@ -135,39 +142,40 @@ class at extends N {
135
142
  </div>
136
143
  `;
137
144
  }
138
- _showControlsForBlock(t) {
139
- var r;
140
- const e = (r = this.getContainer()) == null ? void 0 : r.querySelector(".recommendation-controls-container");
141
- if (!e)
145
+ _showControlsForBlock(e) {
146
+ var i;
147
+ const t = (i = this.getContainer()) == null ? void 0 : i.querySelector(".recommendation-controls-container");
148
+ if (!t)
142
149
  return;
143
- const o = this._getRecommendationIdFromNode(t) === null ? null : c.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);
150
+ const o = this._getRecommendationIdFromNode(e) === null ? null : d.getConfig(e), n = this.rrsEnabled && !!o && (!!(o != null && o.strategyId) || ((o == null ? void 0 : o.configVersion) ?? 0) >= _), s = this.rrsEnabled && !!o && !n;
151
+ t.classList.toggle("strategy-block", n), t.classList.toggle("legacy-strategy-block", s);
145
152
  }
146
153
  async onRender() {
147
154
  var o;
148
155
  b(this.api);
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), 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)) {
156
+ const e = this._getRecommendationIdFromNode(this.currentNode), t = e ?? this.store.currentRecommendationId;
157
+ if (t !== null && this.store.setCurrentBlock(t), e !== null && this._syncNodeConfigIfChanged(e), this._listenStateUpdates(), this._showControlsForBlock(this.currentNode), e !== null && this.strategyControl && (this.strategyControl.api = this.api, this.strategyControl.currentNode = this.currentNode, this.strategyControl.onRender()), t !== null && ((o = this.store.blockStates[t]) != null && o.isInitialized)) {
151
158
  this._initializeSubControls();
152
159
  return;
153
160
  }
154
- await this._fetchBlockData(e), this._initializeSubControls();
161
+ await this._fetchBlockData(t), this._initializeSubControls();
155
162
  }
156
- onTemplateNodeUpdated(t) {
163
+ onTemplateNodeUpdated(e) {
157
164
  var o;
158
- super.onTemplateNodeUpdated(t);
159
- const e = this._getRecommendationIdFromNode(t);
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(() => {
165
+ super.onTemplateNodeUpdated(e);
166
+ const t = this._getRecommendationIdFromNode(e);
167
+ t !== null && t !== this.store.currentRecommendationId && this.store.setCurrentBlock(t), t !== null && this._syncNodeConfigIfChanged(t), this._showControlsForBlock(e), t !== null && !((o = this.store.blockStates[t]) != null && o.isInitialized) && this._fetchBlockData(t).then(() => {
161
168
  this._initializeSubControls();
162
169
  }), this._subControls.forEach((n) => {
163
170
  var s;
164
- n != null && n.api && (n.currentNode = t, (s = n.onTemplateNodeUpdated) == null || s.call(n, t));
171
+ n != null && n.api && (n.currentNode = e, (s = n.onTemplateNodeUpdated) == null || s.call(n, e));
165
172
  });
166
173
  }
167
174
  onDestroy() {
168
- this.storeUnsubscription(), this._flushPendingNodeConfig(), this._subControls.forEach((t) => {
169
- var e;
170
- return (e = t == null ? void 0 : t.onDestroy) == null ? void 0 : e.call(t);
175
+ const e = this.hasUnappliedConfigChange || this.store.$state.configVersion !== this.seenConfigVersion;
176
+ this.storeUnsubscription(), e ? this._refreshProductsOutsidePanel() : this._flushPendingNodeConfig(), this._subControls.forEach((t) => {
177
+ var o;
178
+ return (o = t == null ? void 0 : t.onDestroy) == null ? void 0 : o.call(t);
171
179
  });
172
180
  }
173
181
  /**
@@ -175,9 +183,9 @@ class at extends N {
175
183
  * Each sub-control manages its own form values and event listeners
176
184
  */
177
185
  _initializeSubControls() {
178
- this._subControls.forEach((t) => {
179
- var e;
180
- t && (t.api = this.api, t.currentNode = this.currentNode, (e = t.onRender) == null || e.call(t));
186
+ this._subControls.forEach((e) => {
187
+ var t;
188
+ e && (e.api = this.api, e.currentNode = this.currentNode, (t = e.onRender) == null || t.call(e));
181
189
  });
182
190
  }
183
191
  /**
@@ -204,34 +212,34 @@ class at extends N {
204
212
  * that state and made a re-dropped saved module keep the defaults its wiped
205
213
  * state was rebuilt with (SD-150347).
206
214
  */
207
- _syncNodeConfigIfChanged(t) {
208
- this.pendingNodeConfigWrite && this.pendingNodeConfigWrite.blockId !== t && this._flushPendingNodeConfig();
209
- const e = this.store.blockStates[t];
210
- if (!e)
215
+ _syncNodeConfigIfChanged(e) {
216
+ this.pendingNodeConfigWrite && this.pendingNodeConfigWrite.blockId !== e && this._flushPendingNodeConfig();
217
+ const t = this.store.blockStates[e];
218
+ if (!t)
211
219
  return;
212
- const o = JSON.stringify(c.getConfig(this.currentNode)), n = e.syncedConfigFingerprint;
213
- e.syncedConfigFingerprint = o, n !== o && (this.pendingNodeConfigWrite || this._syncNodeConfigToStore());
220
+ const o = JSON.stringify(d.getConfig(this.currentNode)), n = t.syncedConfigFingerprint;
221
+ t.syncedConfigFingerprint = o, n !== o && (this.pendingNodeConfigWrite || this._syncNodeConfigToStore());
214
222
  }
215
223
  /** Whether the deferred write would move the node's strategyId — see the caller (SD-149916). */
216
224
  _isPendingStrategyIdChange() {
217
- const t = this.pendingNodeConfigWrite;
218
- return t ? c.getConfig(this.currentNode).strategyId !== t.updates.strategyId : !1;
225
+ const e = this.pendingNodeConfigWrite;
226
+ return e ? d.getConfig(this.currentNode).strategyId !== e.updates.strategyId : !1;
219
227
  }
220
- _capturePendingNodeConfigWrite() {
221
- const t = this.store.currentRecommendationId;
222
- if (!this.currentNode || !this.api || t === null)
228
+ _capturePendingNodeConfigWrite(e = this.store.currentRecommendationId) {
229
+ const t = e === null ? void 0 : this.store.blockStates[e];
230
+ if (!this.currentNode || !this.api || e === null || !t)
223
231
  return;
224
- const { filters: e, strategy: o, strategyId: n, size: s, nodeConfigVersion: r } = this.store.recommendationConfigs, { partnerName: l } = h();
232
+ const { filters: o, strategy: n, strategyId: s, size: i, nodeConfigVersion: l } = t.recommendationConfigs, { partnerName: a } = f();
225
233
  this.pendingNodeConfigWrite = {
226
- blockId: t,
234
+ blockId: e,
227
235
  node: this.currentNode,
228
236
  updates: {
229
- filters: e,
230
- strategy: o,
231
- strategyId: n,
232
- size: s,
233
- configVersion: r,
234
- ...l.value ? { partnerName: l.value } : {}
237
+ filters: o,
238
+ strategy: n,
239
+ strategyId: s,
240
+ size: i,
241
+ configVersion: l,
242
+ ...a.value ? { partnerName: a.value } : {}
235
243
  }
236
244
  };
237
245
  }
@@ -245,9 +253,9 @@ class at extends N {
245
253
  * @param documentModifier - The batch to accumulate into
246
254
  * @returns Whether anything was staged
247
255
  */
248
- _stagePendingNodeConfig(t) {
249
- const e = this.pendingNodeConfigWrite;
250
- return !e || !this.currentNode ? !1 : (c.stageConfig(t, this.currentNode, e.updates), !0);
256
+ _stagePendingNodeConfig(e) {
257
+ const t = this.pendingNodeConfigWrite;
258
+ return !t || !this.currentNode ? !1 : (d.stageConfig(e, this.currentNode, t.updates), !0);
251
259
  }
252
260
  /**
253
261
  * Arms the guaranteed fallback write, once the product fetch has settled. The
@@ -268,41 +276,41 @@ class at extends N {
268
276
  * snapshot the intervening re-render staled, and saveConfig swallows that failure.
269
277
  */
270
278
  _flushPendingNodeConfig() {
271
- const t = this.pendingNodeConfigWrite;
272
- if (this.pendingNodeConfigWrite = null, this._clearConfigFlush(), !t || !this.api)
279
+ const e = this.pendingNodeConfigWrite;
280
+ if (this.pendingNodeConfigWrite = null, this._clearConfigFlush(), !e || !this.api)
273
281
  return;
274
- const e = t.blockId === this.store.currentRecommendationId && this.currentNode ? this.currentNode : t.node, o = c.getConfig(e);
275
- JSON.stringify(o.filters) === JSON.stringify(t.updates.filters) && o.strategy === t.updates.strategy && o.strategyId === t.updates.strategyId && o.size === t.updates.size || c.updateConfig(this.api, e, t.updates, "Update recommendation filters");
282
+ const t = e.blockId === this.store.currentRecommendationId && this.currentNode ? this.currentNode : e.node, o = d.getConfig(t);
283
+ JSON.stringify(o.filters) === JSON.stringify(e.updates.filters) && o.strategy === e.updates.strategy && o.strategyId === e.updates.strategyId && o.size === e.updates.size || d.updateConfig(this.api, t, e.updates, "Update recommendation filters");
276
284
  }
277
285
  _syncNodeConfigToStore() {
278
286
  var n;
279
- const t = c.getConfig(this.currentNode), e = this.store.currentRecommendationId, o = e !== null && ((n = this.store.blockStates[e]) == null ? void 0 : n.isInitialized);
287
+ const e = d.getConfig(this.currentNode), t = this.store.currentRecommendationId, o = t !== null && ((n = this.store.blockStates[t]) == null ? void 0 : n.isInitialized);
280
288
  this.store.patchCurrentBlockConfig({
281
- strategy: t.strategy,
282
- strategyId: t.strategyId,
283
- nodeConfigVersion: t.configVersion,
284
- language: t.language,
285
- size: t.size,
286
- productIds: t.productIds,
287
- cardsInRow: t.cardsInRow,
288
- mobileCardsInRow: t.mobileCardsInRow,
289
- mobileLayoutEnabled: t.mobileLayoutEnabled,
290
- orientation: t.layout,
289
+ strategy: e.strategy,
290
+ strategyId: e.strategyId,
291
+ nodeConfigVersion: e.configVersion,
292
+ language: e.language,
293
+ size: e.size,
294
+ productIds: e.productIds,
295
+ cardsInRow: e.cardsInRow,
296
+ mobileCardsInRow: e.mobileCardsInRow,
297
+ mobileLayoutEnabled: e.mobileLayoutEnabled,
298
+ orientation: e.layout,
291
299
  // Only sync filters from node config during initial load.
292
300
  // After initialization, the Pinia store is the source of truth
293
301
  // for filters (edited via the filter drawer).
294
- ...o ? {} : { filters: t.filters },
295
- shuffleProducts: t.shuffleProducts,
296
- priceMovedToNextLine: t.priceMovedToNextLine,
297
- priceHideIfSameAsDiscounted: t.priceHideIfSameAsDiscounted,
302
+ ...o ? {} : { filters: e.filters },
303
+ shuffleProducts: e.shuffleProducts,
304
+ priceMovedToNextLine: e.priceMovedToNextLine,
305
+ priceHideIfSameAsDiscounted: e.priceHideIfSameAsDiscounted,
298
306
  currencySettings: {
299
- name: t.currency.code,
300
- value: t.currency.code,
301
- symbol: t.currency.symbol,
302
- alignment: t.currency.alignment === "before" ? "0" : "1",
303
- decimalCount: t.currency.decimalCount.toString(),
304
- decimalSeparator: t.currency.decimalSeparator,
305
- thousandSeparator: t.currency.thousandSeparator
307
+ name: e.currency.code,
308
+ value: e.currency.code,
309
+ symbol: e.currency.symbol,
310
+ alignment: e.currency.alignment === "before" ? "0" : "1",
311
+ decimalCount: e.currency.decimalCount.toString(),
312
+ decimalSeparator: e.currency.decimalSeparator,
313
+ thousandSeparator: e.currency.thousandSeparator
306
314
  }
307
315
  }, { triggerRefetch: !1 });
308
316
  }
@@ -315,8 +323,8 @@ class at extends N {
315
323
  * Shared by onRender() and onTemplateNodeUpdated() to avoid duplication.
316
324
  * Marks the block as initialized to prevent redundant fetches on re-selection.
317
325
  */
318
- async _fetchBlockData(t) {
319
- t !== null && this.store.markBlockInitialized(t), (await Promise.allSettled([
326
+ async _fetchBlockData(e) {
327
+ e !== null && this.store.markBlockInitialized(e), (await Promise.allSettled([
320
328
  this.store.fetchRecommendationCreateData(),
321
329
  this.store.fetchRecommendationFilters()
322
330
  ])).forEach((o, n) => {
@@ -341,49 +349,49 @@ class at extends N {
341
349
  _applySmartDefaults() {
342
350
  if (!this.currentNode || !this.api)
343
351
  return;
344
- const t = c.getConfig(this.currentNode), e = {};
352
+ const e = d.getConfig(this.currentNode), t = {};
345
353
  let o = null, n = null, s = null;
346
- if (t.currency.code === a.currency.code) {
347
- const { currencyList: r } = this.store;
348
- r.length > 0 && (r.some(
349
- (d) => d.value === `price.${a.currency.code}`
350
- ) || (o = r[0].value.replace("price.", ""), e.currency = {
351
- ...a.currency,
354
+ if (e.currency.code === c.currency.code) {
355
+ const { currencyList: i } = this.store;
356
+ i.length > 0 && (i.some(
357
+ (a) => a.value === `price.${c.currency.code}`
358
+ ) || (o = i[0].value.replace("price.", ""), t.currency = {
359
+ ...c.currency,
352
360
  code: o,
353
361
  symbol: o
354
362
  }));
355
363
  }
356
- if (t.strategy === a.strategy) {
357
- const r = this.store.getActivePredictiveAlgorithms;
358
- r.length > 0 && (r.some(
359
- (d) => d.value === a.strategy
360
- ) || (n = r[0].value, e.strategy = n));
364
+ if (e.strategy === c.strategy) {
365
+ const i = this.store.getActivePredictiveAlgorithms;
366
+ i.length > 0 && (i.some(
367
+ (a) => a.value === c.strategy
368
+ ) || (n = i[0].value, t.strategy = n));
361
369
  }
362
- if (t.language === a.language) {
363
- const r = this.store.getLanguages;
364
- r.length > 0 && (r.some(
365
- (d) => d.value === a.language
366
- ) || (s = r[0].value, e.language = s));
370
+ if (e.language === c.language) {
371
+ const i = this.store.getLanguages;
372
+ i.length > 0 && (i.some(
373
+ (a) => a.value === c.language
374
+ ) || (s = i[0].value, t.language = s));
367
375
  }
368
- !o && !n && !s || (c.updateConfig(
376
+ !o && !n && !s || (d.updateConfig(
369
377
  this.api,
370
378
  this.currentNode,
371
- e,
379
+ t,
372
380
  "Applied smart defaults"
373
- ), o && e.currency && v({
381
+ ), o && t.currency && U({
374
382
  currentNode: this.currentNode,
375
383
  documentModifier: this.api.getDocumentModifier(),
376
- currency: e.currency
384
+ currency: t.currency
377
385
  }), this.store.patchCurrentBlockConfig({
378
386
  ...o ? {
379
387
  currencySettings: {
380
388
  name: o,
381
389
  value: o,
382
390
  symbol: o,
383
- alignment: a.currency.alignment === "before" ? "0" : "1",
384
- decimalCount: a.currency.decimalCount.toString(),
385
- decimalSeparator: a.currency.decimalSeparator,
386
- thousandSeparator: a.currency.thousandSeparator
391
+ alignment: c.currency.alignment === "before" ? "0" : "1",
392
+ decimalCount: c.currency.decimalCount.toString(),
393
+ decimalSeparator: c.currency.decimalSeparator,
394
+ thousandSeparator: c.currency.thousandSeparator
387
395
  }
388
396
  } : {},
389
397
  ...n ? { strategy: n } : {},
@@ -393,16 +401,51 @@ class at extends N {
393
401
  /**
394
402
  * Reads the recommendation-id attribute from the block element within the node
395
403
  */
396
- _getRecommendationIdFromNode(t) {
397
- const e = A(t);
398
- if (!e || !("getAttribute" in e))
404
+ _getRecommendationIdFromNode(e) {
405
+ const t = v(e);
406
+ if (!t || !("getAttribute" in t))
399
407
  return null;
400
- const o = e.getAttribute(I);
408
+ const o = t.getAttribute(I);
401
409
  if (!o)
402
410
  return null;
403
411
  const n = parseInt(o);
404
412
  return Number.isNaN(n) ? null : n;
405
413
  }
414
+ /**
415
+ * Fetches and renders the block's products without the panel, carrying the
416
+ * deferred config write so both still land as one undo entry.
417
+ */
418
+ async _refreshProductsOutsidePanel() {
419
+ var a;
420
+ const e = this.store.currentRecommendationId, t = this._getRecommendationIdFromNode(this.currentNode), o = t !== null && t !== e ? t : e;
421
+ if (((a = this.pendingNodeConfigWrite) == null ? void 0 : a.blockId) !== o && this._flushPendingNodeConfig(), o === null)
422
+ return;
423
+ if (this._capturePendingNodeConfigWrite(o), o !== e) {
424
+ this._flushPendingNodeConfig();
425
+ return;
426
+ }
427
+ const n = this.pendingNodeConfigWrite;
428
+ try {
429
+ await this.store.fetchRecommendationProducts();
430
+ } catch (g) {
431
+ console.warn("Recommendation block: fetchRecommendationProducts failed", g);
432
+ }
433
+ const s = this.pendingNodeConfigWrite === n, i = s ? (n == null ? void 0 : n.updates) ?? {} : {}, l = this.store.blockStates[e];
434
+ try {
435
+ if (l && P(
436
+ e,
437
+ i,
438
+ l.recommendationProducts,
439
+ "Update recommendation configuration"
440
+ )) {
441
+ s && (this.pendingNodeConfigWrite = null, this._clearConfigFlush());
442
+ return;
443
+ }
444
+ s && this._flushPendingNodeConfig();
445
+ } catch (g) {
446
+ console.error("Recommendation block: refresh outside the panel failed", g);
447
+ }
448
+ }
406
449
  /**
407
450
  * Listen to store changes that require product refresh or regeneration.
408
451
  *
@@ -417,55 +460,55 @@ class at extends N {
417
460
  * We skip that tick and update tracking references instead.
418
461
  */
419
462
  _listenStateUpdates() {
420
- const { store: t } = this;
421
- let e = t.recommendationProducts, o = t.$state.configVersion, n = t.currentRecommendationId;
422
- this.storeUnsubscription = t.$subscribe(() => {
423
- const s = t.currentRecommendationId;
424
- if (s !== n) {
425
- n = s, e = t.recommendationProducts, o = t.$state.configVersion;
463
+ const { store: e } = this;
464
+ let t = e.recommendationProducts, o = e.currentRecommendationId;
465
+ this.seenConfigVersion = e.$state.configVersion, this.hasUnappliedConfigChange = !1, this.storeUnsubscription = e.$subscribe(() => {
466
+ const n = e.currentRecommendationId;
467
+ if (n !== o) {
468
+ o = n, t = e.recommendationProducts, this.seenConfigVersion = e.$state.configVersion, this.hasUnappliedConfigChange = !1;
426
469
  return;
427
470
  }
428
- const r = t.$state.configVersion;
429
- r !== o && (o = r, this._capturePendingNodeConfigWrite(), this._isPendingStrategyIdChange() && this._flushPendingNodeConfig(), this._debouncedFetchProducts());
430
- const l = t.recommendationProducts, d = l !== e, m = Array.isArray(l) && l.length > 0;
431
- d && m && (e = l, this._debouncedRegenerateWithProducts());
471
+ const s = e.$state.configVersion;
472
+ s !== this.seenConfigVersion && (this.seenConfigVersion = s, this.hasUnappliedConfigChange = !0, this._capturePendingNodeConfigWrite(), this._isPendingStrategyIdChange() && this._flushPendingNodeConfig(), this._debouncedFetchProducts());
473
+ const i = e.recommendationProducts, l = i !== t, a = Array.isArray(i) && i.length > 0;
474
+ l && a && (t = i, this._debouncedRegenerateWithProducts());
432
475
  });
433
476
  }
434
477
  }
435
478
  export {
436
- ut as ALGORITHM_CONTROL_ID,
437
- T as AlgorithmControl,
479
+ ue as ALGORITHM_CONTROL_ID,
480
+ S as AlgorithmControl,
438
481
  W as CONTROL_BLOCK_ID,
439
- gt as CURRENCY_CONTROL_ID,
440
- P as CurrencyControl,
441
- ft as FILTERS_CONTROL_ID,
442
- S as FiltersControl,
443
- Ct as LAYOUT_ORIENTATION_CONTROL_ID,
444
- yt as LOCALE_CONTROL_ID,
445
- O as LayoutOrientationControl,
482
+ ge as CURRENCY_CONTROL_ID,
483
+ T as CurrencyControl,
484
+ me as FILTERS_CONTROL_ID,
485
+ O as FiltersControl,
486
+ pe as LAYOUT_ORIENTATION_CONTROL_ID,
487
+ Ne as LOCALE_CONTROL_ID,
488
+ k as LayoutOrientationControl,
446
489
  L as LocaleControl,
447
- _t as PRICE_PLACEMENT_CONTROL_ID,
448
- Rt as PRODUCT_COUNT_CONTROL_ID,
449
- Tt as PRODUCT_LAYOUT_CONTROL_ID,
450
- k as PricePlacementControl,
451
- E as ProductCountControl,
452
- F as ProductLayoutControl,
453
- at as RecommendationBlockControl,
454
- St as SHUFFLE_CONTROL_ID,
455
- Lt as STRATEGY_CONTROL_ID,
456
- D as ShuffleControl,
457
- w as StrategyControl,
458
- Et as adjustProductsToSize,
459
- Ft as formatProductPrice,
460
- A as getBlockElement,
461
- Dt as getCardComposition,
462
- wt as getCurrentLayout,
463
- vt as getMainContainerTbody,
464
- B as isPartnerManagedBlock,
465
- At as regenerateMobileProductRows,
466
- U as regenerateProductRowsWithStyles,
467
- v as setCurrencyAttributes,
468
- Bt as updatePricesInPlace,
490
+ Ie as PRICE_PLACEMENT_CONTROL_ID,
491
+ be as PRODUCT_COUNT_CONTROL_ID,
492
+ Se as PRODUCT_LAYOUT_CONTROL_ID,
493
+ E as PricePlacementControl,
494
+ F as ProductCountControl,
495
+ D as ProductLayoutControl,
496
+ ce as RecommendationBlockControl,
497
+ Oe as SHUFFLE_CONTROL_ID,
498
+ Le as STRATEGY_CONTROL_ID,
499
+ w as ShuffleControl,
500
+ B as StrategyControl,
501
+ Fe as adjustProductsToSize,
502
+ De as formatProductPrice,
503
+ v as getBlockElement,
504
+ we as getCardComposition,
505
+ Be as getCurrentLayout,
506
+ Ue as getMainContainerTbody,
507
+ A as isPartnerManagedBlock,
508
+ ve as regenerateMobileProductRows,
509
+ V as regenerateProductRowsWithStyles,
510
+ U as setCurrencyAttributes,
511
+ Ae as updatePricesInPlace,
469
512
  x as updateProductContentInPlace,
470
- xt as updateSingleProductContent
513
+ xe as updateSingleProductContent
471
514
  };
@@ -19,6 +19,8 @@ export declare const provideGuidoActions: (actions: {
19
19
  }) => void;
20
20
  /**
21
21
  * Provides individual Guido action handlers
22
+ * @deprecated No consumer in src/ and not exported from library.ts — provideGuidoActions
23
+ * provides all four keys itself. Slated for deletion, see the SD-667788 dead-code ledger.
22
24
  */
23
25
  export declare const provideBackHandler: (handler: BackHandler) => void;
24
26
  export declare const provideSaveStartHandler: (handler: SaveStartHandler) => void;