PageSourceSearch

https://aus.spell.co/cdn/shop/t/358/assets/product-recommendations…?v=150266027979979058341788394339

js spell.co collected 2026-09-26 17:12:47 UTC 3,242 bytes, 5 lines download raw bytes

1class c{constructor(){this.pendingRequests=new Map}static getInstance(){return c.instance||(c.instance=new c),c.instance}async fetchRecommendations(e){const{containerId:t,productId:n,intent:o,limit:s,sectionId:r}=e;if(this.pendingRequests.has(t))return this.pendingRequests.get(t);const i=this.performRecommendationRequest(e);this.pendingRequests.set(t,i);try{return await i}finally{this.pendingRequests.delete(t)}}async performRecommendationRequest(e){const{containerId:t,productId:n,intent:o,limit:s,sectionId:r}=e;try{const i=this.buildRecommendationUrl(n,o,s,r),a=await fetch(i,{method:"GET",headers:{"Content-Type":"text/html"}});if(!a.ok)throw new Error(`HTTP error! status: ${a.status}`);const l=await a.text();if(!l||l.trim().length===0){this.hideCarouselSection(t);return}const d=document.createElement("div");if(d.innerHTML=l,d.querySelectorAll('[role="listitem"]').length===0){this.hideCarouselSection(t);return}this.updateCarouselContainer(t,l)}catch(i){console.error("Failed to fetch product recommendations:",i),this.handleRecommendationError(t,i)}}buildRecommendationUrl(e,t,n,o){const s=this.getCurrentLocale(),r=new URLSearchParams({product_id:e,intent:t,limit:n.toString(),section_id:o}),i=window.location.origin,a=s?`/${s}`:"";return`${i}${a}/recommendations/products?${r.toString()}`}getCurrentLocale(){const e=window.location.pathname.split("/").filter(Boolean);return e.length>0&&e[0].length<=3?e[0]:""}updateCarouselContainer(e,t){const n=document.getElementById(e);if(!n){console.warn(`Container with ID ${e} not found`);return}const o=n.querySelector(".carousel-scroll");if(!o){console.warn(`Carousel scroll container not found in ${e}`);return}const s=document.createElement("div");s.innerHTML=t;const r=s.querySelectorAll('[role="listitem"]');if(r.length===0){this.showEmptyState(n);return}o.innerHTML="",r.forEach(i=>{o.appendChild(i.cloneNode(!0))}),n.style.display="",n.dispatchEvent(new CustomEvent("recommendationsLoaded",{detail:{productCount:r.length}}))}handleRecommendationError(e,t){document.getElementById(e)&&(console.error(`Recommendation error for ${e}:`,t),this.hideCarouselSection(e))}hideCarouselSection(e){const t=document.getElementById(e);if(!t)return;const n=t.closest(".section-product-carousel");n?n.style.display="none":t.style.display="none"}showEmptyState(e){const t=e.querySelector(".carousel-scroll");t&&(t.innerHTML=`
2        <div class="w-full text-center text-faint py-8">
3          <p>No recommendations available</p>
4        </div>
5      `)}static initializeRecommendations(){const e=c.getInstance();document.querySelectorAll("[data-recommendation-config]").forEach(n=>{try{const o=n.getAttribute("data-recommendation-config");if(!o){console.warn("No recommendation config found for container:",n);return}const s=o.replace(/'/g,'"'),r=JSON.parse(s);if(!r.productId||!r.containerId){console.error("Invalid recommendation config - missing required fields:",r);return}e.fetchRecommendations(r)}catch(o){console.error("Failed to parse recommendation config:",o),console.error("Raw config data was:",n.getAttribute("data-recommendation-config"))}})}}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",c.initializeRecommendations):c.initializeRecommendations();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.