@gengage/assistant-fe 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
- import { a as x, d as L, h as j, i as F, p as z, r as I, t as N } from "./api-paths-XNsAaP_N.js";
2
- import { A as q, E as T, N as D, a as k, l as H, v as $ } from "./context-BBuSsXZ9.js";
3
- import { o as W, t as J } from "./widget-base-CcNNPfdn.js";
4
- import { t as Q } from "./locale-CfqNifrU.js";
5
- import { a as V, n as Y, r as K, t as P } from "./price-formatter-xI3g9Cd4.js";
6
- import { n as X } from "./connection-warning-BjfQKyV7.js";
1
+ import { a as x, d as L, h as j, i as q, p as F, r as I, t as N } from "./api-paths-DMmq3LCM.js";
2
+ import { A as z, E as S, N as D, a as k, l as H, v as $ } from "./context-BBuSsXZ9.js";
3
+ import { o as W, t as J } from "./widget-base-CJIr0DLe.js";
4
+ import { t as K } from "./locale-CfqNifrU.js";
5
+ import { a as Q, n as V, r as Y, t as A } from "./price-formatter-xI3g9Cd4.js";
6
+ import { n as X } from "./connection-warning-CFgiLUDI.js";
7
7
  function R(e) {
8
8
  const t = [];
9
9
  for (const n of Object.values(e)) if (n.type === "ProductCard" && n.props) {
@@ -17,23 +17,23 @@ function M(e) {
17
17
  return t.includes("application/x-ndjson") || t.includes("text/event-stream");
18
18
  }
19
19
  async function Z(e, t) {
20
- const n = [], r = { onEvent: (i) => {
21
- const s = I(i);
22
- !s || s.type !== "ui_spec" || n.push(...R(s.spec.elements));
20
+ const n = [], r = { onEvent: (s) => {
21
+ const i = I(s);
22
+ !i || i.type !== "ui_spec" || n.push(...R(i.spec.elements));
23
23
  } };
24
24
  return t !== void 0 && (r.signal = t), await L(e, r), n;
25
25
  }
26
26
  async function ee(e, t, n) {
27
- const r = N("similar_products", t), i = {
27
+ const r = N("similar_products", t), s = {
28
28
  method: "POST",
29
29
  headers: { "Content-Type": "application/json" },
30
30
  body: JSON.stringify(e)
31
31
  };
32
- n !== void 0 && (i.signal = n);
33
- const s = await fetch(r, i);
34
- if (!s.ok) throw new Error(`HTTP ${s.status}: ${s.statusText}`);
35
- if (M(s)) return Z(s, n);
36
- const a = await s.text();
32
+ n !== void 0 && (s.signal = n);
33
+ const i = await fetch(r, s);
34
+ if (!i.ok) throw new Error(`HTTP ${i.status}: ${i.statusText}`);
35
+ if (M(i)) return Z(i, n);
36
+ const a = await i.text();
37
37
  if (!a) throw new Error("Empty response body from similar_products endpoint");
38
38
  try {
39
39
  return x(JSON.parse(a));
@@ -44,8 +44,8 @@ async function ee(e, t, n) {
44
44
  async function te(e, t) {
45
45
  const n = [];
46
46
  let r = null;
47
- const i = { onEvent: (s) => {
48
- const a = I(s);
47
+ const s = { onEvent: (i) => {
48
+ const a = I(i);
49
49
  if (a) {
50
50
  if (a.type === "metadata" && a.meta) {
51
51
  const d = a.meta.group_name;
@@ -61,28 +61,28 @@ async function te(e, t) {
61
61
  a.type === "ui_spec" && r && r.products.push(...R(a.spec.elements));
62
62
  }
63
63
  } };
64
- return t !== void 0 && (i.signal = t), await L(e, i), n;
64
+ return t !== void 0 && (s.signal = t), await L(e, s), n;
65
65
  }
66
66
  async function ne(e, t, n) {
67
- const r = N("product_groupings", t), i = {
67
+ const r = N("product_groupings", t), s = {
68
68
  method: "POST",
69
69
  headers: { "Content-Type": "application/json" },
70
70
  body: JSON.stringify(e)
71
71
  };
72
- n !== void 0 && (i.signal = n);
73
- const s = await fetch(r, i);
74
- if (!s.ok) throw new Error(`HTTP ${s.status}: ${s.statusText}`);
75
- if (M(s)) return te(s, n);
76
- const a = await s.text();
72
+ n !== void 0 && (s.signal = n);
73
+ const i = await fetch(r, s);
74
+ if (!i.ok) throw new Error(`HTTP ${i.status}: ${i.statusText}`);
75
+ if (M(i)) return te(i, n);
76
+ const a = await i.text();
77
77
  if (!a) return [];
78
78
  try {
79
- return F(JSON.parse(a));
79
+ return q(JSON.parse(a));
80
80
  } catch {
81
81
  throw new Error("Invalid JSON from product_groupings endpoint");
82
82
  }
83
83
  }
84
84
  function U(e) {
85
- const { product: t, index: n, discountType: r, onClick: i, onAddToCart: s, renderCard: a } = e, d = e.i18n, m = e.pricing;
85
+ const { product: t, index: n, discountType: r, onClick: s, onAddToCart: i, renderCard: a } = e, d = e.i18n, m = e.pricing;
86
86
  if (e.renderCardElement) {
87
87
  const o = e.renderCardElement(t, n);
88
88
  if (o) return o;
@@ -90,19 +90,19 @@ function U(e) {
90
90
  if (a) {
91
91
  const o = document.createElement("div");
92
92
  return o.className = "gengage-simrel-card gengage-simrel-card--custom gds-card gds-product-card gds-card-interactive", o.dataset.gengagePart = "simrel-product-card", o.innerHTML = D(a(t, n)), o.addEventListener("click", (c) => {
93
- c.target.closest(".gengage-simrel-atc") || c.target.closest(".gengage-chat-product-card-atc") || i(t);
93
+ c.target.closest(".gengage-simrel-atc") || c.target.closest(".gengage-chat-product-card-atc") || s(t);
94
94
  }), o;
95
95
  }
96
96
  const l = document.createElement("article");
97
97
  l.className = "gengage-simrel-card gengage-chat-product-card gds-card gds-product-card gds-card-interactive", l.dataset.gengagePart = "simrel-product-card", t.inStock === !1 && l.classList.add("gengage-simrel-card--out-of-stock"), l.setAttribute("role", "listitem"), l.dataset.sku = t.sku;
98
98
  const g = document.createElement("div");
99
- if (g.className = "gengage-simrel-card-image gengage-chat-product-card-img-wrapper", g.dataset.gengagePart = "simrel-product-card-image", t.imageUrl && q(t.imageUrl)) {
99
+ if (g.className = "gengage-simrel-card-image gengage-chat-product-card-img-wrapper", g.dataset.gengagePart = "simrel-product-card-image", t.imageUrl && z(t.imageUrl)) {
100
100
  const o = document.createElement("img");
101
- o.className = "gengage-chat-product-card-img", o.src = t.imageUrl, o.alt = t.name, o.loading = "lazy", Y(o), g.appendChild(o);
101
+ o.className = "gengage-chat-product-card-img", o.src = t.imageUrl, o.alt = t.name, o.loading = "lazy", V(o), g.appendChild(o);
102
102
  }
103
103
  if (r === "badge" && t.discountPercent && t.discountPercent > 0) {
104
104
  const o = document.createElement("span");
105
- o.className = "gengage-simrel-badge gengage-chat-product-card-discount-badge", o.textContent = `%${K(t.discountPercent)}`, g.appendChild(o);
105
+ o.className = "gengage-simrel-badge gengage-chat-product-card-discount-badge", o.textContent = `%${Y(t.discountPercent)}`, g.appendChild(o);
106
106
  }
107
107
  l.appendChild(g);
108
108
  const u = document.createElement("div");
@@ -113,32 +113,32 @@ function U(e) {
113
113
  const h = document.createElement("div");
114
114
  if (h.className = "gengage-simrel-card-name gengage-chat-product-card-name", h.textContent = t.name, h.title = t.name, u.appendChild(h), t.rating != null && t.rating > 0) {
115
115
  const o = document.createElement("div");
116
- if (o.className = "gengage-simrel-card-rating gengage-chat-product-card-rating", o.appendChild(V(t.rating)), t.reviewCount != null) {
116
+ if (o.className = "gengage-simrel-card-rating gengage-chat-product-card-rating", o.appendChild(Q(t.rating)), t.reviewCount != null) {
117
117
  const c = document.createElement("span");
118
118
  c.className = "gengage-simrel-card-review-count gengage-chat-product-card-review-count", c.textContent = ` (${t.reviewCount})`, o.appendChild(c);
119
119
  }
120
120
  u.appendChild(o);
121
121
  }
122
- const b = document.createElement("div");
123
- if (b.className = "gengage-simrel-card-price gengage-chat-product-card-price", t.originalPrice && t.originalPrice !== t.price && (r === "strike-through" || !r)) {
122
+ const y = document.createElement("div");
123
+ if (y.className = "gengage-simrel-card-price gengage-chat-product-card-price", t.originalPrice && t.originalPrice !== t.price && (r === "strike-through" || r === "inline" || !r)) {
124
124
  const o = document.createElement("span");
125
- o.className = "gengage-simrel-card-price-original gengage-chat-product-card-original-price", o.textContent = P(t.originalPrice, m), b.appendChild(o);
125
+ o.className = ["gengage-simrel-card-price-original", "gengage-chat-product-card-original-price"].join(" "), r === "inline" && o.classList.add("gengage-simrel-card-price-original--inline"), o.textContent = A(t.originalPrice, m), y.appendChild(o);
126
126
  }
127
127
  if (t.price && parseFloat(t.price) > 0) {
128
128
  const o = document.createElement("span");
129
- o.className = "gengage-simrel-card-price-current gengage-chat-product-card-price-current", o.textContent = P(t.price, m), b.appendChild(o);
129
+ o.className = "gengage-simrel-card-price-current gengage-chat-product-card-price-current", o.textContent = A(t.price, m), y.appendChild(o);
130
130
  }
131
- u.appendChild(b), l.appendChild(u);
131
+ u.appendChild(y), l.appendChild(u);
132
132
  const f = document.createElement("button");
133
133
  if (f.className = "gengage-simrel-card-cta gengage-chat-product-card-cta gds-btn gds-btn-secondary", f.type = "button", f.dataset.gengagePart = "simrel-product-card-cta", f.textContent = d?.ctaLabel ?? "View", f.addEventListener("click", (o) => {
134
- o.preventDefault(), o.stopPropagation(), i(t);
134
+ o.preventDefault(), o.stopPropagation(), s(t);
135
135
  }), l.appendChild(f), t.inStock === !1) {
136
136
  const o = document.createElement("div");
137
137
  o.className = "gengage-simrel-card-oos", o.textContent = d?.outOfStockLabel ?? "Out of Stock", l.appendChild(o);
138
138
  } else if (t.cartCode) {
139
139
  const o = document.createElement("button");
140
140
  o.className = "gengage-simrel-atc gengage-simrel-atc-button gds-btn gds-btn-secondary", o.type = "button", o.textContent = d?.addToCartButton ?? "Add to Cart", o.addEventListener("click", (c) => {
141
- c.preventDefault(), c.stopPropagation(), s({
141
+ c.preventDefault(), c.stopPropagation(), i({
142
142
  sku: t.sku,
143
143
  quantity: 1,
144
144
  cartCode: t.cartCode
@@ -146,7 +146,7 @@ function U(e) {
146
146
  }), l.appendChild(o);
147
147
  }
148
148
  return l.addEventListener("click", (o) => {
149
- o.target.closest(".gengage-simrel-atc") || o.target.closest(".gengage-chat-product-card-atc") || o.target.closest(".gengage-chat-product-card-cta") || i(t);
149
+ o.target.closest(".gengage-simrel-atc") || o.target.closest(".gengage-chat-product-card-atc") || o.target.closest(".gengage-chat-product-card-cta") || s(t);
150
150
  }), l;
151
151
  }
152
152
  function w(e) {
@@ -160,8 +160,8 @@ function w(e) {
160
160
  onAddToCart: e.onAddToCart
161
161
  };
162
162
  e.i18n !== void 0 && (r.i18n = e.i18n), e.discountType !== void 0 && (r.discountType = e.discountType), e.renderCard !== void 0 && (r.renderCard = e.renderCard), e.renderCardElement !== void 0 && (r.renderCardElement = e.renderCardElement);
163
- const i = U(r);
164
- t.appendChild(i);
163
+ const s = U(r);
164
+ t.appendChild(s);
165
165
  }
166
166
  return e.products.length === 0 && (t.style.display = "none", t.dataset.empty = "true"), t;
167
167
  }
@@ -172,17 +172,17 @@ function ie(e) {
172
172
  return n.style.display = "none", n.dataset.empty = "true", n;
173
173
  const r = document.createElement("div");
174
174
  r.className = "gengage-simrel-tabs gds-toolbar", r.dataset.gengagePart = "simrel-tab-bar", r.setAttribute("role", "tablist");
175
- const i = [], s = [];
175
+ const s = [], i = [];
176
176
  let a = 0;
177
177
  const d = (c) => {
178
- const y = {
178
+ const b = {
179
179
  products: c.products,
180
180
  onClick: e.onClick,
181
181
  onAddToCart: e.onAddToCart
182
182
  };
183
- return e.i18n !== void 0 && (y.i18n = e.i18n), e.discountType !== void 0 && (y.discountType = e.discountType), e.renderCard !== void 0 && (y.renderCard = e.renderCard), e.renderCardElement !== void 0 && (y.renderCardElement = e.renderCardElement), e.columns !== void 0 && (y.columns = e.columns), y;
184
- }, m = (c, y = !1) => {
185
- if (y && c !== a && e.onGroupingActivate) {
183
+ return e.i18n !== void 0 && (b.i18n = e.i18n), e.discountType !== void 0 && (b.discountType = e.discountType), e.renderCard !== void 0 && (b.renderCard = e.renderCard), e.renderCardElement !== void 0 && (b.renderCardElement = e.renderCardElement), e.columns !== void 0 && (b.columns = e.columns), b;
184
+ }, m = (c, b = !1) => {
185
+ if (b && c !== a && e.onGroupingActivate) {
186
186
  const p = e.groups[c];
187
187
  e.onGroupingActivate({
188
188
  grouping_label: p.name,
@@ -190,27 +190,27 @@ function ie(e) {
190
190
  });
191
191
  }
192
192
  a = c;
193
- for (let p = 0; p < i.length; p++) {
193
+ for (let p = 0; p < s.length; p++) {
194
194
  const v = p === c;
195
- i[p].classList.toggle("gengage-simrel-tab--active", v), i[p].setAttribute("aria-selected", String(v)), i[p].tabIndex = v ? 0 : -1;
195
+ s[p].classList.toggle("gengage-simrel-tab--active", v), s[p].setAttribute("aria-selected", String(v)), s[p].tabIndex = v ? 0 : -1;
196
196
  }
197
- const S = e.groups[c], _ = s[c];
197
+ const T = e.groups[c], _ = i[c];
198
198
  _.innerHTML = "";
199
- const C = w(d(S));
199
+ const C = w(d(T));
200
200
  _.appendChild(C);
201
- for (let p = 0; p < s.length; p++) {
201
+ for (let p = 0; p < i.length; p++) {
202
202
  const v = p === c;
203
- s[p].style.display = v ? "" : "none", s[p].tabIndex = v ? 0 : -1;
203
+ i[p].style.display = v ? "" : "none", i[p].tabIndex = v ? 0 : -1;
204
204
  }
205
205
  };
206
206
  for (let c = 0; c < e.groups.length; c++) {
207
- const y = e.groups[c], S = `gengage-simrel-tab-${t}-${c}`, _ = `gengage-simrel-panel-${t}-${c}`, C = document.createElement("button");
208
- C.className = "gengage-simrel-tab gds-tab", C.type = "button", C.dataset.gengagePart = "simrel-tab", C.id = S, C.textContent = y.name, C.setAttribute("role", "tab"), C.setAttribute("aria-controls", _), C.setAttribute("aria-selected", String(c === 0)), C.tabIndex = c === 0 ? 0 : -1, c === 0 && C.classList.add("gengage-simrel-tab--active"), C.addEventListener("click", () => m(c, !0)), C.addEventListener("keydown", (v) => {
207
+ const b = e.groups[c], T = `gengage-simrel-tab-${t}-${c}`, _ = `gengage-simrel-panel-${t}-${c}`, C = document.createElement("button");
208
+ C.className = "gengage-simrel-tab gds-tab", C.type = "button", C.dataset.gengagePart = "simrel-tab", C.id = T, C.textContent = b.name, C.setAttribute("role", "tab"), C.setAttribute("aria-controls", _), C.setAttribute("aria-selected", String(c === 0)), C.tabIndex = c === 0 ? 0 : -1, c === 0 && C.classList.add("gengage-simrel-tab--active"), C.addEventListener("click", () => m(c, !0)), C.addEventListener("keydown", (v) => {
209
209
  let E = -1;
210
- v.key === "ArrowRight" || v.key === "ArrowDown" ? E = (c + 1) % e.groups.length : v.key === "ArrowLeft" || v.key === "ArrowUp" ? E = (c - 1 + e.groups.length) % e.groups.length : v.key === "Home" ? E = 0 : v.key === "End" && (E = e.groups.length - 1), E >= 0 && (v.preventDefault(), m(E, !0), i[E].focus());
211
- }), i.push(C), r.appendChild(C);
210
+ v.key === "ArrowRight" || v.key === "ArrowDown" ? E = (c + 1) % e.groups.length : v.key === "ArrowLeft" || v.key === "ArrowUp" ? E = (c - 1 + e.groups.length) % e.groups.length : v.key === "Home" ? E = 0 : v.key === "End" && (E = e.groups.length - 1), E >= 0 && (v.preventDefault(), m(E, !0), s[E].focus());
211
+ }), s.push(C), r.appendChild(C);
212
212
  const p = document.createElement("div");
213
- p.className = "gengage-simrel-tab-panel", p.dataset.gengagePart = "simrel-tab-panel", p.id = _, p.setAttribute("role", "tabpanel"), p.setAttribute("aria-labelledby", S), p.tabIndex = c === 0 ? 0 : -1, c !== 0 && (p.style.display = "none"), s.push(p);
213
+ p.className = "gengage-simrel-tab-panel", p.dataset.gengagePart = "simrel-tab-panel", p.id = _, p.setAttribute("role", "tabpanel"), p.setAttribute("aria-labelledby", T), p.tabIndex = c === 0 ? 0 : -1, c !== 0 && (p.style.display = "none"), i.push(p);
214
214
  }
215
215
  const l = document.createElement("button");
216
216
  l.type = "button", l.className = "gengage-simrel-tabs-arrow gengage-simrel-tabs-arrow--left", l.setAttribute("aria-label", e.i18n?.scrollTabsLeft ?? "Scroll tabs left"), l.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg>';
@@ -229,18 +229,18 @@ function ie(e) {
229
229
  });
230
230
  });
231
231
  const h = () => {
232
- const c = r.scrollLeft <= 4, y = r.scrollLeft + r.clientWidth >= r.scrollWidth - 4;
233
- l.style.display = c ? "none" : "", g.style.display = y ? "none" : "", r.classList.toggle("gengage-simrel-tabs--peek-right", !y), r.classList.toggle("gengage-simrel-tabs--peek-left", !c);
232
+ const c = r.scrollLeft <= 4, b = r.scrollLeft + r.clientWidth >= r.scrollWidth - 4;
233
+ l.style.display = c ? "none" : "", g.style.display = b ? "none" : "", r.classList.toggle("gengage-simrel-tabs--peek-right", !b), r.classList.toggle("gengage-simrel-tabs--peek-left", !c);
234
234
  };
235
235
  r.addEventListener("scroll", h, { passive: !0 }), typeof ResizeObserver < "u" && new ResizeObserver(h).observe(r), l.style.display = "none", g.style.display = "none", requestAnimationFrame(h);
236
- const b = document.createElement("div");
237
- b.className = "gengage-simrel-tabs-wrapper", b.appendChild(l), b.appendChild(r), b.appendChild(g), n.appendChild(b);
238
- const f = s[0], o = w(d(e.groups[0]));
236
+ const y = document.createElement("div");
237
+ y.className = "gengage-simrel-tabs-wrapper", y.appendChild(l), y.appendChild(r), y.appendChild(g), n.appendChild(y);
238
+ const f = i[0], o = w(d(e.groups[0]));
239
239
  f.appendChild(o);
240
- for (const c of s) n.appendChild(c);
240
+ for (const c of i) n.appendChild(c);
241
241
  return n;
242
242
  }
243
- function A(e) {
243
+ function P(e) {
244
244
  if (!e || typeof e != "object") return null;
245
245
  const t = e;
246
246
  if (typeof t.sku != "string" || typeof t.name != "string" || typeof t.url != "string") return null;
@@ -250,10 +250,10 @@ function A(e) {
250
250
  url: t.url
251
251
  }, r = t.imageUrl;
252
252
  typeof r == "string" && (n.imageUrl = r);
253
- const i = t.price;
254
- typeof i == "string" && (n.price = i);
255
- const s = t.originalPrice;
256
- typeof s == "string" && (n.originalPrice = s);
253
+ const s = t.price;
254
+ typeof s == "string" && (n.price = s);
255
+ const i = t.originalPrice;
256
+ typeof i == "string" && (n.originalPrice = i);
257
257
  const a = t.discountPercent;
258
258
  typeof a == "number" && (n.discountPercent = a);
259
259
  const d = t.brand;
@@ -273,19 +273,19 @@ function se(e) {
273
273
  if (!e || typeof e != "object") return null;
274
274
  const t = e, n = t.title, r = t.type;
275
275
  if (typeof n != "string" || typeof r != "string") return null;
276
- const i = {
276
+ const s = {
277
277
  title: n,
278
278
  type: r
279
279
  };
280
- return t.payload !== void 0 && (i.payload = t.payload), i;
280
+ return t.payload !== void 0 && (s.payload = t.payload), s;
281
281
  }
282
282
  var G = {
283
283
  ProductGrid: ({ element: e, renderElement: t, context: n }) => {
284
284
  const r = document.createElement("div");
285
285
  r.className = "gengage-simrel-grid", r.setAttribute("role", "list");
286
- const i = e.props?.columns;
287
- let s;
288
- typeof i == "number" && Number.isFinite(i) && i > 0 ? s = Math.floor(i) : typeof n.gridColumns == "number" && Number.isFinite(n.gridColumns) && n.gridColumns > 0 && (s = Math.floor(n.gridColumns)), s !== void 0 && r.style.setProperty("--gengage-simrel-columns", String(s));
286
+ const s = e.props?.columns;
287
+ let i;
288
+ typeof s == "number" && Number.isFinite(s) && s > 0 ? i = Math.floor(s) : typeof n.gridColumns == "number" && Number.isFinite(n.gridColumns) && n.gridColumns > 0 && (i = Math.floor(n.gridColumns)), i !== void 0 && r.style.setProperty("--gengage-simrel-columns", String(i));
289
289
  for (const a of e.children ?? []) {
290
290
  const d = t(a);
291
291
  d && r.appendChild(d);
@@ -297,11 +297,11 @@ var G = {
297
297
  return r;
298
298
  },
299
299
  ProductCard: ({ element: e, context: t }) => {
300
- const n = A(e.props?.product ?? e.props);
300
+ const n = P(e.props?.product ?? e.props);
301
301
  if (!n) return null;
302
- const r = e.props?.index, i = typeof r == "number" && Number.isFinite(r) ? r : 0, s = e.props?.discountType, a = s === "strike-through" || s === "badge" ? s : t.discountType, d = {
302
+ const r = e.props?.index, s = typeof r == "number" && Number.isFinite(r) ? r : 0, i = e.props?.discountType, a = i === "strike-through" || i === "badge" || i === "inline" ? i : t.discountType, d = {
303
303
  product: n,
304
- index: i,
304
+ index: s,
305
305
  onClick: t.onClick,
306
306
  onAddToCart: t.onAddToCart,
307
307
  i18n: t.i18n
@@ -318,7 +318,7 @@ var G = {
318
318
  if (typeof d.name != "string") continue;
319
319
  const m = [];
320
320
  if (Array.isArray(d.products)) for (const g of d.products) {
321
- const u = A(g);
321
+ const u = P(g);
322
322
  u && m.push(u);
323
323
  }
324
324
  const l = {
@@ -327,13 +327,13 @@ var G = {
327
327
  };
328
328
  typeof d.highlight == "string" && (l.highlight = d.highlight), r.push(l);
329
329
  }
330
- const i = {
330
+ const s = {
331
331
  groups: r,
332
332
  onClick: t.onClick,
333
333
  onAddToCart: t.onAddToCart,
334
334
  i18n: t.i18n
335
- }, s = e.props?.columns;
336
- return typeof s == "number" && Number.isFinite(s) && s > 0 ? i.columns = Math.floor(s) : typeof t.gridColumns == "number" && Number.isFinite(t.gridColumns) && t.gridColumns > 0 && (i.columns = Math.floor(t.gridColumns)), t.discountType !== void 0 && (i.discountType = t.discountType), t.renderCard !== void 0 && (i.renderCard = t.renderCard), t.renderCardElement !== void 0 && (i.renderCardElement = t.renderCardElement), t.onGroupingActivate !== void 0 && (i.onGroupingActivate = t.onGroupingActivate), ie(i);
335
+ }, i = e.props?.columns;
336
+ return typeof i == "number" && Number.isFinite(i) && i > 0 ? s.columns = Math.floor(i) : typeof t.gridColumns == "number" && Number.isFinite(t.gridColumns) && t.gridColumns > 0 && (s.columns = Math.floor(t.gridColumns)), t.discountType !== void 0 && (s.discountType = t.discountType), t.renderCard !== void 0 && (s.renderCard = t.renderCard), t.renderCardElement !== void 0 && (s.renderCardElement = t.renderCardElement), t.onGroupingActivate !== void 0 && (s.onGroupingActivate = t.onGroupingActivate), ie(s);
337
337
  },
338
338
  EmptyState: ({ element: e, context: t }) => {
339
339
  const n = document.createElement("div");
@@ -344,25 +344,25 @@ var G = {
344
344
  AddToCartButton: ({ element: e, context: t }) => {
345
345
  const n = e.props?.sku, r = e.props?.cartCode;
346
346
  if (typeof n != "string" || typeof r != "string") return null;
347
- const i = document.createElement("button");
348
- i.className = "gengage-simrel-atc gengage-chat-product-card-cta", i.type = "button";
349
- const s = e.props?.label;
350
- return i.textContent = typeof s == "string" ? s : t.i18n.addToCartButton, i.addEventListener("click", (a) => {
347
+ const s = document.createElement("button");
348
+ s.className = "gengage-simrel-atc gengage-chat-product-card-cta", s.type = "button";
349
+ const i = e.props?.label;
350
+ return s.textContent = typeof i == "string" ? i : t.i18n.addToCartButton, s.addEventListener("click", (a) => {
351
351
  a.preventDefault(), a.stopPropagation(), t.onAddToCart({
352
352
  sku: n,
353
353
  quantity: 1,
354
354
  cartCode: r
355
355
  });
356
- }), i;
356
+ }), s;
357
357
  },
358
358
  QuickActions: ({ element: e, context: t }) => {
359
359
  const n = document.createElement("div");
360
360
  n.className = "gengage-simrel-quick-actions";
361
361
  const r = e.props?.actions;
362
362
  if (!Array.isArray(r) || !t.onAction) return n;
363
- for (const i of r) {
364
- if (!i || typeof i != "object") continue;
365
- const s = i, a = s.label, d = se(s.action);
363
+ for (const s of r) {
364
+ if (!s || typeof s != "object") continue;
365
+ const i = s, a = i.label, d = se(i.action);
366
366
  if (typeof a != "string" || !d) continue;
367
367
  const m = document.createElement("button");
368
368
  m.className = "gengage-simrel-quick-action", m.type = "button", m.textContent = a, m.addEventListener("click", (l) => {
@@ -375,8 +375,8 @@ var G = {
375
375
  if (!e.children || e.children.length === 0) return null;
376
376
  const n = document.createElement("div");
377
377
  for (const r of e.children) {
378
- const i = t(r);
379
- i && n.appendChild(i);
378
+ const s = t(r);
379
+ s && n.appendChild(s);
380
380
  }
381
381
  return n;
382
382
  };
@@ -431,14 +431,14 @@ function ue(e) {
431
431
  }
432
432
  var pe = class extends J {
433
433
  constructor(...e) {
434
- super(...e), this._abortController = null, this._contentEl = null, this._lastResultCount = -1, this._i18n = B;
434
+ super(...e), this._abortController = null, this._contentEl = null, this._lastResultCount = -1, this._i18n = B, this._pendingAddToCartKeys = /* @__PURE__ */ new Set();
435
435
  }
436
436
  async init(e) {
437
437
  if (!this.isInitialised && (e.mountTarget === void 0 || e.mountTarget === null)) throw new Error("[gengage] SimRel mountTarget is required. Provide a merchant-owned mount before initializing.");
438
438
  await super.init(e);
439
439
  }
440
440
  async onInit(e) {
441
- this._i18n = this._resolveI18n(e), this._contentEl = document.createElement("div"), this._contentEl.className = "gengage-simrel-container", this._contentEl.dataset.gengagePart = "simrel-container", this._contentEl.lang = Q(e.locale);
441
+ this._i18n = this._resolveI18n(e), this._contentEl = document.createElement("div"), this._contentEl.className = "gengage-simrel-container", this._contentEl.dataset.gengagePart = "simrel-container", this._contentEl.lang = K(e.locale);
442
442
  const t = this._clampGridColumns(e.gridColumns);
443
443
  t !== void 0 && this._contentEl.style.setProperty("--gengage-simrel-columns", String(t)), this.root.appendChild(this._contentEl), this._lastSku = e.sku, await this._fetchAndRender(e.sku), $("simrel");
444
444
  }
@@ -471,8 +471,23 @@ var pe = class extends J {
471
471
  productName: e.name
472
472
  }), this.config.onProductNavigate?.(e.url, e.sku, n);
473
473
  }
474
- _handleAddToCart(e) {
475
- H(e.sku, e.quantity), this.config.onAddToCart?.(e), k("gengage:similar:add-to-cart", e);
474
+ async _handleAddToCart(e) {
475
+ const t = `${e.sku}\0${e.cartCode}\0${e.quantity}`;
476
+ if (!this._pendingAddToCartKeys.has(t)) {
477
+ this._pendingAddToCartKeys.add(t);
478
+ try {
479
+ if (this.config.onAddToCart === void 0) return;
480
+ try {
481
+ await Promise.resolve(this.config.onAddToCart(e));
482
+ } catch (n) {
483
+ console.error("[gengage] simrel onAddToCart", n);
484
+ return;
485
+ }
486
+ H(e.sku, e.quantity), k("gengage:similar:add-to-cart", e);
487
+ } finally {
488
+ this._pendingAddToCartKeys.delete(t);
489
+ }
490
+ }
476
491
  }
477
492
  _abort() {
478
493
  this._abortController?.abort(), this._abortController = null;
@@ -499,15 +514,15 @@ var pe = class extends J {
499
514
  this._abortController = t;
500
515
  const n = t.signal;
501
516
  let r = !1;
502
- const i = setTimeout(() => {
517
+ const s = setTimeout(() => {
503
518
  r = !0, t.abort();
504
519
  }, this._resolveRequestTimeoutMs());
505
- if (n.addEventListener("abort", () => clearTimeout(i), { once: !0 }), !this._contentEl) return;
520
+ if (n.addEventListener("abort", () => clearTimeout(s), { once: !0 }), !this._contentEl) return;
506
521
  this._contentEl.innerHTML = "", this._contentEl.style.display = "";
507
- const s = document.createElement("div");
508
- s.className = "gengage-simrel-loading", s.dataset.gengagePart = "simrel-loading";
522
+ const i = document.createElement("div");
523
+ i.className = "gengage-simrel-loading", i.dataset.gengagePart = "simrel-loading";
509
524
  const a = document.createElement("div");
510
- a.className = "gengage-simrel-spinner", a.dataset.gengagePart = "simrel-loading-spinner", s.appendChild(a), this._contentEl.appendChild(s);
525
+ a.className = "gengage-simrel-spinner", a.dataset.gengagePart = "simrel-loading-spinner", i.appendChild(a), this._contentEl.appendChild(i);
511
526
  const d = { middlewareUrl: this.config.middlewareUrl }, m = X({
512
527
  source: "simrel",
513
528
  locale: this.config.locale
@@ -523,7 +538,7 @@ var pe = class extends J {
523
538
  const g = await ee(l, d, n);
524
539
  if (this._lastResultCount = g.length, !this._contentEl) return;
525
540
  if (this._contentEl.innerHTML = "", g.length > 0 && this.config.enableProductGroupings !== !1) try {
526
- const u = g.map((f) => f.sku), h = new Map(g.map((f) => [f.sku, f])), b = (await ne({
541
+ const u = g.map((f) => f.sku), h = new Map(g.map((f) => [f.sku, f])), y = (await ne({
527
542
  account_id: this.config.accountId,
528
543
  session_id: this.config.session?.sessionId ?? "",
529
544
  correlation_id: this.config.session?.sessionId ?? "",
@@ -535,9 +550,9 @@ var pe = class extends J {
535
550
  ...o
536
551
  })).filter((o) => typeof o.sku == "string" && typeof o.name == "string" && typeof o.url == "string")
537
552
  })).filter((f) => f.products.length > 0);
538
- if (b.length > 0 && this._contentEl) {
539
- const f = this._buildGroupsSpec(b), o = this._renderUISpec(f);
540
- this._contentEl.appendChild(o), T("simrel"), this._emitSimilarProductsImpression(b.reduce((c, y) => c + y.products.length, 0), !0);
553
+ if (y.length > 0 && this._contentEl) {
554
+ const f = this._buildGroupsSpec(y), o = this._renderUISpec(f);
555
+ this._contentEl.appendChild(o), S("simrel"), this._emitSimilarProductsImpression(y.reduce((c, b) => c + b.products.length, 0), !0);
541
556
  return;
542
557
  }
543
558
  } catch {
@@ -547,7 +562,7 @@ var pe = class extends J {
547
562
  const u = this._buildProductsSpec(g), h = this._renderUISpec(u);
548
563
  this._contentEl.appendChild(h);
549
564
  }
550
- g.length > 0 && T("simrel"), this._emitSimilarProductsImpression(g.length, !1);
565
+ g.length > 0 && S("simrel"), this._emitSimilarProductsImpression(g.length, !1);
551
566
  } catch (l) {
552
567
  const g = ue(l);
553
568
  if (g && this._isSuperseded(n)) return;
@@ -561,13 +576,13 @@ var pe = class extends J {
561
576
  u.className = "gengage-simrel-error";
562
577
  const h = document.createElement("span");
563
578
  h.textContent = this._i18n.errorLoadingMessage, u.appendChild(h);
564
- const b = document.createElement("button");
565
- b.className = "gengage-simrel-retry", b.textContent = this._i18n.retryButtonText, b.addEventListener("click", () => {
579
+ const y = document.createElement("button");
580
+ y.className = "gengage-simrel-retry", y.textContent = this._i18n.retryButtonText, y.addEventListener("click", () => {
566
581
  this._fetchAndRender(this.config.sku);
567
- }), u.appendChild(b), this._contentEl.appendChild(u);
582
+ }), u.appendChild(y), this._contentEl.appendChild(u);
568
583
  }
569
584
  } finally {
570
- clearTimeout(i), m();
585
+ clearTimeout(s), m();
571
586
  }
572
587
  }
573
588
  _clampGridColumns(e) {
@@ -581,12 +596,14 @@ var pe = class extends J {
581
596
  };
582
597
  }
583
598
  _resolveUISpecRegistry() {
584
- return z(oe(), this.config.renderer?.registry);
599
+ return F(oe(), this.config.renderer?.registry);
585
600
  }
586
601
  _buildRenderContext() {
587
602
  const e = this.config.renderCard, t = {
588
603
  onClick: (r) => this._handleProductClick(r),
589
- onAddToCart: (r) => this._handleAddToCart(r),
604
+ onAddToCart: (r) => {
605
+ this._handleAddToCart(r);
606
+ },
590
607
  onGroupingActivate: (r) => {
591
608
  k("gengage:similar:grouping-click", {
592
609
  grouping_label: r.grouping_label,
@@ -601,28 +618,28 @@ var pe = class extends J {
601
618
  return n !== void 0 && (t.gridColumns = n), t;
602
619
  }
603
620
  _renderUISpec(e) {
604
- const t = this._resolveUISpecRegistry(), n = this._buildRenderContext(), r = this.config.renderer?.unknownRenderer ?? O, i = (a, d) => ae(a, d, t, r), s = this.config.renderer?.renderUISpec;
605
- return s ? s(e, n, {
621
+ const t = this._resolveUISpecRegistry(), n = this._buildRenderContext(), r = this.config.renderer?.unknownRenderer ?? O, s = (a, d) => ae(a, d, t, r), i = this.config.renderer?.renderUISpec;
622
+ return i ? i(e, n, {
606
623
  registry: t,
607
624
  unknownRenderer: r,
608
- defaultRender: i
609
- }) : i(e, n);
625
+ defaultRender: s
626
+ }) : s(e, n);
610
627
  }
611
628
  _buildProductsSpec(e) {
612
629
  const t = {}, n = [];
613
- for (let s = 0; s < e.length; s++) {
614
- const a = e[s], d = `product-${s}`;
630
+ for (let i = 0; i < e.length; i++) {
631
+ const a = e[i], d = `product-${i}`;
615
632
  n.push(d), t[d] = {
616
633
  type: "ProductCard",
617
634
  props: {
618
635
  product: a,
619
- index: s,
636
+ index: i,
620
637
  discountType: this.config.discountType
621
638
  }
622
639
  };
623
640
  }
624
- const r = { layout: "grid" }, i = this._clampGridColumns(this.config.gridColumns);
625
- return i !== void 0 && (r.columns = i), t.root = {
641
+ const r = { layout: "grid" }, s = this._clampGridColumns(this.config.gridColumns);
642
+ return s !== void 0 && (r.columns = s), t.root = {
626
643
  type: "ProductGrid",
627
644
  props: r,
628
645
  children: n
@@ -1,8 +1,8 @@
1
- import { d as x, h as Q, p as R, r as N, t as H } from "./api-paths-XNsAaP_N.js";
1
+ import { d as x, h as Q, p as R, r as N, t as H } from "./api-paths-DMmq3LCM.js";
2
2
  import { A as O, D as U, E as j, a as q, v as M } from "./context-BBuSsXZ9.js";
3
- import { o as F, t as W } from "./widget-base-CcNNPfdn.js";
3
+ import { o as F, t as W } from "./widget-base-CJIr0DLe.js";
4
4
  import { t as A } from "./locale-CfqNifrU.js";
5
- import { n as D } from "./connection-warning-BjfQKyV7.js";
5
+ import { n as D } from "./connection-warning-CFgiLUDI.js";
6
6
  async function z(e, t, n) {
7
7
  const o = H("launcher_action", t), i = {
8
8
  uiSpecs: [],