@gengage/assistant-fe 0.1.1 → 0.1.2

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 (48) hide show
  1. package/dist/chat/components/ChatDrawer.d.ts +5 -1
  2. package/dist/chat/components/ChatDrawer.d.ts.map +1 -1
  3. package/dist/chat/components/ProactivePopup.d.ts +7 -0
  4. package/dist/chat/components/ProactivePopup.d.ts.map +1 -1
  5. package/dist/chat/index.d.ts +6 -0
  6. package/dist/chat/index.d.ts.map +1 -1
  7. package/dist/chat/session-persistence.d.ts +7 -3
  8. package/dist/chat/session-persistence.d.ts.map +1 -1
  9. package/dist/chat/types.d.ts +6 -0
  10. package/dist/chat/types.d.ts.map +1 -1
  11. package/dist/chat.cjs +1 -1
  12. package/dist/chat.iife.js +9 -9
  13. package/dist/chat.iife.js.map +1 -1
  14. package/dist/chat.js +2 -2
  15. package/dist/common/streaming.d.ts +6 -0
  16. package/dist/common/streaming.d.ts.map +1 -1
  17. package/dist/common/v1-protocol-adapter.d.ts.map +1 -1
  18. package/dist/common/widget-base.d.ts +1 -0
  19. package/dist/common/widget-base.d.ts.map +1 -1
  20. package/dist/common.cjs +1 -1
  21. package/dist/common.js +4 -4
  22. package/dist/{index-CmlYMq-h.js → index-CXbH-cw8.js} +741 -622
  23. package/dist/index-CXbH-cw8.js.map +1 -0
  24. package/dist/index-DHfTHscz.cjs +13 -0
  25. package/dist/index-DHfTHscz.cjs.map +1 -0
  26. package/dist/index.cjs +1 -1
  27. package/dist/index.js +2 -2
  28. package/dist/qna/components/renderUISpec.d.ts.map +1 -1
  29. package/dist/qna.cjs +1 -1
  30. package/dist/qna.cjs.map +1 -1
  31. package/dist/qna.iife.js +6 -6
  32. package/dist/qna.iife.js.map +1 -1
  33. package/dist/qna.js +8 -7
  34. package/dist/qna.js.map +1 -1
  35. package/dist/{schemas-SGuXpngy.js → schemas-CPkzbgia.js} +1034 -1020
  36. package/dist/schemas-CPkzbgia.js.map +1 -0
  37. package/dist/{schemas-DbbfBnZe.cjs → schemas-tCxs1sED.cjs} +16 -16
  38. package/dist/schemas-tCxs1sED.cjs.map +1 -0
  39. package/dist/simrel.cjs +1 -1
  40. package/dist/simrel.iife.js +6 -6
  41. package/dist/simrel.iife.js.map +1 -1
  42. package/dist/simrel.js +1 -1
  43. package/package.json +3 -2
  44. package/dist/index-CmlYMq-h.js.map +0 -1
  45. package/dist/index-DK4lqi85.cjs +0 -13
  46. package/dist/index-DK4lqi85.cjs.map +0 -1
  47. package/dist/schemas-DbbfBnZe.cjs.map +0 -1
  48. package/dist/schemas-SGuXpngy.js.map +0 -1
package/dist/simrel.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./schemas-DbbfBnZe.cjs"),C=require("./quantity-stepper-UbAp53Ow.cjs");function S(n){const e=n.headers.get("Content-Type")??"";return e.includes("application/x-ndjson")||e.includes("text/event-stream")}async function I(n,e){const t=[],r={onEvent:i=>{const s=c.adaptV1Event(i);if(!(!s||s.type!=="ui_spec")){for(const a of Object.values(s.spec.elements))if(a.type==="ProductCard"&&a.props){const u=a.props.product??a.props;typeof u.sku=="string"&&typeof u.name=="string"&&t.push(u)}}}};return e!==void 0&&(r.signal=e),await c.consumeStream(n,r),t}async function N(n,e,t){const r=c.buildChatEndpointUrl("similar_products",e),i={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)};t!==void 0&&(i.signal=t);const s=await fetch(r,i);if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);if(S(s))return I(s,t);const a=await s.text();if(!a)return[];try{return c.normalizeSimilarProductsResponse(JSON.parse(a))}catch{throw new Error("Invalid JSON from similar_products endpoint")}}async function U(n,e){const t=[];let r=null;const i={onEvent:s=>{const a=c.adaptV1Event(s);if(a){if(a.type==="metadata"&&a.meta){const u=a.meta.group_name;if(typeof u=="string"){r={name:u,products:[]};const l=a.meta.highlight;typeof l=="string"&&(r.highlight=l),t.push(r)}}if(a.type==="ui_spec"&&r){for(const u of Object.values(a.spec.elements))if(u.type==="ProductCard"&&u.props){const l=u.props.product??u.props;typeof l.sku=="string"&&typeof l.name=="string"&&r.products.push(l)}}}}};return e!==void 0&&(i.signal=e),await c.consumeStream(n,i),t}async function x(n,e,t){const r=c.buildChatEndpointUrl("product_groupings",e),i={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)};t!==void 0&&(i.signal=t);const s=await fetch(r,i);if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);if(S(s))return U(s,t);const a=await s.text();if(!a)return[];try{return c.normalizeProductGroupingsResponse(JSON.parse(a))}catch{throw new Error("Invalid JSON from product_groupings endpoint")}}function k(n){const{product:e,index:t,discountType:r,onClick:i,onAddToCart:s,renderCard:a}=n,u=n.i18n,l=n.pricing;if(a){const o=document.createElement("div");return o.className="gengage-simrel-card gengage-simrel-card--custom",o.innerHTML=C.sanitizeHtml(a(e,t)),o.addEventListener("click",p=>{p.target.closest(".gengage-simrel-atc")||i(e)}),o}const g=document.createElement("article");g.className="gengage-simrel-card",g.setAttribute("role","listitem"),g.dataset.sku=e.sku;const d=document.createElement("div");if(d.className="gengage-simrel-card-image",e.imageUrl&&C.isSafeImageUrl(e.imageUrl)){const o=document.createElement("img");o.src=e.imageUrl,o.alt=e.name,o.loading="lazy",C.addImageErrorHandler(o),d.appendChild(o)}if(r==="badge"&&e.discountPercent&&e.discountPercent>0){const o=document.createElement("span");o.className="gengage-simrel-badge",o.textContent=`%${C.clampDiscount(e.discountPercent)}`,d.appendChild(o)}g.appendChild(d);const m=document.createElement("div");if(m.className="gengage-simrel-card-info",e.brand){const o=document.createElement("div");o.className="gengage-simrel-card-brand",o.textContent=e.brand,m.appendChild(o)}const f=document.createElement("div");if(f.className="gengage-simrel-card-name",f.textContent=e.name,m.appendChild(f),e.rating!=null&&e.rating>0){const o=document.createElement("div");if(o.className="gengage-simrel-card-rating",o.textContent=C.renderStarRating(e.rating),e.reviewCount!=null){const p=document.createElement("span");p.className="gengage-simrel-card-review-count",p.textContent=` (${e.reviewCount})`,o.appendChild(p)}m.appendChild(o)}const h=document.createElement("div");if(h.className="gengage-simrel-card-price",e.originalPrice&&e.originalPrice!==e.price&&(r==="strike-through"||!r)){const o=document.createElement("span");o.className="gengage-simrel-card-price-original",o.textContent=C.formatPrice(e.originalPrice,l),h.appendChild(o)}if(e.price){const o=document.createElement("span");o.className="gengage-simrel-card-price-current",o.textContent=C.formatPrice(e.price,l),h.appendChild(o)}if(m.appendChild(h),g.appendChild(m),e.cartCode){const o=e.cartCode,p=C.createQuantityStepper({compact:!1,label:u?.addToCartButton??"Sepete Ekle",onSubmit:y=>{s({sku:e.sku,quantity:y,cartCode:o})}});p.classList.add("gengage-simrel-atc"),g.appendChild(p)}return g.addEventListener("click",o=>{o.target.closest(".gengage-simrel-atc")||i(e)}),g}function _(n){const e=document.createElement("div");e.className="gengage-simrel-grid",e.setAttribute("role","list"),e.setAttribute("aria-label",n.i18n?.similarProductsAriaLabel??"Similar products"),n.columns&&e.style.setProperty("--gengage-simrel-columns",String(n.columns));for(let t=0;t<n.products.length;t++){const i={product:n.products[t],index:t,onClick:n.onClick,onAddToCart:n.onAddToCart};n.i18n!==void 0&&(i.i18n=n.i18n),n.discountType!==void 0&&(i.discountType=n.discountType),n.renderCard!==void 0&&(i.renderCard=n.renderCard);const s=k(i);e.appendChild(s)}if(n.products.length===0){const t=document.createElement("div");t.className="gengage-simrel-empty",t.textContent=n.i18n?.emptyStateMessage??"Benzer ürün bulunamadı.",e.appendChild(t)}return e}let L=0;function j(n){const e=L++,t=document.createElement("div");if(t.className="gengage-simrel-groups",n.groups.length===0){const d=document.createElement("div");return d.className="gengage-simrel-empty",d.textContent=n.i18n?.emptyStateMessage??"Benzer ürün bulunamadı.",t.appendChild(d),t}const r=document.createElement("div");r.className="gengage-simrel-tabs",r.setAttribute("role","tablist");const i=[],s=[],a=d=>{const m={products:d.products,onClick:n.onClick,onAddToCart:n.onAddToCart};return n.i18n!==void 0&&(m.i18n=n.i18n),n.discountType!==void 0&&(m.discountType=n.discountType),n.renderCard!==void 0&&(m.renderCard=n.renderCard),m},u=d=>{for(let o=0;o<i.length;o++){const p=o===d;i[o].classList.toggle("gengage-simrel-tab--active",p),i[o].setAttribute("aria-selected",String(p)),i[o].tabIndex=p?0:-1}const m=n.groups[d],f=s[d];f.innerHTML="";const h=_(a(m));f.appendChild(h);for(let o=0;o<s.length;o++){const p=o===d;s[o].style.display=p?"":"none",s[o].tabIndex=p?0:-1}};for(let d=0;d<n.groups.length;d++){const m=n.groups[d],f=`gengage-simrel-tab-${e}-${d}`,h=`gengage-simrel-panel-${e}-${d}`,o=document.createElement("button");o.className="gengage-simrel-tab",o.type="button",o.id=f,o.textContent=m.name,o.setAttribute("role","tab"),o.setAttribute("aria-controls",h),o.setAttribute("aria-selected",String(d===0)),o.tabIndex=d===0?0:-1,d===0&&o.classList.add("gengage-simrel-tab--active"),o.addEventListener("click",()=>u(d)),o.addEventListener("keydown",y=>{let b=-1;y.key==="ArrowRight"||y.key==="ArrowDown"?b=(d+1)%n.groups.length:y.key==="ArrowLeft"||y.key==="ArrowUp"?b=(d-1+n.groups.length)%n.groups.length:y.key==="Home"?b=0:y.key==="End"&&(b=n.groups.length-1),b>=0&&(y.preventDefault(),u(b),i[b].focus())}),i.push(o),r.appendChild(o);const p=document.createElement("div");p.className="gengage-simrel-tab-panel",p.id=h,p.setAttribute("role","tabpanel"),p.setAttribute("aria-labelledby",f),p.tabIndex=d===0?0:-1,d!==0&&(p.style.display="none"),s.push(p)}t.appendChild(r);const l=s[0],g=_(a(n.groups[0]));l.appendChild(g);for(const d of s)t.appendChild(d);return t}function E(n){if(!n||typeof n!="object")return null;const e=n;if(typeof e.sku!="string"||typeof e.name!="string"||typeof e.url!="string")return null;const t={sku:e.sku,name:e.name,url:e.url},r=e.imageUrl;typeof r=="string"&&(t.imageUrl=r);const i=e.price;typeof i=="string"&&(t.price=i);const s=e.originalPrice;typeof s=="string"&&(t.originalPrice=s);const a=e.discountPercent;typeof a=="number"&&(t.discountPercent=a);const u=e.brand;typeof u=="string"&&(t.brand=u);const l=e.rating;typeof l=="number"&&(t.rating=l);const g=e.reviewCount;typeof g=="number"&&(t.reviewCount=g);const d=e.cartCode;typeof d=="string"&&(t.cartCode=d);const m=e.inStock;return typeof m=="boolean"&&(t.inStock=m),t}function G(n){if(!n||typeof n!="object")return null;const e=n,t=e.title,r=e.type;if(typeof t!="string"||typeof r!="string")return null;const i={title:t,type:r};return e.payload!==void 0&&(i.payload=e.payload),i}const T={ProductGrid:({element:n,renderElement:e,context:t})=>{const r=document.createElement("div");r.className="gengage-simrel-grid",r.setAttribute("role","list");const i=n.props?.columns;typeof i=="number"&&Number.isFinite(i)&&i>0&&r.style.setProperty("--gengage-simrel-columns",String(i));for(const s of n.children??[]){const a=e(s);a&&r.appendChild(a)}if(r.children.length===0){const s=document.createElement("div");s.className="gengage-simrel-empty",s.textContent=t.i18n.emptyStateMessage,r.appendChild(s)}return r},ProductCard:({element:n,context:e})=>{const t=n.props?.product??n.props,r=E(t);if(!r)return null;const i=n.props?.index,s=typeof i=="number"&&Number.isFinite(i)?i:0,a=n.props?.discountType,u=a==="strike-through"||a==="badge"?a:e.discountType,l={product:r,index:s,onClick:e.onClick,onAddToCart:e.onAddToCart,i18n:e.i18n};return u!==void 0&&(l.discountType=u),e.renderCard!==void 0&&(l.renderCard=e.renderCard),e.pricing!==void 0&&(l.pricing=e.pricing),k(l)},GroupTabs:({element:n,context:e})=>{const t=n.props?.groups;if(!Array.isArray(t))return null;const r=[];for(const s of t){if(!s||typeof s!="object")continue;const a=s;if(typeof a.name!="string")continue;const u=[];if(Array.isArray(a.products))for(const g of a.products){const d=E(g);d&&u.push(d)}const l={name:a.name,products:u};typeof a.highlight=="string"&&(l.highlight=a.highlight),r.push(l)}const i={groups:r,onClick:e.onClick,onAddToCart:e.onAddToCart,i18n:e.i18n};return e.discountType!==void 0&&(i.discountType=e.discountType),e.renderCard!==void 0&&(i.renderCard=e.renderCard),j(i)},EmptyState:({element:n,context:e})=>{const t=document.createElement("div");t.className="gengage-simrel-empty";const r=n.props?.message;return t.textContent=typeof r=="string"?r:e.i18n.emptyStateMessage,t},AddToCartButton:({element:n,context:e})=>{const t=n.props?.sku,r=n.props?.cartCode;if(typeof t!="string"||typeof r!="string")return null;const i=document.createElement("button");i.className="gengage-simrel-atc",i.type="button";const s=n.props?.label;return i.textContent=typeof s=="string"?s:e.i18n.addToCartButton,i.addEventListener("click",a=>{a.preventDefault(),a.stopPropagation(),e.onAddToCart({sku:t,quantity:1,cartCode:r})}),i},QuickActions:({element:n,context:e})=>{const t=document.createElement("div");t.className="gengage-simrel-quick-actions";const r=n.props?.actions;if(!Array.isArray(r)||!e.onAction)return t;for(const i of r){if(!i||typeof i!="object")continue;const s=i,a=s.label,u=G(s.action);if(typeof a!="string"||!u)continue;const l=document.createElement("button");l.className="gengage-simrel-quick-action",l.type="button",l.textContent=a,l.addEventListener("click",g=>{g.preventDefault(),g.stopPropagation(),e.onAction?.(u)}),t.appendChild(l)}return t}},v=({element:n,renderElement:e})=>{if(!n.children||n.children.length===0)return null;const t=document.createElement("div");for(const r of n.children){const i=e(r);i&&t.appendChild(i)}return t};function w(){return{...T}}function P(n,e,t=T,r=v){return c.renderUISpecWithRegistry({spec:n,context:e,registry:t,containerClassName:"gengage-simrel-uispec",unknownRenderer:r})}const A={similarProductsAriaLabel:"Benzer ürünler",emptyStateMessage:"Benzer ürün bulunamadı.",addToCartButton:"Sepete Ekle",priceSuffix:" TL"},O={similarProductsAriaLabel:"Similar products",emptyStateMessage:"No similar products found.",addToCartButton:"Add to cart",priceSuffix:""};function D(n){return n?n.toLowerCase().split("-")[0]??"tr":"tr"}function M(n){return D(n)==="en"?O:A}const q=c.object({sku:c.string(),name:c.string(),imageUrl:c.string().url().optional(),price:c.string().optional(),originalPrice:c.string().optional(),discountPercent:c.number().optional(),url:c.string().url(),brand:c.string().optional(),rating:c.number().min(0).max(5).optional(),reviewCount:c.number().int().nonnegative().optional()}),H=c.object({layout:c._enum(["grid","carousel"]).optional(),columns:c.number().int().positive().optional()}),B=c.object({product:q,index:c.number().int().nonnegative(),discountType:c._enum(["strike-through","badge"]).optional()}),z=c.object({sku:c.string(),label:c.string().optional(),cartCode:c.string()}),$=c.object({actions:c.array(c.object({label:c.string(),action:c.object({title:c.string(),type:c.string(),payload:c.unknown().optional()})}))}),F=c.object({message:c.string().optional()}),J={components:{ProductGrid:{schema:H,description:"Outer grid or carousel container for similar products."},ProductCard:{schema:B,description:"A single product card with image, title, price, and actions."},AddToCartButton:{schema:z,description:"Add-to-cart CTA rendered inside or below a product card."},QuickActions:{schema:$,description:"A row of quick-action buttons below product info."},EmptyState:{schema:F,description:"Empty state shown when no similar products are available."}}};class R extends c.BaseWidget{constructor(){super(...arguments),this._abortController=null,this._contentEl=null,this._i18n=A}async onInit(e){this._i18n=this._resolveI18n(e),this._contentEl=document.createElement("div"),this._contentEl.className="gengage-simrel-container",this.root.appendChild(this._contentEl),this._lastSku=e.sku,await this._fetchAndRender(e.sku),this.isVisible=!0,c.trackInit("simrel")}onUpdate(e){const t=e.sku;!t||t===this._lastSku||(this._lastSku=t,this._fetchAndRender(t))}onShow(){this._contentEl&&(this._contentEl.style.opacity="0",this._contentEl.style.transition="opacity 0.3s ease-in",requestAnimationFrame(()=>{this._contentEl&&(this._contentEl.style.opacity="1")}))}onHide(){}onDestroy(){this._abort(),this._contentEl&&(this._contentEl.remove(),this._contentEl=null)}_handleProductClick(e){const t={sku:e.sku,name:e.name,url:e.url};if(e.imageUrl!==void 0&&(t.imageUrl=e.imageUrl),e.price!==void 0&&(t.price=e.price),e.originalPrice!==void 0&&(t.originalPrice=e.originalPrice),e.discountPercent!==void 0&&(t.discountPercent=e.discountPercent),e.brand!==void 0&&(t.brand=e.brand),e.rating!==void 0&&(t.rating=e.rating),e.reviewCount!==void 0&&(t.reviewCount=e.reviewCount),e.cartCode!==void 0&&(t.cartCode=e.cartCode),e.inStock!==void 0&&(t.inStock=e.inStock),this.config.onProductClick?.(t)===!1)return;c.trackProductDetail(e.sku,e.name);const r=this.config.session?.sessionId??null;c.dispatch("gengage:similar:product-click",{sku:e.sku,url:e.url,sessionId:r}),this.config.onProductNavigate?.(e.url,e.sku,r)}_handleAddToCart(e){c.trackCartAdd(e.sku,e.quantity),this.config.onAddToCart?.(e),c.dispatch("gengage:similar:add-to-cart",e),this.track(c.basketAddEvent(this.analyticsContext(),{attribution_source:"simrel",attribution_action_id:crypto.randomUUID(),cart_value:0,currency:"TRY",line_items:e.quantity,sku:e.sku}))}_abort(){this._abortController?.abort(),this._abortController=null}async _fetchAndRender(e){this._abort(),this._abortController=new AbortController;const t=this._abortController.signal;if(!this._contentEl)return;this._contentEl.innerHTML="",this._contentEl.style.display="";const r=document.createElement("div");r.className="gengage-simrel-loading";const i=document.createElement("div");i.className="gengage-simrel-spinner",r.appendChild(i),this._contentEl.appendChild(r);const s={middlewareUrl:this.config.middlewareUrl},a=crypto.randomUUID(),u=Date.now();this.track(c.streamStartEvent(this.analyticsContext(),{endpoint:"similar_products",request_id:a,widget:"simrel"}));try{const l={account_id:this.config.accountId,session_id:this.config.session?.sessionId??"",correlation_id:this.config.session?.sessionId??"",sku:e};this.config.domain!==void 0&&(l.domain=this.config.domain);const g=await N(l,s,t);if(!this._contentEl)return;if(this._contentEl.innerHTML="",g.length>0)try{const d=g.map(f=>f.sku),m=await x({account_id:this.config.accountId,session_id:this.config.session?.sessionId??"",correlation_id:this.config.session?.sessionId??"",skus:d},s,t);if(m.length>0&&this._contentEl){const f=this._buildGroupsSpec(m),h=this._renderUISpec(f);this._contentEl.appendChild(h),c.trackShow("simrel"),this.track(c.streamDoneEvent(this.analyticsContext(),{request_id:a,latency_ms:Date.now()-u,chunk_count:m.reduce((o,p)=>o+p.products.length,0),widget:"simrel"})),this.track(c.widgetHistorySnapshotEvent(this.analyticsContext(),{message_count:m.reduce((o,p)=>o+p.products.length,0),history_ref:a,redaction_level:"none",widget:"simrel"}));return}}catch{}if(this._contentEl){const d=this._buildProductsSpec(g),m=this._renderUISpec(d);this._contentEl.appendChild(m)}g.length>0&&c.trackShow("simrel"),this.track(c.streamDoneEvent(this.analyticsContext(),{request_id:a,latency_ms:Date.now()-u,chunk_count:g.length,widget:"simrel"})),this.track(c.widgetHistorySnapshotEvent(this.analyticsContext(),{message_count:g.length,history_ref:a,redaction_level:"none",widget:"simrel"}))}catch(l){if(l instanceof DOMException&&l.name==="AbortError")return;c.dispatch("gengage:global:error",{source:"simrel",code:"FETCH_ERROR",message:c.getGlobalErrorMessage(this.config.locale)}),this.track(c.streamErrorEvent(this.analyticsContext(),{request_id:a,error_code:"FETCH_ERROR",error_message:l instanceof Error?l.message:String(l),widget:"simrel"})),this._contentEl&&(this._contentEl.innerHTML="",this._contentEl.style.display="none")}}_resolveI18n(e){return{...M(e.locale),...e.i18n}}_resolveUISpecRegistry(){const e=w();return c.mergeUISpecRegistry(e,this.config.renderer?.registry)}_buildRenderContext(){const e=this.config.renderCard,t={onClick:r=>this._handleProductClick(r),onAddToCart:r=>this._handleAddToCart(r),i18n:this._i18n};return this.config.discountType!==void 0&&(t.discountType=this.config.discountType),e!==void 0&&(t.renderCard=e),this.config.pricing!==void 0&&(t.pricing=this.config.pricing),t}_renderUISpec(e){const t=this._resolveUISpecRegistry(),r=this._buildRenderContext(),i=this.config.renderer?.unknownRenderer??v,s=(l,g)=>P(l,g,t,i),a=this.config.renderer?.renderUISpec;return a?a(e,r,{registry:t,unknownRenderer:i,defaultRender:s}):s(e,r)}_buildProductsSpec(e){const t={},r=[];for(let i=0;i<e.length;i++){const s=e[i],a=`product-${i}`;r.push(a),t[a]={type:"ProductCard",props:{product:s,index:i,discountType:this.config.discountType}}}return t.root={type:"ProductGrid",props:{layout:"grid"},children:r},{root:"root",elements:t}}_buildGroupsSpec(e){return{root:"root",elements:{root:{type:"GroupTabs",props:{groups:e}}}}}}function W(){return new R}exports.GengageSimRel=R;exports.createDefaultSimRelUISpecRegistry=w;exports.createSimRelWidget=W;exports.defaultSimRelUnknownUISpecRenderer=v;exports.renderSimRelUISpec=P;exports.simRelCatalog=J;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./schemas-tCxs1sED.cjs"),C=require("./quantity-stepper-UbAp53Ow.cjs");function S(n){const e=n.headers.get("Content-Type")??"";return e.includes("application/x-ndjson")||e.includes("text/event-stream")}async function I(n,e){const t=[],r={onEvent:i=>{const s=c.adaptV1Event(i);if(!(!s||s.type!=="ui_spec")){for(const a of Object.values(s.spec.elements))if(a.type==="ProductCard"&&a.props){const u=a.props.product??a.props;typeof u.sku=="string"&&typeof u.name=="string"&&t.push(u)}}}};return e!==void 0&&(r.signal=e),await c.consumeStream(n,r),t}async function N(n,e,t){const r=c.buildChatEndpointUrl("similar_products",e),i={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)};t!==void 0&&(i.signal=t);const s=await fetch(r,i);if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);if(S(s))return I(s,t);const a=await s.text();if(!a)return[];try{return c.normalizeSimilarProductsResponse(JSON.parse(a))}catch{throw new Error("Invalid JSON from similar_products endpoint")}}async function U(n,e){const t=[];let r=null;const i={onEvent:s=>{const a=c.adaptV1Event(s);if(a){if(a.type==="metadata"&&a.meta){const u=a.meta.group_name;if(typeof u=="string"){r={name:u,products:[]};const l=a.meta.highlight;typeof l=="string"&&(r.highlight=l),t.push(r)}}if(a.type==="ui_spec"&&r){for(const u of Object.values(a.spec.elements))if(u.type==="ProductCard"&&u.props){const l=u.props.product??u.props;typeof l.sku=="string"&&typeof l.name=="string"&&r.products.push(l)}}}}};return e!==void 0&&(i.signal=e),await c.consumeStream(n,i),t}async function x(n,e,t){const r=c.buildChatEndpointUrl("product_groupings",e),i={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)};t!==void 0&&(i.signal=t);const s=await fetch(r,i);if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);if(S(s))return U(s,t);const a=await s.text();if(!a)return[];try{return c.normalizeProductGroupingsResponse(JSON.parse(a))}catch{throw new Error("Invalid JSON from product_groupings endpoint")}}function k(n){const{product:e,index:t,discountType:r,onClick:i,onAddToCart:s,renderCard:a}=n,u=n.i18n,l=n.pricing;if(a){const o=document.createElement("div");return o.className="gengage-simrel-card gengage-simrel-card--custom",o.innerHTML=C.sanitizeHtml(a(e,t)),o.addEventListener("click",p=>{p.target.closest(".gengage-simrel-atc")||i(e)}),o}const g=document.createElement("article");g.className="gengage-simrel-card",g.setAttribute("role","listitem"),g.dataset.sku=e.sku;const d=document.createElement("div");if(d.className="gengage-simrel-card-image",e.imageUrl&&C.isSafeImageUrl(e.imageUrl)){const o=document.createElement("img");o.src=e.imageUrl,o.alt=e.name,o.loading="lazy",C.addImageErrorHandler(o),d.appendChild(o)}if(r==="badge"&&e.discountPercent&&e.discountPercent>0){const o=document.createElement("span");o.className="gengage-simrel-badge",o.textContent=`%${C.clampDiscount(e.discountPercent)}`,d.appendChild(o)}g.appendChild(d);const m=document.createElement("div");if(m.className="gengage-simrel-card-info",e.brand){const o=document.createElement("div");o.className="gengage-simrel-card-brand",o.textContent=e.brand,m.appendChild(o)}const f=document.createElement("div");if(f.className="gengage-simrel-card-name",f.textContent=e.name,m.appendChild(f),e.rating!=null&&e.rating>0){const o=document.createElement("div");if(o.className="gengage-simrel-card-rating",o.textContent=C.renderStarRating(e.rating),e.reviewCount!=null){const p=document.createElement("span");p.className="gengage-simrel-card-review-count",p.textContent=` (${e.reviewCount})`,o.appendChild(p)}m.appendChild(o)}const h=document.createElement("div");if(h.className="gengage-simrel-card-price",e.originalPrice&&e.originalPrice!==e.price&&(r==="strike-through"||!r)){const o=document.createElement("span");o.className="gengage-simrel-card-price-original",o.textContent=C.formatPrice(e.originalPrice,l),h.appendChild(o)}if(e.price){const o=document.createElement("span");o.className="gengage-simrel-card-price-current",o.textContent=C.formatPrice(e.price,l),h.appendChild(o)}if(m.appendChild(h),g.appendChild(m),e.cartCode){const o=e.cartCode,p=C.createQuantityStepper({compact:!1,label:u?.addToCartButton??"Sepete Ekle",onSubmit:y=>{s({sku:e.sku,quantity:y,cartCode:o})}});p.classList.add("gengage-simrel-atc"),g.appendChild(p)}return g.addEventListener("click",o=>{o.target.closest(".gengage-simrel-atc")||i(e)}),g}function _(n){const e=document.createElement("div");e.className="gengage-simrel-grid",e.setAttribute("role","list"),e.setAttribute("aria-label",n.i18n?.similarProductsAriaLabel??"Similar products"),n.columns&&e.style.setProperty("--gengage-simrel-columns",String(n.columns));for(let t=0;t<n.products.length;t++){const i={product:n.products[t],index:t,onClick:n.onClick,onAddToCart:n.onAddToCart};n.i18n!==void 0&&(i.i18n=n.i18n),n.discountType!==void 0&&(i.discountType=n.discountType),n.renderCard!==void 0&&(i.renderCard=n.renderCard);const s=k(i);e.appendChild(s)}if(n.products.length===0){const t=document.createElement("div");t.className="gengage-simrel-empty",t.textContent=n.i18n?.emptyStateMessage??"Benzer ürün bulunamadı.",e.appendChild(t)}return e}let L=0;function j(n){const e=L++,t=document.createElement("div");if(t.className="gengage-simrel-groups",n.groups.length===0){const d=document.createElement("div");return d.className="gengage-simrel-empty",d.textContent=n.i18n?.emptyStateMessage??"Benzer ürün bulunamadı.",t.appendChild(d),t}const r=document.createElement("div");r.className="gengage-simrel-tabs",r.setAttribute("role","tablist");const i=[],s=[],a=d=>{const m={products:d.products,onClick:n.onClick,onAddToCart:n.onAddToCart};return n.i18n!==void 0&&(m.i18n=n.i18n),n.discountType!==void 0&&(m.discountType=n.discountType),n.renderCard!==void 0&&(m.renderCard=n.renderCard),m},u=d=>{for(let o=0;o<i.length;o++){const p=o===d;i[o].classList.toggle("gengage-simrel-tab--active",p),i[o].setAttribute("aria-selected",String(p)),i[o].tabIndex=p?0:-1}const m=n.groups[d],f=s[d];f.innerHTML="";const h=_(a(m));f.appendChild(h);for(let o=0;o<s.length;o++){const p=o===d;s[o].style.display=p?"":"none",s[o].tabIndex=p?0:-1}};for(let d=0;d<n.groups.length;d++){const m=n.groups[d],f=`gengage-simrel-tab-${e}-${d}`,h=`gengage-simrel-panel-${e}-${d}`,o=document.createElement("button");o.className="gengage-simrel-tab",o.type="button",o.id=f,o.textContent=m.name,o.setAttribute("role","tab"),o.setAttribute("aria-controls",h),o.setAttribute("aria-selected",String(d===0)),o.tabIndex=d===0?0:-1,d===0&&o.classList.add("gengage-simrel-tab--active"),o.addEventListener("click",()=>u(d)),o.addEventListener("keydown",y=>{let b=-1;y.key==="ArrowRight"||y.key==="ArrowDown"?b=(d+1)%n.groups.length:y.key==="ArrowLeft"||y.key==="ArrowUp"?b=(d-1+n.groups.length)%n.groups.length:y.key==="Home"?b=0:y.key==="End"&&(b=n.groups.length-1),b>=0&&(y.preventDefault(),u(b),i[b].focus())}),i.push(o),r.appendChild(o);const p=document.createElement("div");p.className="gengage-simrel-tab-panel",p.id=h,p.setAttribute("role","tabpanel"),p.setAttribute("aria-labelledby",f),p.tabIndex=d===0?0:-1,d!==0&&(p.style.display="none"),s.push(p)}t.appendChild(r);const l=s[0],g=_(a(n.groups[0]));l.appendChild(g);for(const d of s)t.appendChild(d);return t}function E(n){if(!n||typeof n!="object")return null;const e=n;if(typeof e.sku!="string"||typeof e.name!="string"||typeof e.url!="string")return null;const t={sku:e.sku,name:e.name,url:e.url},r=e.imageUrl;typeof r=="string"&&(t.imageUrl=r);const i=e.price;typeof i=="string"&&(t.price=i);const s=e.originalPrice;typeof s=="string"&&(t.originalPrice=s);const a=e.discountPercent;typeof a=="number"&&(t.discountPercent=a);const u=e.brand;typeof u=="string"&&(t.brand=u);const l=e.rating;typeof l=="number"&&(t.rating=l);const g=e.reviewCount;typeof g=="number"&&(t.reviewCount=g);const d=e.cartCode;typeof d=="string"&&(t.cartCode=d);const m=e.inStock;return typeof m=="boolean"&&(t.inStock=m),t}function G(n){if(!n||typeof n!="object")return null;const e=n,t=e.title,r=e.type;if(typeof t!="string"||typeof r!="string")return null;const i={title:t,type:r};return e.payload!==void 0&&(i.payload=e.payload),i}const T={ProductGrid:({element:n,renderElement:e,context:t})=>{const r=document.createElement("div");r.className="gengage-simrel-grid",r.setAttribute("role","list");const i=n.props?.columns;typeof i=="number"&&Number.isFinite(i)&&i>0&&r.style.setProperty("--gengage-simrel-columns",String(i));for(const s of n.children??[]){const a=e(s);a&&r.appendChild(a)}if(r.children.length===0){const s=document.createElement("div");s.className="gengage-simrel-empty",s.textContent=t.i18n.emptyStateMessage,r.appendChild(s)}return r},ProductCard:({element:n,context:e})=>{const t=n.props?.product??n.props,r=E(t);if(!r)return null;const i=n.props?.index,s=typeof i=="number"&&Number.isFinite(i)?i:0,a=n.props?.discountType,u=a==="strike-through"||a==="badge"?a:e.discountType,l={product:r,index:s,onClick:e.onClick,onAddToCart:e.onAddToCart,i18n:e.i18n};return u!==void 0&&(l.discountType=u),e.renderCard!==void 0&&(l.renderCard=e.renderCard),e.pricing!==void 0&&(l.pricing=e.pricing),k(l)},GroupTabs:({element:n,context:e})=>{const t=n.props?.groups;if(!Array.isArray(t))return null;const r=[];for(const s of t){if(!s||typeof s!="object")continue;const a=s;if(typeof a.name!="string")continue;const u=[];if(Array.isArray(a.products))for(const g of a.products){const d=E(g);d&&u.push(d)}const l={name:a.name,products:u};typeof a.highlight=="string"&&(l.highlight=a.highlight),r.push(l)}const i={groups:r,onClick:e.onClick,onAddToCart:e.onAddToCart,i18n:e.i18n};return e.discountType!==void 0&&(i.discountType=e.discountType),e.renderCard!==void 0&&(i.renderCard=e.renderCard),j(i)},EmptyState:({element:n,context:e})=>{const t=document.createElement("div");t.className="gengage-simrel-empty";const r=n.props?.message;return t.textContent=typeof r=="string"?r:e.i18n.emptyStateMessage,t},AddToCartButton:({element:n,context:e})=>{const t=n.props?.sku,r=n.props?.cartCode;if(typeof t!="string"||typeof r!="string")return null;const i=document.createElement("button");i.className="gengage-simrel-atc",i.type="button";const s=n.props?.label;return i.textContent=typeof s=="string"?s:e.i18n.addToCartButton,i.addEventListener("click",a=>{a.preventDefault(),a.stopPropagation(),e.onAddToCart({sku:t,quantity:1,cartCode:r})}),i},QuickActions:({element:n,context:e})=>{const t=document.createElement("div");t.className="gengage-simrel-quick-actions";const r=n.props?.actions;if(!Array.isArray(r)||!e.onAction)return t;for(const i of r){if(!i||typeof i!="object")continue;const s=i,a=s.label,u=G(s.action);if(typeof a!="string"||!u)continue;const l=document.createElement("button");l.className="gengage-simrel-quick-action",l.type="button",l.textContent=a,l.addEventListener("click",g=>{g.preventDefault(),g.stopPropagation(),e.onAction?.(u)}),t.appendChild(l)}return t}},v=({element:n,renderElement:e})=>{if(!n.children||n.children.length===0)return null;const t=document.createElement("div");for(const r of n.children){const i=e(r);i&&t.appendChild(i)}return t};function w(){return{...T}}function P(n,e,t=T,r=v){return c.renderUISpecWithRegistry({spec:n,context:e,registry:t,containerClassName:"gengage-simrel-uispec",unknownRenderer:r})}const A={similarProductsAriaLabel:"Benzer ürünler",emptyStateMessage:"Benzer ürün bulunamadı.",addToCartButton:"Sepete Ekle",priceSuffix:" TL"},O={similarProductsAriaLabel:"Similar products",emptyStateMessage:"No similar products found.",addToCartButton:"Add to cart",priceSuffix:""};function D(n){return n?n.toLowerCase().split("-")[0]??"tr":"tr"}function M(n){return D(n)==="en"?O:A}const q=c.object({sku:c.string(),name:c.string(),imageUrl:c.string().url().optional(),price:c.string().optional(),originalPrice:c.string().optional(),discountPercent:c.number().optional(),url:c.string().url(),brand:c.string().optional(),rating:c.number().min(0).max(5).optional(),reviewCount:c.number().int().nonnegative().optional()}),H=c.object({layout:c._enum(["grid","carousel"]).optional(),columns:c.number().int().positive().optional()}),B=c.object({product:q,index:c.number().int().nonnegative(),discountType:c._enum(["strike-through","badge"]).optional()}),z=c.object({sku:c.string(),label:c.string().optional(),cartCode:c.string()}),$=c.object({actions:c.array(c.object({label:c.string(),action:c.object({title:c.string(),type:c.string(),payload:c.unknown().optional()})}))}),F=c.object({message:c.string().optional()}),J={components:{ProductGrid:{schema:H,description:"Outer grid or carousel container for similar products."},ProductCard:{schema:B,description:"A single product card with image, title, price, and actions."},AddToCartButton:{schema:z,description:"Add-to-cart CTA rendered inside or below a product card."},QuickActions:{schema:$,description:"A row of quick-action buttons below product info."},EmptyState:{schema:F,description:"Empty state shown when no similar products are available."}}};class R extends c.BaseWidget{constructor(){super(...arguments),this._abortController=null,this._contentEl=null,this._i18n=A}async onInit(e){this._i18n=this._resolveI18n(e),this._contentEl=document.createElement("div"),this._contentEl.className="gengage-simrel-container",this.root.appendChild(this._contentEl),this._lastSku=e.sku,await this._fetchAndRender(e.sku),this.isVisible=!0,c.trackInit("simrel")}onUpdate(e){const t=e.sku;!t||t===this._lastSku||(this._lastSku=t,this._fetchAndRender(t))}onShow(){this._contentEl&&(this._contentEl.style.opacity="0",this._contentEl.style.transition="opacity 0.3s ease-in",requestAnimationFrame(()=>{this._contentEl&&(this._contentEl.style.opacity="1")}))}onHide(){}onDestroy(){this._abort(),this._contentEl&&(this._contentEl.remove(),this._contentEl=null)}_handleProductClick(e){const t={sku:e.sku,name:e.name,url:e.url};if(e.imageUrl!==void 0&&(t.imageUrl=e.imageUrl),e.price!==void 0&&(t.price=e.price),e.originalPrice!==void 0&&(t.originalPrice=e.originalPrice),e.discountPercent!==void 0&&(t.discountPercent=e.discountPercent),e.brand!==void 0&&(t.brand=e.brand),e.rating!==void 0&&(t.rating=e.rating),e.reviewCount!==void 0&&(t.reviewCount=e.reviewCount),e.cartCode!==void 0&&(t.cartCode=e.cartCode),e.inStock!==void 0&&(t.inStock=e.inStock),this.config.onProductClick?.(t)===!1)return;c.trackProductDetail(e.sku,e.name);const r=this.config.session?.sessionId??null;c.dispatch("gengage:similar:product-click",{sku:e.sku,url:e.url,sessionId:r}),this.config.onProductNavigate?.(e.url,e.sku,r)}_handleAddToCart(e){c.trackCartAdd(e.sku,e.quantity),this.config.onAddToCart?.(e),c.dispatch("gengage:similar:add-to-cart",e),this.track(c.basketAddEvent(this.analyticsContext(),{attribution_source:"simrel",attribution_action_id:crypto.randomUUID(),cart_value:0,currency:"TRY",line_items:e.quantity,sku:e.sku}))}_abort(){this._abortController?.abort(),this._abortController=null}async _fetchAndRender(e){this._abort(),this._abortController=new AbortController;const t=this._abortController.signal;if(!this._contentEl)return;this._contentEl.innerHTML="",this._contentEl.style.display="";const r=document.createElement("div");r.className="gengage-simrel-loading";const i=document.createElement("div");i.className="gengage-simrel-spinner",r.appendChild(i),this._contentEl.appendChild(r);const s={middlewareUrl:this.config.middlewareUrl},a=crypto.randomUUID(),u=Date.now();this.track(c.streamStartEvent(this.analyticsContext(),{endpoint:"similar_products",request_id:a,widget:"simrel"}));try{const l={account_id:this.config.accountId,session_id:this.config.session?.sessionId??"",correlation_id:this.config.session?.sessionId??"",sku:e};this.config.domain!==void 0&&(l.domain=this.config.domain);const g=await N(l,s,t);if(!this._contentEl)return;if(this._contentEl.innerHTML="",g.length>0)try{const d=g.map(f=>f.sku),m=await x({account_id:this.config.accountId,session_id:this.config.session?.sessionId??"",correlation_id:this.config.session?.sessionId??"",skus:d},s,t);if(m.length>0&&this._contentEl){const f=this._buildGroupsSpec(m),h=this._renderUISpec(f);this._contentEl.appendChild(h),c.trackShow("simrel"),this.track(c.streamDoneEvent(this.analyticsContext(),{request_id:a,latency_ms:Date.now()-u,chunk_count:m.reduce((o,p)=>o+p.products.length,0),widget:"simrel"})),this.track(c.widgetHistorySnapshotEvent(this.analyticsContext(),{message_count:m.reduce((o,p)=>o+p.products.length,0),history_ref:a,redaction_level:"none",widget:"simrel"}));return}}catch{}if(this._contentEl){const d=this._buildProductsSpec(g),m=this._renderUISpec(d);this._contentEl.appendChild(m)}g.length>0&&c.trackShow("simrel"),this.track(c.streamDoneEvent(this.analyticsContext(),{request_id:a,latency_ms:Date.now()-u,chunk_count:g.length,widget:"simrel"})),this.track(c.widgetHistorySnapshotEvent(this.analyticsContext(),{message_count:g.length,history_ref:a,redaction_level:"none",widget:"simrel"}))}catch(l){if(l instanceof DOMException&&l.name==="AbortError")return;c.dispatch("gengage:global:error",{source:"simrel",code:"FETCH_ERROR",message:c.getGlobalErrorMessage(this.config.locale)}),this.track(c.streamErrorEvent(this.analyticsContext(),{request_id:a,error_code:"FETCH_ERROR",error_message:l instanceof Error?l.message:String(l),widget:"simrel"})),this._contentEl&&(this._contentEl.innerHTML="",this._contentEl.style.display="none")}}_resolveI18n(e){return{...M(e.locale),...e.i18n}}_resolveUISpecRegistry(){const e=w();return c.mergeUISpecRegistry(e,this.config.renderer?.registry)}_buildRenderContext(){const e=this.config.renderCard,t={onClick:r=>this._handleProductClick(r),onAddToCart:r=>this._handleAddToCart(r),i18n:this._i18n};return this.config.discountType!==void 0&&(t.discountType=this.config.discountType),e!==void 0&&(t.renderCard=e),this.config.pricing!==void 0&&(t.pricing=this.config.pricing),t}_renderUISpec(e){const t=this._resolveUISpecRegistry(),r=this._buildRenderContext(),i=this.config.renderer?.unknownRenderer??v,s=(l,g)=>P(l,g,t,i),a=this.config.renderer?.renderUISpec;return a?a(e,r,{registry:t,unknownRenderer:i,defaultRender:s}):s(e,r)}_buildProductsSpec(e){const t={},r=[];for(let i=0;i<e.length;i++){const s=e[i],a=`product-${i}`;r.push(a),t[a]={type:"ProductCard",props:{product:s,index:i,discountType:this.config.discountType}}}return t.root={type:"ProductGrid",props:{layout:"grid"},children:r},{root:"root",elements:t}}_buildGroupsSpec(e){return{root:"root",elements:{root:{type:"GroupTabs",props:{groups:e}}}}}}function W(){return new R}exports.GengageSimRel=R;exports.createDefaultSimRelUISpecRegistry=w;exports.createSimRelWidget=W;exports.defaultSimRelUnknownUISpecRenderer=v;exports.renderSimRelUISpec=P;exports.simRelCatalog=J;
2
2
  //# sourceMappingURL=simrel.cjs.map