@yassirbenmoussa/aicommerce-sdk 1.5.0 → 1.6.0
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.
- package/dist/ai-commerce.min.js +2 -2
- package/dist/index.cjs +6 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +6 -2
- package/dist/index.mjs.map +1 -1
- package/dist/widget.min.js +4 -4
- package/dist/widget.min.js.map +1 -1
- package/package.json +1 -1
package/dist/ai-commerce.min.js
CHANGED
|
@@ -547,7 +547,7 @@ var O=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object
|
|
|
547
547
|
.aicommerce-messages::-webkit-scrollbar-thumb:hover {
|
|
548
548
|
background: var(--aic-text-secondary);
|
|
549
549
|
}
|
|
550
|
-
`}function J(t){let e=document.createElement("style");e.id="aicommerce-widget-styles",e.textContent=t;let r=document.getElementById("aicommerce-widget-styles");return r&&r.remove(),document.head.appendChild(e),e}var V=B(()=>{});var X={};Y(X,{AICommerceWidget:()=>exports.AICommerceWidget,createWidget:()=>j});function j(t){if(!t.apiKey)throw new Error("AICommerceWidget: apiKey is required");let e=new exports.AICommerce({apiKey:t.apiKey,storeId:t.storeId,baseUrl:t.baseUrl}),r={isOpen:false,isLoading:true,isRecording:false,messages:[],storeConfig:null},a=null,u=[],s=null,f=null,p;async function
|
|
550
|
+
`}function J(t){let e=document.createElement("style");e.id="aicommerce-widget-styles",e.textContent=t;let r=document.getElementById("aicommerce-widget-styles");return r&&r.remove(),document.head.appendChild(e),e}var V=B(()=>{});var X={};Y(X,{AICommerceWidget:()=>exports.AICommerceWidget,createWidget:()=>j});function j(t){if(!t.apiKey)throw new Error("AICommerceWidget: apiKey is required");let e=new exports.AICommerce({apiKey:t.apiKey,storeId:t.storeId,baseUrl:t.baseUrl}),r={isOpen:false,isLoading:true,isRecording:false,messages:[],storeConfig:null},a=null,u=[],s=null,f=null,p;async function _(){try{let o=t.baseUrl||K(),i=await fetch(`${o}/api/v1/store`,{headers:{"x-api-key":t.apiKey}});return i.ok?(await i.json()).store:null}catch(o){return console.error("Failed to fetch store config:",o),null}}function K(){if(typeof window<"u"){let o=document.querySelector("script[data-aicommerce-url]");if(o)return o.getAttribute("data-aicommerce-url")||""}return "https://api.aicommerce.dev"}async function G(){r.storeConfig=await _(),p={apiKey:t.apiKey,storeId:t.storeId,baseUrl:t.baseUrl||K(),position:t.position||"bottom-right",theme:t.theme||"auto",primaryColor:t.primaryColor||r.storeConfig?.primaryColor||"#6366f1",welcomeMessage:t.welcomeMessage||r.storeConfig?.welcomeMessage||"Hi! How can I help you find the perfect product today?",botName:t.botName||r.storeConfig?.chatBotName||"Shopping Assistant",zIndex:t.zIndex||9999,buttonText:t.buttonText||"\u{1F4AC}",hideLauncher:t.hideLauncher||false,onOpen:t.onOpen,onClose:t.onClose,onProductClick:t.onProductClick,onMessage:t.onMessage};let o=D(p);f=J(o),s=document.createElement("div"),s.id="aicommerce-widget",s.className=`aicommerce-widget aicommerce-${p.position} aicommerce-theme-${p.theme}`,document.body.appendChild(s),b(),r.messages.push({role:"assistant",content:p.welcomeMessage}),r.isLoading=false,b();}function b(){if(!s)return;let o=`
|
|
551
551
|
${p.hideLauncher?"":`
|
|
552
552
|
<button class="aicommerce-launcher ${r.isOpen?"aicommerce-hidden":""}" aria-label="Open chat">
|
|
553
553
|
<span class="aicommerce-launcher-icon">${p.buttonText}</span>
|
|
@@ -649,5 +649,5 @@ var O=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var de=Object
|
|
|
649
649
|
</div>
|
|
650
650
|
<audio src="${o.audioUrl}" preload="metadata"></audio>
|
|
651
651
|
</div>
|
|
652
|
-
`}function Z(){if(!s)return;let o=s.querySelector(".aicommerce-launcher");o&&o.addEventListener("click",()=>L());let i=s.querySelector(".aicommerce-close");i&&i.addEventListener("click",()=>M());let n=s.querySelector(".aicommerce-input"),y=s.querySelector(".aicommerce-send");n&&n.addEventListener("keypress",c=>{c.key==="Enter"&&n.value.trim()&&(A(n.value.trim()),n.value="");}),y&&n&&y.addEventListener("click",()=>{n.value.trim()&&(A(n.value.trim()),n.value="");});let l=s.querySelector(".aicommerce-mic");l&&l.addEventListener("click",()=>ee()),s.querySelectorAll(".aicommerce-product-card").forEach(c=>{c.addEventListener("click",()=>{let d=c.getAttribute("data-product-id"),h=r.messages.flatMap(x=>x.products||[]).find(x=>x.id===d);h&&p.onProductClick
|
|
652
|
+
`}function Z(){if(!s)return;let o=s.querySelector(".aicommerce-launcher");o&&o.addEventListener("click",()=>L());let i=s.querySelector(".aicommerce-close");i&&i.addEventListener("click",()=>M());let n=s.querySelector(".aicommerce-input"),y=s.querySelector(".aicommerce-send");n&&n.addEventListener("keypress",c=>{c.key==="Enter"&&n.value.trim()&&(A(n.value.trim()),n.value="");}),y&&n&&y.addEventListener("click",()=>{n.value.trim()&&(A(n.value.trim()),n.value="");});let l=s.querySelector(".aicommerce-mic");l&&l.addEventListener("click",()=>ee()),s.querySelectorAll(".aicommerce-product-card").forEach(c=>{c.addEventListener("click",()=>{let d=c.getAttribute("data-product-id"),h=r.messages.flatMap(x=>x.products||[]).find(x=>x.id===d);h&&(p.onProductClick?p.onProductClick(h):h.url&&window.open(h.url,"_blank","noopener,noreferrer"));});}),s.querySelectorAll(".aicommerce-products").forEach(c=>{let d=false,h=0,x=0;c.addEventListener("mousedown",k=>{d=true,c.style.cursor="grabbing",h=k.pageX-c.offsetLeft,x=c.scrollLeft;}),c.addEventListener("mouseleave",()=>{d=false,c.style.cursor="grab";}),c.addEventListener("mouseup",()=>{d=false,c.style.cursor="grab";}),c.addEventListener("mousemove",k=>{if(!d)return;k.preventDefault();let v=(k.pageX-c.offsetLeft-h)*2;c.scrollLeft=x-v;});}),s.querySelectorAll(".aicommerce-audio-player").forEach(c=>{let d=c.querySelector("audio"),h=c.querySelector(".aicommerce-audio-btn"),x=c.querySelectorAll(".aicommerce-waveform-bar"),k=c.querySelector(".aicommerce-current-time");if(!d||!h)return;h.addEventListener("click",()=>{!d.paused?(d.pause(),h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>'):(s?.querySelectorAll("audio").forEach(w=>{if(w!==d&&!w.paused){w.pause();let E=w.closest(".aicommerce-audio-player")?.querySelector(".aicommerce-audio-btn");E&&(E.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>');}}),d.play(),h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>');}),d.addEventListener("timeupdate",()=>{if(k&&(k.textContent=N(d.currentTime)),d.duration){let v=d.currentTime/d.duration*100;x.forEach((w,q)=>{q/x.length*100<=v?w.style.backgroundColor=c.closest(".aicommerce-user")?"rgba(255,255,255,1)":"var(--aic-primary)":w.style.backgroundColor=c.closest(".aicommerce-user")?"rgba(255,255,255,0.4)":"rgba(99,102,241,0.3)";});}}),d.addEventListener("ended",()=>{h.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>';});let S=c.querySelector(".aicommerce-waveform-bars");S&&S.addEventListener("click",v=>{let w=S.getBoundingClientRect(),E=(v.clientX-w.left)/w.width;d.duration&&(d.currentTime=E*d.duration);});});}async function ee(){if(r.isRecording)a&&a.state!=="inactive"&&a.stop();else try{let o=await navigator.mediaDevices.getUserMedia({audio:!0});u=[],a=new MediaRecorder(o,{mimeType:MediaRecorder.isTypeSupported("audio/webm")?"audio/webm":"audio/mp4"}),a.ondataavailable=i=>{i.data.size>0&&u.push(i.data);},a.onstop=async()=>{if(o.getTracks().forEach(i=>i.stop()),u.length>0){let i=new Blob(u,{type:a?.mimeType||"audio/webm"});await re(i);}r.isRecording=!1,b();},a.start(),r.isRecording=!0,b();}catch(o){console.error("Failed to start recording:",o),r.messages.push({role:"assistant",content:"Unable to access microphone. Please check your permissions."}),b();}}async function re(o){let i=URL.createObjectURL(o),n=Array(40).fill(10),y=0;try{n=await oe(o);let l=new Audio(i);await new Promise(P=>{l.onloadedmetadata=()=>{y=l.duration,P();},l.onerror=()=>P();});}catch(l){console.error("Audio analysis failed",l);}r.messages.push({role:"user",content:"Voice message",audioUrl:i,audioDuration:y,waveformBars:n}),r.isLoading=true,b();try{let l=await e.chatWithAudio(o);return r.messages.push({role:"assistant",content:l.reply,products:l.products}),p.onMessage&&p.onMessage("Voice message",l),l}catch(l){throw r.messages.push({role:"assistant",content:"Sorry, I encountered an error processing your voice message. Please try again."}),l}finally{r.isLoading=false,b();}}function te(o){return /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/.test(o)}function N(o){let i=Math.floor(o/60),n=Math.floor(o%60);return `${i}:${n.toString().padStart(2,"0")}`}async function oe(o){try{let i=new(window.AudioContext||window.webkitAudioContext),n=await o.arrayBuffer(),l=(await i.decodeAudioData(n)).getChannelData(0),P=40,g=Math.floor(l.length/P),U=[];for(let c=0;c<P;c++){let d=c*g,h=d+g,x=0;for(let v=d;v<h;v++)l[v]&&(x+=l[v]*l[v]);let k=Math.sqrt(x/g),S=Math.min(100,Math.max(10,k*400));U.push(S);}return U}catch(i){return console.error("Analysis error",i),Array.from({length:40},()=>20+Math.random()*60)}}async function A(o){r.messages.push({role:"user",content:o}),r.isLoading=true,b();try{let i=await e.chat(o);return r.messages.push({role:"assistant",content:i.reply,products:i.products}),p.onMessage&&p.onMessage(o,i),i}catch(i){throw r.messages.push({role:"assistant",content:"Sorry, I encountered an error. Please try again."}),i}finally{r.isLoading=false,b();}}function L(){r.isOpen=true,b(),p.onOpen?.(),setTimeout(()=>{s?.querySelector(".aicommerce-input")?.focus();},100);}function M(){r.isOpen=false,b(),p.onClose?.();}function ie(){r.isOpen?M():L();}function ae(){s&&(s.remove(),s=null),f&&(f.remove(),f=null);}function se(o){if(Object.assign(p,o),o.primaryColor){let i=D(p);f&&(f.textContent=i);}b();}function R(o){let i=document.createElement("div");return i.textContent=o,i.innerHTML}function ne(o,i){let y={USD:"$",EUR:"\u20AC",GBP:"\xA3",MAD:"DH",SAR:"SAR",AED:"AED",JPY:"\xA5",CNY:"\xA5"}[i||"USD"]||i||"$";return `${o.toFixed(2)} ${y}`}return G(),{open:L,close:M,toggle:ie,destroy:ae,sendMessage:A,updateConfig:se}}exports.AICommerceWidget=void 0;var F=B(()=>{$();V();exports.AICommerceWidget={init:j,VERSION:"1.0.0"};typeof window<"u"&&(window.AICommerceWidget=exports.AICommerceWidget);});$();F();var be="1.0.0";typeof window<"u"&&(window.AICommerce=($(),W(z)).AICommerce,window.AICommerceError=($(),W(z)).AICommerceError,window.AICommerceWidget=(F(),W(X)).AICommerceWidget);exports.VERSION=be;exports.createWidget=j;return exports;})({});//# sourceMappingURL=index.min.js.map
|
|
653
653
|
//# sourceMappingURL=index.min.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -1159,8 +1159,12 @@ function createWidget(config) {
|
|
|
1159
1159
|
card.addEventListener("click", () => {
|
|
1160
1160
|
const productId = card.getAttribute("data-product-id");
|
|
1161
1161
|
const product = state.messages.flatMap((m) => m.products || []).find((p) => p.id === productId);
|
|
1162
|
-
if (product
|
|
1163
|
-
resolvedConfig.onProductClick
|
|
1162
|
+
if (product) {
|
|
1163
|
+
if (resolvedConfig.onProductClick) {
|
|
1164
|
+
resolvedConfig.onProductClick(product);
|
|
1165
|
+
} else if (product.url) {
|
|
1166
|
+
window.open(product.url, "_blank", "noopener,noreferrer");
|
|
1167
|
+
}
|
|
1164
1168
|
}
|
|
1165
1169
|
});
|
|
1166
1170
|
});
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/widget-styles.ts","../src/widget.ts","../src/index.ts"],"names":["AICommerce","AICommerceError","AICommerceWidget"],"mappings":"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AAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA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","file":"index.cjs","sourcesContent":["import type {\r\n AICommerceConfig,\r\n ChatRequest,\r\n ChatResponse,\r\n ChatContext,\r\n Session,\r\n APIError,\r\n Product,\r\n} from './types';\r\n\r\n/**\r\n * AI Commerce SDK Client\r\n * \r\n * @example\r\n * ```typescript\r\n * import { AICommerce } from '@yassirbenmoussa/aicommerce-sdk';\r\n * \r\n * const client = new AICommerce({ apiKey: 'your-api-key' });\r\n * const response = await client.chat('I need a laptop under $1000');\r\n * console.log(response.products);\r\n * ```\r\n */\r\nexport class AICommerce {\r\n private readonly apiKey: string;\r\n private readonly storeId: string | undefined;\r\n private readonly baseUrl: string;\r\n private readonly timeout: number;\r\n private sessionToken: string | null = null;\r\n\r\n constructor(config: AICommerceConfig) {\r\n if (!config.apiKey) {\r\n throw new Error('AICommerce: apiKey is required');\r\n }\r\n\r\n this.apiKey = config.apiKey;\r\n this.storeId = config.storeId;\r\n this.baseUrl = this.normalizeUrl(config.baseUrl || this.detectBaseUrl());\r\n this.timeout = config.timeout || 30000;\r\n }\r\n\r\n /**\r\n * Detect the base URL based on environment\r\n */\r\n private detectBaseUrl(): string {\r\n // Check for data attribute on script tag (set by widget loader)\r\n if (typeof window !== 'undefined') {\r\n const script = document.querySelector('script[data-aicommerce-url]');\r\n if (script) {\r\n return script.getAttribute('data-aicommerce-url') || 'https://api.aicommerce.dev';\r\n }\r\n }\r\n // Default to production API\r\n return 'https://api.aicommerce.dev';\r\n }\r\n\r\n /**\r\n * Normalize URL (remove trailing slash)\r\n */\r\n private normalizeUrl(url: string): string {\r\n return url.replace(/\\/$/, '');\r\n }\r\n\r\n /**\r\n * Make an API request\r\n */\r\n private async request<T>(\r\n endpoint: string,\r\n options: RequestInit = {}\r\n ): Promise<T> {\r\n const url = `${this.baseUrl}${endpoint}`;\r\n\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n ...options,\r\n signal: controller.signal,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': this.apiKey,\r\n ...(this.storeId && { 'x-store-id': this.storeId }),\r\n ...(this.sessionToken && { 'X-Session-Token': this.sessionToken }),\r\n ...options.headers,\r\n },\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n const error: APIError = {\r\n code: errorData.code || 'UNKNOWN_ERROR',\r\n message: errorData.message || errorData.error || `HTTP ${response.status}`,\r\n status: response.status,\r\n };\r\n throw new AICommerceError(error.message, error.code, error.status);\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n\r\n if (error instanceof AICommerceError) {\r\n throw error;\r\n }\r\n\r\n if (error instanceof Error && error.name === 'AbortError') {\r\n throw new AICommerceError('Request timeout', 'TIMEOUT', 408);\r\n }\r\n\r\n throw new AICommerceError(\r\n error instanceof Error ? error.message : 'Unknown error',\r\n 'NETWORK_ERROR',\r\n 0\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Send a chat message and get product recommendations\r\n * \r\n * @param message - The user's message or full ChatRequest object\r\n * @param context - Optional context for better recommendations\r\n * @returns Chat response with AI reply and products\r\n * \r\n * @example\r\n * ```typescript\r\n * // Simple usage\r\n * const response = await client.chat('I need running shoes');\r\n * \r\n * // With context\r\n * const response = await client.chat('I need running shoes', {\r\n * budget: { max: 150 },\r\n * preferences: ['comfortable', 'lightweight']\r\n * });\r\n * ```\r\n */\r\n async chat(\r\n message: string | ChatRequest,\r\n context?: ChatContext\r\n ): Promise<ChatResponse> {\r\n const request: ChatRequest = typeof message === 'string'\r\n ? { message, context, sessionToken: this.sessionToken || undefined }\r\n : { ...message, sessionToken: message.sessionToken || this.sessionToken || undefined };\r\n\r\n const response = await this.request<ChatResponse>('/api/v1/chat', {\r\n method: 'POST',\r\n body: JSON.stringify(request),\r\n });\r\n\r\n // Store session token for follow-up messages\r\n if (response.sessionToken) {\r\n this.sessionToken = response.sessionToken;\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Send an audio message and get product recommendations\r\n * \r\n * @param audioBlob - Audio blob (from MediaRecorder or file input)\r\n * @param context - Optional context for better recommendations\r\n * @returns Chat response with AI reply and products\r\n * \r\n * @example\r\n * ```typescript\r\n * // Record audio using MediaRecorder\r\n * const mediaRecorder = new MediaRecorder(stream);\r\n * const chunks: Blob[] = [];\r\n * mediaRecorder.ondataavailable = (e) => chunks.push(e.data);\r\n * mediaRecorder.onstop = async () => {\r\n * const audioBlob = new Blob(chunks, { type: 'audio/webm' });\r\n * const response = await client.chatWithAudio(audioBlob);\r\n * console.log(response.reply);\r\n * };\r\n * ```\r\n */\r\n async chatWithAudio(\r\n audioBlob: Blob,\r\n context?: ChatContext\r\n ): Promise<ChatResponse> {\r\n // Convert blob to base64\r\n const arrayBuffer = await audioBlob.arrayBuffer();\r\n const base64 = btoa(\r\n new Uint8Array(arrayBuffer).reduce(\r\n (data, byte) => data + String.fromCharCode(byte),\r\n ''\r\n )\r\n );\r\n\r\n const request: ChatRequest = {\r\n audioBase64: base64,\r\n audioMimeType: audioBlob.type || 'audio/webm',\r\n context,\r\n sessionToken: this.sessionToken || undefined,\r\n };\r\n\r\n const response = await this.request<ChatResponse>('/api/v1/chat', {\r\n method: 'POST',\r\n body: JSON.stringify(request),\r\n });\r\n\r\n // Store session token for follow-up messages\r\n if (response.sessionToken) {\r\n this.sessionToken = response.sessionToken;\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Create a new chat session\r\n * \r\n * @returns Session information with token\r\n */\r\n async createSession(): Promise<Session> {\r\n const response = await this.request<{ session: Session }>('/api/v1/chat/session', {\r\n method: 'POST',\r\n });\r\n\r\n this.sessionToken = response.session.token;\r\n return response.session;\r\n }\r\n\r\n /**\r\n * Clear the current session\r\n */\r\n clearSession(): void {\r\n this.sessionToken = null;\r\n }\r\n\r\n /**\r\n * Get the current session token\r\n */\r\n getSessionToken(): string | null {\r\n return this.sessionToken;\r\n }\r\n\r\n /**\r\n * Set a session token (for restoring sessions)\r\n */\r\n setSessionToken(token: string): void {\r\n this.sessionToken = token;\r\n }\r\n\r\n // ============================================\r\n // Products API\r\n // ============================================\r\n\r\n /**\r\n * Products API namespace\r\n */\r\n readonly products = {\r\n /**\r\n * Create a new product\r\n */\r\n create: async (product: CreateProductInput): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>('/api/v1/products', {\r\n method: 'POST',\r\n body: JSON.stringify(product),\r\n });\r\n },\r\n\r\n /**\r\n * Batch upsert products (create or update)\r\n */\r\n batchUpsert: async (products: CreateProductInput[]): Promise<BatchUpsertResponse> => {\r\n return this.request<BatchUpsertResponse>('/api/v1/products', {\r\n method: 'POST',\r\n body: JSON.stringify({ products }),\r\n });\r\n },\r\n\r\n /**\r\n * List products with pagination\r\n */\r\n list: async (options?: ListProductsOptions): Promise<ListProductsResponse> => {\r\n const params = new URLSearchParams();\r\n if (options?.page) params.set('page', String(options.page));\r\n if (options?.perPage) params.set('perPage', String(options.perPage));\r\n if (options?.search) params.set('search', options.search);\r\n if (options?.categoryId) params.set('categoryId', options.categoryId);\r\n if (options?.isActive !== undefined) params.set('isActive', String(options.isActive));\r\n\r\n const query = params.toString();\r\n return this.request<ListProductsResponse>(`/api/v1/products${query ? `?${query}` : ''}`);\r\n },\r\n\r\n /**\r\n * Get a single product by ID\r\n */\r\n get: async (productId: string): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>(`/api/v1/products/${productId}`);\r\n },\r\n\r\n /**\r\n * Update a product\r\n */\r\n update: async (productId: string, data: UpdateProductInput): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>(`/api/v1/products/${productId}`, {\r\n method: 'PUT',\r\n body: JSON.stringify(data),\r\n });\r\n },\r\n\r\n /**\r\n * Delete a product\r\n */\r\n delete: async (productId: string): Promise<{ success: boolean; deleted: boolean }> => {\r\n return this.request<{ success: boolean; deleted: boolean }>(`/api/v1/products/${productId}`, {\r\n method: 'DELETE',\r\n });\r\n },\r\n };\r\n\r\n // ============================================\r\n // Upload API\r\n // ============================================\r\n\r\n /**\r\n * Upload an image file\r\n * \r\n * @example\r\n * ```typescript\r\n * // Upload from File input\r\n * const file = document.querySelector('input[type=\"file\"]').files[0];\r\n * const result = await client.upload(file);\r\n * console.log(result.url);\r\n * \r\n * // Upload and associate with product\r\n * const result = await client.upload(file, { productId: 'prod_123', isPrimary: true });\r\n * ```\r\n */\r\n async upload(file: File | Blob, options?: UploadOptions): Promise<UploadResponse> {\r\n const formData = new FormData();\r\n formData.append('file', file);\r\n\r\n if (options?.folder) formData.append('folder', options.folder);\r\n if (options?.productId) formData.append('productId', options.productId);\r\n if (options?.isPrimary) formData.append('isPrimary', 'true');\r\n\r\n const url = `${this.baseUrl}/api/v1/upload`;\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'X-API-Key': this.apiKey,\r\n },\r\n body: formData,\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n throw new AICommerceError(\r\n errorData.message || errorData.error || `HTTP ${response.status}`,\r\n errorData.code || 'UPLOAD_ERROR',\r\n response.status\r\n );\r\n }\r\n\r\n return response.json();\r\n }\r\n\r\n /**\r\n * Static method for one-off chat requests\r\n * \r\n * @example\r\n * ```typescript\r\n * const response = await AICommerce.quickChat({\r\n * apiKey: 'your-api-key',\r\n * message: 'I need a laptop'\r\n * });\r\n * ```\r\n */\r\n static async quickChat(options: {\r\n apiKey: string;\r\n message: string;\r\n baseUrl?: string;\r\n context?: ChatContext;\r\n }): Promise<ChatResponse> {\r\n const client = new AICommerce({\r\n apiKey: options.apiKey,\r\n baseUrl: options.baseUrl,\r\n });\r\n return client.chat(options.message, options.context);\r\n }\r\n}\r\n\r\n// ============================================\r\n// Product Types\r\n// ============================================\r\n\r\nexport interface CreateProductInput {\r\n name: string;\r\n slug: string;\r\n description?: string;\r\n sku?: string;\r\n barcode?: string;\r\n price: number;\r\n compareAtPrice?: number;\r\n currency?: string;\r\n quantity?: number;\r\n trackInventory?: boolean;\r\n isActive?: boolean;\r\n isFeatured?: boolean;\r\n tags?: string;\r\n externalId?: string;\r\n categoryId?: string;\r\n images?: Array<{ url: string; alt?: string; isPrimary?: boolean }>;\r\n}\r\n\r\nexport interface UpdateProductInput {\r\n name?: string;\r\n slug?: string;\r\n description?: string | null;\r\n sku?: string | null;\r\n barcode?: string | null;\r\n price?: number;\r\n compareAtPrice?: number | null;\r\n currency?: string;\r\n quantity?: number;\r\n trackInventory?: boolean;\r\n isActive?: boolean;\r\n isFeatured?: boolean;\r\n tags?: string | null;\r\n categoryId?: string | null;\r\n}\r\n\r\nexport interface ProductResponse {\r\n success: boolean;\r\n product: Product;\r\n}\r\n\r\nexport interface BatchUpsertResponse {\r\n success: boolean;\r\n processed: number;\r\n errors: number;\r\n results: Array<{ id: string; slug: string; status: 'created' | 'updated' }>;\r\n errorDetails?: Array<{ slug: string; error: string }>;\r\n}\r\n\r\nexport interface ListProductsOptions {\r\n page?: number;\r\n perPage?: number;\r\n search?: string;\r\n categoryId?: string;\r\n isActive?: boolean;\r\n}\r\n\r\nexport interface ListProductsResponse {\r\n success: boolean;\r\n data: Product[];\r\n total: number;\r\n page: number;\r\n perPage: number;\r\n totalPages: number;\r\n}\r\n\r\nexport interface UploadOptions {\r\n folder?: string;\r\n productId?: string;\r\n isPrimary?: boolean;\r\n}\r\n\r\nexport interface UploadResponse {\r\n success: boolean;\r\n url: string;\r\n key: string;\r\n size: number;\r\n contentType: string;\r\n productImage?: {\r\n id: string;\r\n url: string;\r\n alt: string | null;\r\n isPrimary: boolean;\r\n };\r\n}\r\n\r\n/**\r\n * Custom error class for AI Commerce SDK\r\n */\r\nexport class AICommerceError extends Error {\r\n readonly code: string;\r\n readonly status: number;\r\n\r\n constructor(message: string, code: string, status: number) {\r\n super(message);\r\n this.name = 'AICommerceError';\r\n this.code = code;\r\n this.status = status;\r\n\r\n // Maintain proper prototype chain\r\n Object.setPrototypeOf(this, AICommerceError.prototype);\r\n }\r\n}\r\n","/**\r\n * Widget Styles (CSS-in-JS)\r\n * \r\n * Generates scoped CSS for the AI Commerce widget\r\n * Uses store's primaryColor for theming\r\n */\r\n\r\nimport type { WidgetConfig } from './types';\r\n\r\ntype ResolvedConfig = Required<Omit<WidgetConfig, 'storeId' | 'onOpen' | 'onClose' | 'onProductClick' | 'onMessage'>> & Pick<WidgetConfig, 'storeId'>;\r\n\r\n/**\r\n * Convert hex to RGB\r\n */\r\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } {\r\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n return result\r\n ? {\r\n r: parseInt(result[1], 16),\r\n g: parseInt(result[2], 16),\r\n b: parseInt(result[3], 16),\r\n }\r\n : { r: 99, g: 102, b: 241 }; // Default indigo\r\n}\r\n\r\n/**\r\n * Create widget styles\r\n */\r\nexport function createWidgetStyles(config: ResolvedConfig): string {\r\n const primary = config.primaryColor;\r\n const rgb = hexToRgb(primary);\r\n const isLeft = config.position === 'bottom-left';\r\n\r\n return `\r\n/* AI Commerce Widget Styles */\r\n#aicommerce-widget {\r\n --aic-primary: ${primary};\r\n --aic-primary-rgb: ${rgb.r}, ${rgb.g}, ${rgb.b};\r\n --aic-primary-light: rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.1);\r\n --aic-primary-dark: rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.9);\r\n --aic-bg: #ffffff;\r\n --aic-bg-secondary: #f8fafc;\r\n --aic-text: #1e293b;\r\n --aic-text-secondary: #64748b;\r\n --aic-border: #e2e8f0;\r\n --aic-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\r\n --aic-radius: 16px;\r\n --aic-z-index: ${config.zIndex};\r\n \r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;\r\n font-size: 14px;\r\n line-height: 1.5;\r\n position: fixed;\r\n bottom: 20px;\r\n ${isLeft ? 'left: 20px;' : 'right: 20px;'}\r\n z-index: var(--aic-z-index);\r\n}\r\n\r\n/* Dark theme */\r\n#aicommerce-widget.aicommerce-theme-dark,\r\n@media (prefers-color-scheme: dark) {\r\n #aicommerce-widget.aicommerce-theme-auto {\r\n --aic-bg: #1e293b;\r\n --aic-bg-secondary: #0f172a;\r\n --aic-text: #f1f5f9;\r\n --aic-text-secondary: #94a3b8;\r\n --aic-border: #334155;\r\n }\r\n}\r\n\r\n/* Launcher Button */\r\n.aicommerce-launcher {\r\n width: 60px;\r\n height: 60px;\r\n border-radius: 50%;\r\n background: linear-gradient(135deg, var(--aic-primary), var(--aic-primary-dark));\r\n border: none;\r\n cursor: pointer;\r\n box-shadow: 0 4px 20px rgba(var(--aic-primary-rgb), 0.4);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n animation: aic-pulse 2s infinite;\r\n}\r\n\r\n.aicommerce-launcher:hover {\r\n transform: scale(1.1);\r\n box-shadow: 0 6px 30px rgba(var(--aic-primary-rgb), 0.5);\r\n}\r\n\r\n.aicommerce-launcher-icon {\r\n font-size: 24px;\r\n}\r\n\r\n.aicommerce-hidden {\r\n display: none !important;\r\n}\r\n\r\n@keyframes aic-pulse {\r\n 0%, 100% { box-shadow: 0 4px 20px rgba(var(--aic-primary-rgb), 0.4); }\r\n 50% { box-shadow: 0 4px 30px rgba(var(--aic-primary-rgb), 0.6); }\r\n}\r\n\r\n/* Chat Window */\r\n.aicommerce-chat {\r\n position: absolute;\r\n bottom: 0;\r\n ${isLeft ? 'left: 0;' : 'right: 0;'}\r\n width: 380px;\r\n max-width: calc(100vw - 40px);\r\n height: 600px;\r\n max-height: calc(100vh - 100px);\r\n background: var(--aic-bg);\r\n border-radius: var(--aic-radius);\r\n box-shadow: var(--aic-shadow);\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n transform-origin: bottom ${isLeft ? 'left' : 'right'};\r\n}\r\n\r\n.aicommerce-chat.aicommerce-closed {\r\n opacity: 0;\r\n transform: scale(0.9) translateY(20px);\r\n pointer-events: none;\r\n}\r\n\r\n.aicommerce-chat.aicommerce-open {\r\n opacity: 1;\r\n transform: scale(1) translateY(0);\r\n}\r\n\r\n/* Header */\r\n.aicommerce-header {\r\n background: linear-gradient(135deg, var(--aic-primary), var(--aic-primary-dark));\r\n color: white;\r\n padding: 16px 20px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n}\r\n\r\n.aicommerce-header-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n}\r\n\r\n.aicommerce-avatar {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.2);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 20px;\r\n overflow: hidden;\r\n}\r\n\r\n.aicommerce-avatar img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n}\r\n\r\n.aicommerce-header-text {\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n.aicommerce-bot-name {\r\n font-weight: 600;\r\n font-size: 16px;\r\n}\r\n\r\n.aicommerce-status {\r\n font-size: 12px;\r\n opacity: 0.9;\r\n}\r\n\r\n.aicommerce-close {\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.2);\r\n border: none;\r\n color: white;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 16px;\r\n transition: background 0.2s;\r\n}\r\n\r\n.aicommerce-close:hover {\r\n background: rgba(255, 255, 255, 0.3);\r\n}\r\n\r\n/* Messages */\r\n.aicommerce-messages {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 20px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n background: var(--aic-bg-secondary);\r\n}\r\n\r\n.aicommerce-message {\r\n max-width: 85%;\r\n animation: aic-slide-in 0.3s ease-out;\r\n}\r\n\r\n.aicommerce-message.aicommerce-user {\r\n align-self: flex-end;\r\n}\r\n\r\n.aicommerce-message.aicommerce-assistant {\r\n align-self: flex-start;\r\n}\r\n\r\n.aicommerce-message-content {\r\n padding: 12px 16px;\r\n border-radius: 16px;\r\n line-height: 1.5;\r\n}\r\n\r\n.aicommerce-user .aicommerce-message-content {\r\n background: var(--aic-primary);\r\n color: white;\r\n border-bottom-right-radius: 4px;\r\n}\r\n\r\n.aicommerce-assistant .aicommerce-message-content {\r\n background: var(--aic-bg);\r\n color: var(--aic-text);\r\n border-bottom-left-radius: 4px;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n@keyframes aic-slide-in {\r\n from { opacity: 0; transform: translateY(10px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n}\r\n\r\n/* Typing Indicator */\r\n.aicommerce-typing {\r\n display: flex;\r\n gap: 4px;\r\n padding: 12px 16px;\r\n background: var(--aic-bg);\r\n border-radius: 16px;\r\n width: fit-content;\r\n}\r\n\r\n.aicommerce-typing span {\r\n width: 8px;\r\n height: 8px;\r\n background: var(--aic-text-secondary);\r\n border-radius: 50%;\r\n animation: aic-bounce 1.4s infinite ease-in-out;\r\n}\r\n\r\n.aicommerce-typing span:nth-child(1) { animation-delay: -0.32s; }\r\n.aicommerce-typing span:nth-child(2) { animation-delay: -0.16s; }\r\n\r\n@keyframes aic-bounce {\r\n 0%, 80%, 100% { transform: scale(0); }\r\n 40% { transform: scale(1); }\r\n}\r\n\r\n/* Product Cards */\r\n.aicommerce-products {\r\n display: flex;\r\n gap: 16px;\r\n margin-top: 12px;\r\n overflow-x: auto;\r\n padding-bottom: 16px;\r\n width: 100%;\r\n max-width: 100%;\r\n cursor: grab;\r\n user-select: none;\r\n -webkit-user-select: none;\r\n scrollbar-width: none; /* Firefox */\r\n}\r\n.aicommerce-products::-webkit-scrollbar {\r\n display: none; /* Chrome/Safari */\r\n}\r\n\r\n.aicommerce-product-card {\r\n flex-shrink: 0;\r\n width: 280px;\r\n background: var(--aic-bg);\r\n border-radius: 12px;\r\n overflow: hidden;\r\n cursor: pointer;\r\n transition: all 0.2s;\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\r\n}\r\n\r\n.aicommerce-product-card:hover {\r\n transform: translateY(-2px);\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);\r\n}\r\n\r\n.aicommerce-product-image {\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n height: auto;\r\n object-fit: cover;\r\n}\r\n\r\n.aicommerce-product-placeholder {\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n height: auto;\r\n background: var(--aic-bg-secondary);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 32px;\r\n}\r\n\r\n.aicommerce-product-info {\r\n padding: 10px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n}\r\n\r\n.aicommerce-product-name {\r\n font-weight: 500;\r\n font-size: 13px;\r\n color: var(--aic-text);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n.aicommerce-product-price {\r\n font-weight: 600;\r\n font-size: 14px;\r\n color: var(--aic-primary);\r\n}\r\n\r\n.aicommerce-product-desc {\r\n font-size: 12px;\r\n color: var(--aic-text-secondary);\r\n line-height: 1.4;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n margin-top: 4px;\r\n}\r\n\r\n/* Audio Player */\r\n.aicommerce-audio-player {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n min-width: 240px;\r\n padding: 4px 0;\r\n}\r\n\r\n.aicommerce-audio-btn {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: none;\r\n cursor: pointer;\r\n transition: all 0.2s;\r\n background: rgba(255, 255, 255, 0.25);\r\n color: white;\r\n flex-shrink: 0;\r\n padding: 0;\r\n}\r\n\r\n.aicommerce-audio-btn:hover {\r\n background: rgba(255, 255, 255, 0.35);\r\n transform: scale(1.05);\r\n}\r\n\r\n.aicommerce-audio-btn:active {\r\n transform: scale(0.95);\r\n}\r\n\r\n/* Invert colors for assistant (since background is white/gray) */\r\n.aicommerce-assistant .aicommerce-audio-btn {\r\n background: var(--aic-primary);\r\n color: white;\r\n}\r\n.aicommerce-assistant .aicommerce-audio-btn:hover {\r\n background: var(--aic-primary-dark);\r\n}\r\n\r\n.aicommerce-audio-waveform {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 6px;\r\n min-width: 0; /* Prevent overflow */\r\n}\r\n\r\n.aicommerce-waveform-bars {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n height: 24px;\r\n cursor: pointer;\r\n width: 100%;\r\n}\r\n\r\n.aicommerce-waveform-bar {\r\n width: 3px;\r\n border-radius: 2px;\r\n min-height: 3px;\r\n transition: background-color 0.1s;\r\n flex-shrink: 0;\r\n}\r\n\r\n.aicommerce-audio-time {\r\n display: flex;\r\n justify-content: space-between;\r\n font-size: 11px;\r\n font-weight: 500;\r\n}\r\n\r\n.aicommerce-user .aicommerce-audio-time {\r\n color: rgba(255, 255, 255, 0.8);\r\n}\r\n.aicommerce-assistant .aicommerce-audio-time {\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n/* RTL Support */\r\n.aicommerce-rtl {\r\n direction: rtl;\r\n text-align: right;\r\n}\r\n.aicommerce-ltr {\r\n direction: ltr;\r\n text-align: left;\r\n}\r\n\r\n/* Input Area */\r\n.aicommerce-input-container {\r\n padding: 16px 20px;\r\n background: var(--aic-bg);\r\n border-top: 1px solid var(--aic-border);\r\n display: flex;\r\n gap: 12px;\r\n}\r\n\r\n.aicommerce-input {\r\n flex: 1;\r\n padding: 12px 16px;\r\n border: 1px solid var(--aic-border);\r\n border-radius: 24px;\r\n background: var(--aic-bg-secondary);\r\n color: var(--aic-text);\r\n font-size: 14px;\r\n outline: none;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-input:focus {\r\n border-color: var(--aic-primary);\r\n box-shadow: 0 0 0 3px var(--aic-primary-light);\r\n}\r\n\r\n.aicommerce-input::placeholder {\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n.aicommerce-send {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n background: var(--aic-primary);\r\n border: none;\r\n color: white;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-send:hover:not(:disabled) {\r\n background: var(--aic-primary-dark);\r\n transform: scale(1.05);\r\n}\r\n\r\n.aicommerce-send:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n}\r\n\r\n/* Microphone Button */\r\n.aicommerce-mic {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n background: var(--aic-bg-secondary);\r\n border: 1px solid var(--aic-border);\r\n color: var(--aic-text-secondary);\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-mic:hover:not(:disabled) {\r\n background: var(--aic-primary-light);\r\n border-color: var(--aic-primary);\r\n color: var(--aic-primary);\r\n}\r\n\r\n.aicommerce-mic.aicommerce-recording {\r\n background: #ef4444;\r\n border-color: #ef4444;\r\n color: white;\r\n animation: aic-recording-pulse 1s infinite;\r\n}\r\n\r\n.aicommerce-mic:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n}\r\n\r\n@keyframes aic-recording-pulse {\r\n 0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }\r\n 50% { transform: scale(1.05); box-shadow: 0 0 0 8px rgba(239, 68, 68, 0); }\r\n}\r\n\r\n/* Mobile Responsive */\r\n@media (max-width: 420px) {\r\n #aicommerce-widget {\r\n bottom: 16px;\r\n ${isLeft ? 'left: 16px;' : 'right: 16px;'}\r\n }\r\n \r\n .aicommerce-chat {\r\n width: calc(100vw - 32px);\r\n height: calc(100vh - 100px);\r\n border-radius: 12px;\r\n }\r\n \r\n .aicommerce-launcher {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n}\r\n\r\n/* Scrollbar */\r\n.aicommerce-messages::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-thumb {\r\n background: var(--aic-border);\r\n border-radius: 3px;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-thumb:hover {\r\n background: var(--aic-text-secondary);\r\n}\r\n`;\r\n}\r\n\r\n/**\r\n * Inject styles into the document\r\n */\r\nexport function injectStyles(css: string): HTMLStyleElement {\r\n const style = document.createElement('style');\r\n style.id = 'aicommerce-widget-styles';\r\n style.textContent = css;\r\n\r\n // Remove existing styles\r\n const existing = document.getElementById('aicommerce-widget-styles');\r\n if (existing) {\r\n existing.remove();\r\n }\r\n\r\n document.head.appendChild(style);\r\n return style;\r\n}\r\n","/**\r\n * AI Commerce Chat Widget\r\n * \r\n * Embeddable chat widget for e-commerce stores\r\n * Uses store's primaryColor for theming\r\n */\r\n\r\nimport { AICommerce } from './client';\r\nimport type {\r\n WidgetConfig,\r\n WidgetInstance,\r\n StoreConfig,\r\n Product,\r\n ChatResponse\r\n} from './types';\r\nimport { createWidgetStyles, injectStyles } from './widget-styles';\r\n\r\n// Widget state\r\ninterface WidgetState {\r\n isOpen: boolean;\r\n isLoading: boolean;\r\n isRecording: boolean;\r\n messages: Array<{\r\n role: 'user' | 'assistant';\r\n content: string;\r\n products?: Product[];\r\n audioUrl?: string; // Voice message URL\r\n audioDuration?: number;\r\n waveformBars?: number[];\r\n }>;\r\n storeConfig: StoreConfig | null;\r\n}\r\n\r\n/**\r\n * Create and initialize the AI Commerce chat widget\r\n */\r\nexport function createWidget(config: WidgetConfig): WidgetInstance {\r\n // Validate config\r\n if (!config.apiKey) {\r\n throw new Error('AICommerceWidget: apiKey is required');\r\n }\r\n\r\n // Initialize client\r\n const client = new AICommerce({\r\n apiKey: config.apiKey,\r\n storeId: config.storeId,\r\n baseUrl: config.baseUrl,\r\n });\r\n\r\n // Widget state\r\n const state: WidgetState = {\r\n isOpen: false,\r\n isLoading: true,\r\n isRecording: false,\r\n messages: [],\r\n storeConfig: null,\r\n };\r\n\r\n // Audio recording state\r\n let mediaRecorder: MediaRecorder | null = null;\r\n let audioChunks: Blob[] = [];\r\n\r\n // DOM elements\r\n let container: HTMLDivElement | null = null;\r\n let launcher: HTMLButtonElement | null = null;\r\n let chatWindow: HTMLDivElement | null = null;\r\n let styleElement: HTMLStyleElement | null = null;\r\n\r\n // Resolved config (merged with store config)\r\n let resolvedConfig: Required<Omit<WidgetConfig, 'storeId' | 'onOpen' | 'onClose' | 'onProductClick' | 'onMessage'>> &\r\n Pick<WidgetConfig, 'storeId' | 'onOpen' | 'onClose' | 'onProductClick' | 'onMessage'>;\r\n\r\n /**\r\n * Fetch store configuration\r\n */\r\n async function fetchStoreConfig(): Promise<StoreConfig | null> {\r\n try {\r\n const baseUrl = config.baseUrl || detectBaseUrl();\r\n const response = await fetch(`${baseUrl}/api/v1/store`, {\r\n headers: { 'x-api-key': config.apiKey },\r\n });\r\n\r\n if (!response.ok) return null;\r\n\r\n const data = await response.json();\r\n return data.store;\r\n } catch (error) {\r\n console.error('Failed to fetch store config:', error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Detect base URL\r\n */\r\n function detectBaseUrl(): string {\r\n if (typeof window !== 'undefined') {\r\n // Check for data attribute on script tag\r\n const script = document.querySelector('script[data-aicommerce-url]');\r\n if (script) {\r\n return script.getAttribute('data-aicommerce-url') || '';\r\n }\r\n }\r\n return 'https://api.aicommerce.dev';\r\n }\r\n\r\n /**\r\n * Initialize the widget\r\n */\r\n async function initialize(): Promise<void> {\r\n // Fetch store config\r\n state.storeConfig = await fetchStoreConfig();\r\n\r\n // Merge configs\r\n resolvedConfig = {\r\n apiKey: config.apiKey,\r\n storeId: config.storeId,\r\n baseUrl: config.baseUrl || detectBaseUrl(),\r\n position: config.position || 'bottom-right',\r\n theme: config.theme || 'auto',\r\n primaryColor: config.primaryColor || state.storeConfig?.primaryColor || '#6366f1',\r\n welcomeMessage: config.welcomeMessage || state.storeConfig?.welcomeMessage || 'Hi! How can I help you find the perfect product today?',\r\n botName: config.botName || state.storeConfig?.chatBotName || 'Shopping Assistant',\r\n zIndex: config.zIndex || 9999,\r\n buttonText: config.buttonText || '💬',\r\n hideLauncher: config.hideLauncher || false,\r\n onOpen: config.onOpen,\r\n onClose: config.onClose,\r\n onProductClick: config.onProductClick,\r\n onMessage: config.onMessage,\r\n };\r\n\r\n // Inject styles\r\n const styles = createWidgetStyles(resolvedConfig);\r\n styleElement = injectStyles(styles);\r\n\r\n // Create container\r\n container = document.createElement('div');\r\n container.id = 'aicommerce-widget';\r\n container.className = `aicommerce-widget aicommerce-${resolvedConfig.position} aicommerce-theme-${resolvedConfig.theme}`;\r\n document.body.appendChild(container);\r\n\r\n // Render widget\r\n render();\r\n\r\n // Add welcome message\r\n state.messages.push({\r\n role: 'assistant',\r\n content: resolvedConfig.welcomeMessage,\r\n });\r\n state.isLoading = false;\r\n render();\r\n }\r\n\r\n /**\r\n * Render the widget\r\n */\r\n function render(): void {\r\n if (!container) return;\r\n\r\n const html = `\r\n ${!resolvedConfig.hideLauncher ? `\r\n <button class=\"aicommerce-launcher ${state.isOpen ? 'aicommerce-hidden' : ''}\" aria-label=\"Open chat\">\r\n <span class=\"aicommerce-launcher-icon\">${resolvedConfig.buttonText}</span>\r\n </button>\r\n ` : ''}\r\n \r\n <div class=\"aicommerce-chat ${state.isOpen ? 'aicommerce-open' : 'aicommerce-closed'}\">\r\n <div class=\"aicommerce-header\">\r\n <div class=\"aicommerce-header-info\">\r\n <div class=\"aicommerce-avatar\">\r\n ${state.storeConfig?.logo\r\n ? `<img src=\"${state.storeConfig.logo}\" alt=\"${resolvedConfig.botName}\" />`\r\n : `<span>🤖</span>`\r\n }\r\n </div>\r\n <div class=\"aicommerce-header-text\">\r\n <span class=\"aicommerce-bot-name\">${resolvedConfig.botName}</span>\r\n <span class=\"aicommerce-status\">Online</span>\r\n </div>\r\n </div>\r\n <button class=\"aicommerce-close\" aria-label=\"Close chat\">✕</button>\r\n </div>\r\n \r\n <div class=\"aicommerce-messages\">\r\n ${state.messages.map((msg, index) => {\r\n const isRtl = isArabic(msg.content);\r\n const isUser = msg.role === 'user';\r\n\r\n return `\r\n <div class=\"aicommerce-message aicommerce-${msg.role}\">\r\n <div class=\"aicommerce-message-content ${isRtl ? 'aicommerce-rtl' : 'aicommerce-ltr'}\">\r\n ${msg.audioUrl ? renderAudioPlayer(msg, index, isUser) : escapeHtml(msg.content)}\r\n </div>\r\n ${msg.products && msg.products.length > 0 ? `\r\n <div class=\"aicommerce-products\">\r\n ${msg.products.map(product => `\r\n <div class=\"aicommerce-product-card\" data-product-id=\"${product.id}\">\r\n ${(product.image || product.imageUrl) ? `\r\n <img src=\"${product.image || product.imageUrl}\" alt=\"${escapeHtml(product.name)}\" class=\"aicommerce-product-image\" />\r\n ` : `\r\n <div class=\"aicommerce-product-placeholder\">📦</div>\r\n `}\r\n <div class=\"aicommerce-product-info\">\r\n <span class=\"aicommerce-product-name\" title=\"${escapeHtml(product.name)}\">${escapeHtml(product.name)}</span>\r\n ${product.description ? `<p class=\"aicommerce-product-desc\">${escapeHtml(product.description)}</p>` : ''}\r\n <span class=\"aicommerce-product-price\">${formatPrice(product.price, product.currency)}</span>\r\n </div>\r\n </div>\r\n `).join('')}\r\n </div>\r\n ` : ''}\r\n </div>\r\n `}).join('')}\r\n ${state.isLoading ? `\r\n <div class=\"aicommerce-message aicommerce-assistant\">\r\n <div class=\"aicommerce-typing\">\r\n <span></span><span></span><span></span>\r\n </div>\r\n </div>\r\n ` : ''}\r\n </div>\r\n \r\n <div class=\"aicommerce-input-container\">\r\n <input \r\n type=\"text\" \r\n class=\"aicommerce-input\" \r\n placeholder=\"Type your message...\"\r\n ${state.isLoading || state.isRecording ? 'disabled' : ''}\r\n />\r\n <button class=\"aicommerce-mic ${state.isRecording ? 'aicommerce-recording' : ''}\" ${state.isLoading ? 'disabled' : ''} aria-label=\"${state.isRecording ? 'Stop recording' : 'Voice input'}\">\r\n ${state.isRecording ? `\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\"/>\r\n </svg>\r\n ` : `\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"/>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"/>\r\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"/>\r\n </svg>\r\n `}\r\n </button>\r\n <button class=\"aicommerce-send\" ${state.isLoading || state.isRecording ? 'disabled' : ''} aria-label=\"Send message\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n `;\r\n\r\n container.innerHTML = html;\r\n\r\n // Attach event listeners\r\n attachEventListeners();\r\n\r\n // Scroll to bottom\r\n const messagesEl = container.querySelector('.aicommerce-messages');\r\n if (messagesEl) {\r\n messagesEl.scrollTop = messagesEl.scrollHeight;\r\n }\r\n }\r\n\r\n function renderAudioPlayer(msg: any, index: number, isUser: boolean): string {\r\n return `\r\n <div class=\"aicommerce-audio-player\" data-message-index=\"${index}\">\r\n <button class=\"aicommerce-audio-btn\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>\r\n </button>\r\n <div class=\"aicommerce-audio-waveform\">\r\n <div class=\"aicommerce-waveform-bars\">\r\n ${(msg.waveformBars || Array(40).fill(10)).map((height: number) => `\r\n <div class=\"aicommerce-waveform-bar\" style=\"height: ${height}%; background-color: ${isUser ? 'rgba(255,255,255,0.4)' : 'rgba(99,102,241,0.3)'}\"></div>\r\n `).join('')}\r\n </div>\r\n <div class=\"aicommerce-audio-time\">\r\n <span class=\"aicommerce-current-time\">0:00</span>\r\n <span>${formatTime(msg.audioDuration || 0)}</span>\r\n </div>\r\n </div>\r\n <audio src=\"${msg.audioUrl}\" preload=\"metadata\"></audio>\r\n </div>\r\n `;\r\n }\r\n\r\n /**\r\n * Attach event listeners\r\n */\r\n function attachEventListeners(): void {\r\n if (!container) return;\r\n\r\n // Launcher click\r\n const launcherEl = container.querySelector('.aicommerce-launcher');\r\n if (launcherEl) {\r\n launcherEl.addEventListener('click', () => open());\r\n }\r\n\r\n // Close button\r\n const closeEl = container.querySelector('.aicommerce-close');\r\n if (closeEl) {\r\n closeEl.addEventListener('click', () => close());\r\n }\r\n\r\n // Input\r\n const inputEl = container.querySelector('.aicommerce-input') as HTMLInputElement;\r\n const sendEl = container.querySelector('.aicommerce-send');\r\n\r\n if (inputEl) {\r\n inputEl.addEventListener('keypress', (e) => {\r\n if (e.key === 'Enter' && inputEl.value.trim()) {\r\n handleSend(inputEl.value.trim());\r\n inputEl.value = '';\r\n }\r\n });\r\n }\r\n\r\n if (sendEl && inputEl) {\r\n sendEl.addEventListener('click', () => {\r\n if (inputEl.value.trim()) {\r\n handleSend(inputEl.value.trim());\r\n inputEl.value = '';\r\n }\r\n });\r\n }\r\n\r\n // Microphone button\r\n const micEl = container.querySelector('.aicommerce-mic');\r\n if (micEl) {\r\n micEl.addEventListener('click', () => handleMicClick());\r\n }\r\n\r\n // Product clicks\r\n const productCards = container.querySelectorAll('.aicommerce-product-card');\r\n productCards.forEach(card => {\r\n card.addEventListener('click', () => {\r\n const productId = card.getAttribute('data-product-id');\r\n const product = state.messages\r\n .flatMap(m => m.products || [])\r\n .find(p => p.id === productId);\r\n\r\n if (product && resolvedConfig.onProductClick) {\r\n resolvedConfig.onProductClick(product);\r\n }\r\n });\r\n });\r\n\r\n // Product Sliders (Drag to Scroll)\r\n const sliders = container.querySelectorAll('.aicommerce-products') as NodeListOf<HTMLElement>;\r\n sliders.forEach(slider => {\r\n let isDown = false;\r\n let startX = 0;\r\n let scrollLeft = 0;\r\n\r\n slider.addEventListener('mousedown', (e) => {\r\n isDown = true;\r\n slider.style.cursor = 'grabbing';\r\n startX = e.pageX - slider.offsetLeft;\r\n scrollLeft = slider.scrollLeft;\r\n });\r\n slider.addEventListener('mouseleave', () => {\r\n isDown = false;\r\n slider.style.cursor = 'grab';\r\n });\r\n slider.addEventListener('mouseup', () => {\r\n isDown = false;\r\n slider.style.cursor = 'grab';\r\n });\r\n slider.addEventListener('mousemove', (e) => {\r\n if (!isDown) return;\r\n e.preventDefault();\r\n const x = e.pageX - slider.offsetLeft;\r\n const walk = (x - startX) * 2; // scroll-fast\r\n slider.scrollLeft = scrollLeft - walk;\r\n });\r\n });\r\n\r\n // Audio Players\r\n const audioPlayers = container.querySelectorAll('.aicommerce-audio-player');\r\n audioPlayers.forEach(player => {\r\n const audio = player.querySelector('audio');\r\n const btn = player.querySelector('.aicommerce-audio-btn');\r\n const bars = player.querySelectorAll('.aicommerce-waveform-bar');\r\n const timeDisplay = player.querySelector('.aicommerce-current-time');\r\n\r\n if (!audio || !btn) return;\r\n\r\n // Toggle Play\r\n btn.addEventListener('click', () => {\r\n const isPlaying = !audio.paused;\r\n\r\n if (!isPlaying) {\r\n // Pause all others\r\n container?.querySelectorAll('audio').forEach((a: HTMLAudioElement) => {\r\n if (a !== audio && !a.paused) {\r\n a.pause();\r\n const parent = a.closest('.aicommerce-audio-player');\r\n const otherBtn = parent?.querySelector('.aicommerce-audio-btn');\r\n if (otherBtn) otherBtn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n }\r\n });\r\n\r\n audio.play();\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"6\" y=\"4\" width=\"4\" height=\"16\"></rect><rect x=\"14\" y=\"4\" width=\"4\" height=\"16\"></rect></svg>`;\r\n } else {\r\n audio.pause();\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n }\r\n });\r\n\r\n audio.addEventListener('timeupdate', () => {\r\n if (timeDisplay) timeDisplay.textContent = formatTime(audio.currentTime);\r\n\r\n if (audio.duration) {\r\n const progress = (audio.currentTime / audio.duration) * 100;\r\n bars.forEach((bar, i) => {\r\n const barPos = (i / bars.length) * 100;\r\n if (barPos <= progress) {\r\n (bar as HTMLElement).style.backgroundColor = player.closest('.aicommerce-user') ? 'rgba(255,255,255,1)' : 'var(--aic-primary)';\r\n } else {\r\n (bar as HTMLElement).style.backgroundColor = player.closest('.aicommerce-user') ? 'rgba(255,255,255,0.4)' : 'rgba(99,102,241,0.3)';\r\n }\r\n });\r\n }\r\n });\r\n\r\n audio.addEventListener('ended', () => {\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n });\r\n\r\n const waveform = player.querySelector('.aicommerce-waveform-bars');\r\n if (waveform) {\r\n waveform.addEventListener('click', (e: any) => {\r\n const rect = waveform.getBoundingClientRect();\r\n const x = e.clientX - rect.left;\r\n const percent = x / rect.width;\r\n if (audio.duration) {\r\n audio.currentTime = percent * audio.duration;\r\n }\r\n });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Handle microphone button click\r\n */\r\n async function handleMicClick(): Promise<void> {\r\n if (state.isRecording) {\r\n // Stop recording\r\n if (mediaRecorder && mediaRecorder.state !== 'inactive') {\r\n mediaRecorder.stop();\r\n }\r\n } else {\r\n // Start recording\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\r\n audioChunks = [];\r\n\r\n mediaRecorder = new MediaRecorder(stream, {\r\n mimeType: MediaRecorder.isTypeSupported('audio/webm') ? 'audio/webm' : 'audio/mp4'\r\n });\r\n\r\n mediaRecorder.ondataavailable = (e) => {\r\n if (e.data.size > 0) {\r\n audioChunks.push(e.data);\r\n }\r\n };\r\n\r\n mediaRecorder.onstop = async () => {\r\n // Stop all tracks\r\n stream.getTracks().forEach(track => track.stop());\r\n\r\n if (audioChunks.length > 0) {\r\n const audioBlob = new Blob(audioChunks, { type: mediaRecorder?.mimeType || 'audio/webm' });\r\n await handleAudioSend(audioBlob);\r\n }\r\n\r\n state.isRecording = false;\r\n render();\r\n };\r\n\r\n mediaRecorder.start();\r\n state.isRecording = true;\r\n render();\r\n } catch (error) {\r\n console.error('Failed to start recording:', error);\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Unable to access microphone. Please check your permissions.',\r\n });\r\n render();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle sending audio message\r\n */\r\n async function handleAudioSend(audioBlob: Blob): Promise<ChatResponse> {\r\n // Create audio URL for playback\r\n const audioUrl = URL.createObjectURL(audioBlob);\r\n\r\n // Analyze audio for waveform\r\n let waveformBars: number[] = Array(40).fill(10);\r\n let audioDuration = 0;\r\n\r\n try {\r\n waveformBars = await analyzeAudio(audioBlob);\r\n\r\n // Get duration\r\n const audio = new Audio(audioUrl);\r\n await new Promise<void>((resolve) => {\r\n audio.onloadedmetadata = () => {\r\n audioDuration = audio.duration;\r\n resolve();\r\n };\r\n audio.onerror = () => resolve();\r\n });\r\n } catch (e) {\r\n console.error(\"Audio analysis failed\", e);\r\n }\r\n\r\n // Add user message with audio\r\n state.messages.push({\r\n role: 'user',\r\n content: 'Voice message',\r\n audioUrl,\r\n audioDuration,\r\n waveformBars\r\n });\r\n state.isLoading = true;\r\n render();\r\n\r\n try {\r\n const response = await client.chatWithAudio(audioBlob);\r\n\r\n // Add assistant message\r\n state.messages.push({\r\n role: 'assistant',\r\n content: response.reply,\r\n products: response.products,\r\n });\r\n\r\n if (resolvedConfig.onMessage) {\r\n resolvedConfig.onMessage('Voice message', response);\r\n }\r\n\r\n return response;\r\n } catch (error) {\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Sorry, I encountered an error processing your voice message. Please try again.',\r\n });\r\n throw error;\r\n } finally {\r\n state.isLoading = false;\r\n render();\r\n }\r\n }\r\n\r\n /**\r\n * Helpers\r\n */\r\n function isArabic(text: string): boolean {\r\n return /[\\u0600-\\u06FF\\u0750-\\u077F\\u08A0-\\u08FF\\uFB50-\\uFDFF\\uFE70-\\uFEFF]/.test(text);\r\n }\r\n\r\n function formatTime(seconds: number): string {\r\n const mins = Math.floor(seconds / 60);\r\n const secs = Math.floor(seconds % 60);\r\n return `${mins}:${secs.toString().padStart(2, '0')}`;\r\n }\r\n\r\n async function analyzeAudio(blob: Blob): Promise<number[]> {\r\n try {\r\n const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();\r\n const arrayBuffer = await blob.arrayBuffer();\r\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\r\n const channelData = audioBuffer.getChannelData(0);\r\n\r\n const bars = 40;\r\n const step = Math.floor(channelData.length / bars);\r\n const calculatedBars = [];\r\n\r\n for (let i = 0; i < bars; i++) {\r\n const start = i * step;\r\n const end = start + step;\r\n let sum = 0;\r\n for (let j = start; j < end; j++) {\r\n if (channelData[j]) sum += channelData[j] * channelData[j];\r\n }\r\n const rms = Math.sqrt(sum / step);\r\n const height = Math.min(100, Math.max(10, rms * 400));\r\n calculatedBars.push(height);\r\n }\r\n return calculatedBars;\r\n } catch (e) {\r\n console.error(\"Analysis error\", e);\r\n return Array.from({ length: 40 }, () => 20 + Math.random() * 60);\r\n }\r\n }\r\n\r\n /**\r\n * Handle sending a message\r\n */\r\n async function handleSend(message: string): Promise<ChatResponse> {\r\n // Add user message\r\n state.messages.push({ role: 'user', content: message });\r\n state.isLoading = true;\r\n render();\r\n\r\n try {\r\n const response = await client.chat(message);\r\n\r\n // Add assistant message\r\n state.messages.push({\r\n role: 'assistant',\r\n content: response.reply,\r\n products: response.products,\r\n });\r\n\r\n if (resolvedConfig.onMessage) {\r\n resolvedConfig.onMessage(message, response);\r\n }\r\n\r\n return response;\r\n } catch (error) {\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Sorry, I encountered an error. Please try again.',\r\n });\r\n throw error;\r\n } finally {\r\n state.isLoading = false;\r\n render();\r\n }\r\n }\r\n\r\n /**\r\n * Open the widget\r\n */\r\n function open(): void {\r\n state.isOpen = true;\r\n render();\r\n resolvedConfig.onOpen?.();\r\n\r\n // Focus input\r\n setTimeout(() => {\r\n const input = container?.querySelector('.aicommerce-input') as HTMLInputElement;\r\n input?.focus();\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Close the widget\r\n */\r\n function close(): void {\r\n state.isOpen = false;\r\n render();\r\n resolvedConfig.onClose?.();\r\n }\r\n\r\n /**\r\n * Toggle the widget\r\n */\r\n function toggle(): void {\r\n if (state.isOpen) {\r\n close();\r\n } else {\r\n open();\r\n }\r\n }\r\n\r\n /**\r\n * Destroy the widget\r\n */\r\n function destroy(): void {\r\n if (container) {\r\n container.remove();\r\n container = null;\r\n }\r\n if (styleElement) {\r\n styleElement.remove();\r\n styleElement = null;\r\n }\r\n }\r\n\r\n /**\r\n * Update configuration\r\n */\r\n function updateConfig(newConfig: Partial<WidgetConfig>): void {\r\n Object.assign(resolvedConfig, newConfig);\r\n\r\n if (newConfig.primaryColor) {\r\n const styles = createWidgetStyles(resolvedConfig);\r\n if (styleElement) {\r\n styleElement.textContent = styles;\r\n }\r\n }\r\n\r\n render();\r\n }\r\n\r\n // Utility functions\r\n function escapeHtml(text: string): string {\r\n const div = document.createElement('div');\r\n div.textContent = text;\r\n return div.innerHTML;\r\n }\r\n\r\n function formatPrice(price: number, currency?: string): string {\r\n const symbols: Record<string, string> = {\r\n USD: '$', EUR: '€', GBP: '£', MAD: 'DH',\r\n SAR: 'SAR', AED: 'AED', JPY: '¥', CNY: '¥',\r\n };\r\n const symbol = symbols[currency || 'USD'] || currency || '$';\r\n return `${price.toFixed(2)} ${symbol}`;\r\n }\r\n\r\n // Initialize and return instance\r\n initialize();\r\n\r\n return {\r\n open,\r\n close,\r\n toggle,\r\n destroy,\r\n sendMessage: handleSend,\r\n updateConfig,\r\n };\r\n}\r\n\r\n/**\r\n * Global widget initialization for script tag usage\r\n */\r\nexport const AICommerceWidget = {\r\n init: createWidget,\r\n VERSION: '1.0.0',\r\n};\r\n\r\n// Auto-attach to window for UMD builds\r\nif (typeof window !== 'undefined') {\r\n (window as unknown as Record<string, unknown>).AICommerceWidget = AICommerceWidget;\r\n}\r\n","/**\r\n * AI Commerce SDK\r\n * \r\n * AI-powered product recommendations for e-commerce\r\n * \r\n * @packageDocumentation\r\n * @module @yassirbenmoussa/aicommerce-sdk\r\n * \r\n * @example\r\n * ```typescript\r\n * // npm usage - Client API\r\n * import { AICommerce } from '@yassirbenmoussa/aicommerce-sdk';\r\n * \r\n * const client = new AICommerce({ apiKey: 'your-api-key' });\r\n * const response = await client.chat('I need a laptop');\r\n * console.log(response.products);\r\n * ```\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Widget usage -->\r\n * <script src=\"https://cdn.aicommerce.dev/widget.min.js\"></script>\r\n * <script>\r\n * AICommerceWidget.init({\r\n * apiKey: 'your-api-key',\r\n * position: 'bottom-right',\r\n * theme: 'auto'\r\n * });\r\n * </script>\r\n * ```\r\n */\r\n\r\n// Export main client\r\nexport { AICommerce, AICommerceError } from './client';\r\n\r\n// Export widget\r\nexport { createWidget, AICommerceWidget } from './widget';\r\n\r\n// Export all types\r\nexport type {\r\n // Client types\r\n AICommerceConfig,\r\n ChatRequest,\r\n ChatResponse,\r\n ChatContext,\r\n Product,\r\n Session,\r\n APIError,\r\n EventType,\r\n EventCallback,\r\n // Widget types\r\n StoreConfig,\r\n WidgetConfig,\r\n WidgetInstance,\r\n} from './types';\r\n\r\n// Version\r\nexport const VERSION = '1.0.0';\r\n\r\n// For UMD builds, attach to window\r\nif (typeof window !== 'undefined') {\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerce = require('./client').AICommerce;\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerceError = require('./client').AICommerceError;\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerceWidget = require('./widget').AICommerceWidget;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/widget-styles.ts","../src/widget.ts","../src/index.ts"],"names":["AICommerce","AICommerceError","AICommerceWidget"],"mappings":"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AAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA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","file":"index.cjs","sourcesContent":["import type {\r\n AICommerceConfig,\r\n ChatRequest,\r\n ChatResponse,\r\n ChatContext,\r\n Session,\r\n APIError,\r\n Product,\r\n} from './types';\r\n\r\n/**\r\n * AI Commerce SDK Client\r\n * \r\n * @example\r\n * ```typescript\r\n * import { AICommerce } from '@yassirbenmoussa/aicommerce-sdk';\r\n * \r\n * const client = new AICommerce({ apiKey: 'your-api-key' });\r\n * const response = await client.chat('I need a laptop under $1000');\r\n * console.log(response.products);\r\n * ```\r\n */\r\nexport class AICommerce {\r\n private readonly apiKey: string;\r\n private readonly storeId: string | undefined;\r\n private readonly baseUrl: string;\r\n private readonly timeout: number;\r\n private sessionToken: string | null = null;\r\n\r\n constructor(config: AICommerceConfig) {\r\n if (!config.apiKey) {\r\n throw new Error('AICommerce: apiKey is required');\r\n }\r\n\r\n this.apiKey = config.apiKey;\r\n this.storeId = config.storeId;\r\n this.baseUrl = this.normalizeUrl(config.baseUrl || this.detectBaseUrl());\r\n this.timeout = config.timeout || 30000;\r\n }\r\n\r\n /**\r\n * Detect the base URL based on environment\r\n */\r\n private detectBaseUrl(): string {\r\n // Check for data attribute on script tag (set by widget loader)\r\n if (typeof window !== 'undefined') {\r\n const script = document.querySelector('script[data-aicommerce-url]');\r\n if (script) {\r\n return script.getAttribute('data-aicommerce-url') || 'https://api.aicommerce.dev';\r\n }\r\n }\r\n // Default to production API\r\n return 'https://api.aicommerce.dev';\r\n }\r\n\r\n /**\r\n * Normalize URL (remove trailing slash)\r\n */\r\n private normalizeUrl(url: string): string {\r\n return url.replace(/\\/$/, '');\r\n }\r\n\r\n /**\r\n * Make an API request\r\n */\r\n private async request<T>(\r\n endpoint: string,\r\n options: RequestInit = {}\r\n ): Promise<T> {\r\n const url = `${this.baseUrl}${endpoint}`;\r\n\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n ...options,\r\n signal: controller.signal,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': this.apiKey,\r\n ...(this.storeId && { 'x-store-id': this.storeId }),\r\n ...(this.sessionToken && { 'X-Session-Token': this.sessionToken }),\r\n ...options.headers,\r\n },\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n const error: APIError = {\r\n code: errorData.code || 'UNKNOWN_ERROR',\r\n message: errorData.message || errorData.error || `HTTP ${response.status}`,\r\n status: response.status,\r\n };\r\n throw new AICommerceError(error.message, error.code, error.status);\r\n }\r\n\r\n return response.json();\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n\r\n if (error instanceof AICommerceError) {\r\n throw error;\r\n }\r\n\r\n if (error instanceof Error && error.name === 'AbortError') {\r\n throw new AICommerceError('Request timeout', 'TIMEOUT', 408);\r\n }\r\n\r\n throw new AICommerceError(\r\n error instanceof Error ? error.message : 'Unknown error',\r\n 'NETWORK_ERROR',\r\n 0\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Send a chat message and get product recommendations\r\n * \r\n * @param message - The user's message or full ChatRequest object\r\n * @param context - Optional context for better recommendations\r\n * @returns Chat response with AI reply and products\r\n * \r\n * @example\r\n * ```typescript\r\n * // Simple usage\r\n * const response = await client.chat('I need running shoes');\r\n * \r\n * // With context\r\n * const response = await client.chat('I need running shoes', {\r\n * budget: { max: 150 },\r\n * preferences: ['comfortable', 'lightweight']\r\n * });\r\n * ```\r\n */\r\n async chat(\r\n message: string | ChatRequest,\r\n context?: ChatContext\r\n ): Promise<ChatResponse> {\r\n const request: ChatRequest = typeof message === 'string'\r\n ? { message, context, sessionToken: this.sessionToken || undefined }\r\n : { ...message, sessionToken: message.sessionToken || this.sessionToken || undefined };\r\n\r\n const response = await this.request<ChatResponse>('/api/v1/chat', {\r\n method: 'POST',\r\n body: JSON.stringify(request),\r\n });\r\n\r\n // Store session token for follow-up messages\r\n if (response.sessionToken) {\r\n this.sessionToken = response.sessionToken;\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Send an audio message and get product recommendations\r\n * \r\n * @param audioBlob - Audio blob (from MediaRecorder or file input)\r\n * @param context - Optional context for better recommendations\r\n * @returns Chat response with AI reply and products\r\n * \r\n * @example\r\n * ```typescript\r\n * // Record audio using MediaRecorder\r\n * const mediaRecorder = new MediaRecorder(stream);\r\n * const chunks: Blob[] = [];\r\n * mediaRecorder.ondataavailable = (e) => chunks.push(e.data);\r\n * mediaRecorder.onstop = async () => {\r\n * const audioBlob = new Blob(chunks, { type: 'audio/webm' });\r\n * const response = await client.chatWithAudio(audioBlob);\r\n * console.log(response.reply);\r\n * };\r\n * ```\r\n */\r\n async chatWithAudio(\r\n audioBlob: Blob,\r\n context?: ChatContext\r\n ): Promise<ChatResponse> {\r\n // Convert blob to base64\r\n const arrayBuffer = await audioBlob.arrayBuffer();\r\n const base64 = btoa(\r\n new Uint8Array(arrayBuffer).reduce(\r\n (data, byte) => data + String.fromCharCode(byte),\r\n ''\r\n )\r\n );\r\n\r\n const request: ChatRequest = {\r\n audioBase64: base64,\r\n audioMimeType: audioBlob.type || 'audio/webm',\r\n context,\r\n sessionToken: this.sessionToken || undefined,\r\n };\r\n\r\n const response = await this.request<ChatResponse>('/api/v1/chat', {\r\n method: 'POST',\r\n body: JSON.stringify(request),\r\n });\r\n\r\n // Store session token for follow-up messages\r\n if (response.sessionToken) {\r\n this.sessionToken = response.sessionToken;\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Create a new chat session\r\n * \r\n * @returns Session information with token\r\n */\r\n async createSession(): Promise<Session> {\r\n const response = await this.request<{ session: Session }>('/api/v1/chat/session', {\r\n method: 'POST',\r\n });\r\n\r\n this.sessionToken = response.session.token;\r\n return response.session;\r\n }\r\n\r\n /**\r\n * Clear the current session\r\n */\r\n clearSession(): void {\r\n this.sessionToken = null;\r\n }\r\n\r\n /**\r\n * Get the current session token\r\n */\r\n getSessionToken(): string | null {\r\n return this.sessionToken;\r\n }\r\n\r\n /**\r\n * Set a session token (for restoring sessions)\r\n */\r\n setSessionToken(token: string): void {\r\n this.sessionToken = token;\r\n }\r\n\r\n // ============================================\r\n // Products API\r\n // ============================================\r\n\r\n /**\r\n * Products API namespace\r\n */\r\n readonly products = {\r\n /**\r\n * Create a new product\r\n */\r\n create: async (product: CreateProductInput): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>('/api/v1/products', {\r\n method: 'POST',\r\n body: JSON.stringify(product),\r\n });\r\n },\r\n\r\n /**\r\n * Batch upsert products (create or update)\r\n */\r\n batchUpsert: async (products: CreateProductInput[]): Promise<BatchUpsertResponse> => {\r\n return this.request<BatchUpsertResponse>('/api/v1/products', {\r\n method: 'POST',\r\n body: JSON.stringify({ products }),\r\n });\r\n },\r\n\r\n /**\r\n * List products with pagination\r\n */\r\n list: async (options?: ListProductsOptions): Promise<ListProductsResponse> => {\r\n const params = new URLSearchParams();\r\n if (options?.page) params.set('page', String(options.page));\r\n if (options?.perPage) params.set('perPage', String(options.perPage));\r\n if (options?.search) params.set('search', options.search);\r\n if (options?.categoryId) params.set('categoryId', options.categoryId);\r\n if (options?.isActive !== undefined) params.set('isActive', String(options.isActive));\r\n\r\n const query = params.toString();\r\n return this.request<ListProductsResponse>(`/api/v1/products${query ? `?${query}` : ''}`);\r\n },\r\n\r\n /**\r\n * Get a single product by ID\r\n */\r\n get: async (productId: string): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>(`/api/v1/products/${productId}`);\r\n },\r\n\r\n /**\r\n * Update a product\r\n */\r\n update: async (productId: string, data: UpdateProductInput): Promise<ProductResponse> => {\r\n return this.request<ProductResponse>(`/api/v1/products/${productId}`, {\r\n method: 'PUT',\r\n body: JSON.stringify(data),\r\n });\r\n },\r\n\r\n /**\r\n * Delete a product\r\n */\r\n delete: async (productId: string): Promise<{ success: boolean; deleted: boolean }> => {\r\n return this.request<{ success: boolean; deleted: boolean }>(`/api/v1/products/${productId}`, {\r\n method: 'DELETE',\r\n });\r\n },\r\n };\r\n\r\n // ============================================\r\n // Upload API\r\n // ============================================\r\n\r\n /**\r\n * Upload an image file\r\n * \r\n * @example\r\n * ```typescript\r\n * // Upload from File input\r\n * const file = document.querySelector('input[type=\"file\"]').files[0];\r\n * const result = await client.upload(file);\r\n * console.log(result.url);\r\n * \r\n * // Upload and associate with product\r\n * const result = await client.upload(file, { productId: 'prod_123', isPrimary: true });\r\n * ```\r\n */\r\n async upload(file: File | Blob, options?: UploadOptions): Promise<UploadResponse> {\r\n const formData = new FormData();\r\n formData.append('file', file);\r\n\r\n if (options?.folder) formData.append('folder', options.folder);\r\n if (options?.productId) formData.append('productId', options.productId);\r\n if (options?.isPrimary) formData.append('isPrimary', 'true');\r\n\r\n const url = `${this.baseUrl}/api/v1/upload`;\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'X-API-Key': this.apiKey,\r\n },\r\n body: formData,\r\n });\r\n\r\n if (!response.ok) {\r\n const errorData = await response.json().catch(() => ({}));\r\n throw new AICommerceError(\r\n errorData.message || errorData.error || `HTTP ${response.status}`,\r\n errorData.code || 'UPLOAD_ERROR',\r\n response.status\r\n );\r\n }\r\n\r\n return response.json();\r\n }\r\n\r\n /**\r\n * Static method for one-off chat requests\r\n * \r\n * @example\r\n * ```typescript\r\n * const response = await AICommerce.quickChat({\r\n * apiKey: 'your-api-key',\r\n * message: 'I need a laptop'\r\n * });\r\n * ```\r\n */\r\n static async quickChat(options: {\r\n apiKey: string;\r\n message: string;\r\n baseUrl?: string;\r\n context?: ChatContext;\r\n }): Promise<ChatResponse> {\r\n const client = new AICommerce({\r\n apiKey: options.apiKey,\r\n baseUrl: options.baseUrl,\r\n });\r\n return client.chat(options.message, options.context);\r\n }\r\n}\r\n\r\n// ============================================\r\n// Product Types\r\n// ============================================\r\n\r\nexport interface CreateProductInput {\r\n name: string;\r\n slug: string;\r\n description?: string;\r\n sku?: string;\r\n barcode?: string;\r\n price: number;\r\n compareAtPrice?: number;\r\n currency?: string;\r\n quantity?: number;\r\n trackInventory?: boolean;\r\n isActive?: boolean;\r\n isFeatured?: boolean;\r\n tags?: string;\r\n externalId?: string;\r\n categoryId?: string;\r\n images?: Array<{ url: string; alt?: string; isPrimary?: boolean }>;\r\n}\r\n\r\nexport interface UpdateProductInput {\r\n name?: string;\r\n slug?: string;\r\n description?: string | null;\r\n sku?: string | null;\r\n barcode?: string | null;\r\n price?: number;\r\n compareAtPrice?: number | null;\r\n currency?: string;\r\n quantity?: number;\r\n trackInventory?: boolean;\r\n isActive?: boolean;\r\n isFeatured?: boolean;\r\n tags?: string | null;\r\n categoryId?: string | null;\r\n}\r\n\r\nexport interface ProductResponse {\r\n success: boolean;\r\n product: Product;\r\n}\r\n\r\nexport interface BatchUpsertResponse {\r\n success: boolean;\r\n processed: number;\r\n errors: number;\r\n results: Array<{ id: string; slug: string; status: 'created' | 'updated' }>;\r\n errorDetails?: Array<{ slug: string; error: string }>;\r\n}\r\n\r\nexport interface ListProductsOptions {\r\n page?: number;\r\n perPage?: number;\r\n search?: string;\r\n categoryId?: string;\r\n isActive?: boolean;\r\n}\r\n\r\nexport interface ListProductsResponse {\r\n success: boolean;\r\n data: Product[];\r\n total: number;\r\n page: number;\r\n perPage: number;\r\n totalPages: number;\r\n}\r\n\r\nexport interface UploadOptions {\r\n folder?: string;\r\n productId?: string;\r\n isPrimary?: boolean;\r\n}\r\n\r\nexport interface UploadResponse {\r\n success: boolean;\r\n url: string;\r\n key: string;\r\n size: number;\r\n contentType: string;\r\n productImage?: {\r\n id: string;\r\n url: string;\r\n alt: string | null;\r\n isPrimary: boolean;\r\n };\r\n}\r\n\r\n/**\r\n * Custom error class for AI Commerce SDK\r\n */\r\nexport class AICommerceError extends Error {\r\n readonly code: string;\r\n readonly status: number;\r\n\r\n constructor(message: string, code: string, status: number) {\r\n super(message);\r\n this.name = 'AICommerceError';\r\n this.code = code;\r\n this.status = status;\r\n\r\n // Maintain proper prototype chain\r\n Object.setPrototypeOf(this, AICommerceError.prototype);\r\n }\r\n}\r\n","/**\r\n * Widget Styles (CSS-in-JS)\r\n * \r\n * Generates scoped CSS for the AI Commerce widget\r\n * Uses store's primaryColor for theming\r\n */\r\n\r\nimport type { WidgetConfig } from './types';\r\n\r\ntype ResolvedConfig = Required<Omit<WidgetConfig, 'storeId' | 'onOpen' | 'onClose' | 'onProductClick' | 'onMessage'>> & Pick<WidgetConfig, 'storeId'>;\r\n\r\n/**\r\n * Convert hex to RGB\r\n */\r\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } {\r\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n return result\r\n ? {\r\n r: parseInt(result[1], 16),\r\n g: parseInt(result[2], 16),\r\n b: parseInt(result[3], 16),\r\n }\r\n : { r: 99, g: 102, b: 241 }; // Default indigo\r\n}\r\n\r\n/**\r\n * Create widget styles\r\n */\r\nexport function createWidgetStyles(config: ResolvedConfig): string {\r\n const primary = config.primaryColor;\r\n const rgb = hexToRgb(primary);\r\n const isLeft = config.position === 'bottom-left';\r\n\r\n return `\r\n/* AI Commerce Widget Styles */\r\n#aicommerce-widget {\r\n --aic-primary: ${primary};\r\n --aic-primary-rgb: ${rgb.r}, ${rgb.g}, ${rgb.b};\r\n --aic-primary-light: rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.1);\r\n --aic-primary-dark: rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.9);\r\n --aic-bg: #ffffff;\r\n --aic-bg-secondary: #f8fafc;\r\n --aic-text: #1e293b;\r\n --aic-text-secondary: #64748b;\r\n --aic-border: #e2e8f0;\r\n --aic-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);\r\n --aic-radius: 16px;\r\n --aic-z-index: ${config.zIndex};\r\n \r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;\r\n font-size: 14px;\r\n line-height: 1.5;\r\n position: fixed;\r\n bottom: 20px;\r\n ${isLeft ? 'left: 20px;' : 'right: 20px;'}\r\n z-index: var(--aic-z-index);\r\n}\r\n\r\n/* Dark theme */\r\n#aicommerce-widget.aicommerce-theme-dark,\r\n@media (prefers-color-scheme: dark) {\r\n #aicommerce-widget.aicommerce-theme-auto {\r\n --aic-bg: #1e293b;\r\n --aic-bg-secondary: #0f172a;\r\n --aic-text: #f1f5f9;\r\n --aic-text-secondary: #94a3b8;\r\n --aic-border: #334155;\r\n }\r\n}\r\n\r\n/* Launcher Button */\r\n.aicommerce-launcher {\r\n width: 60px;\r\n height: 60px;\r\n border-radius: 50%;\r\n background: linear-gradient(135deg, var(--aic-primary), var(--aic-primary-dark));\r\n border: none;\r\n cursor: pointer;\r\n box-shadow: 0 4px 20px rgba(var(--aic-primary-rgb), 0.4);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n animation: aic-pulse 2s infinite;\r\n}\r\n\r\n.aicommerce-launcher:hover {\r\n transform: scale(1.1);\r\n box-shadow: 0 6px 30px rgba(var(--aic-primary-rgb), 0.5);\r\n}\r\n\r\n.aicommerce-launcher-icon {\r\n font-size: 24px;\r\n}\r\n\r\n.aicommerce-hidden {\r\n display: none !important;\r\n}\r\n\r\n@keyframes aic-pulse {\r\n 0%, 100% { box-shadow: 0 4px 20px rgba(var(--aic-primary-rgb), 0.4); }\r\n 50% { box-shadow: 0 4px 30px rgba(var(--aic-primary-rgb), 0.6); }\r\n}\r\n\r\n/* Chat Window */\r\n.aicommerce-chat {\r\n position: absolute;\r\n bottom: 0;\r\n ${isLeft ? 'left: 0;' : 'right: 0;'}\r\n width: 380px;\r\n max-width: calc(100vw - 40px);\r\n height: 600px;\r\n max-height: calc(100vh - 100px);\r\n background: var(--aic-bg);\r\n border-radius: var(--aic-radius);\r\n box-shadow: var(--aic-shadow);\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n transform-origin: bottom ${isLeft ? 'left' : 'right'};\r\n}\r\n\r\n.aicommerce-chat.aicommerce-closed {\r\n opacity: 0;\r\n transform: scale(0.9) translateY(20px);\r\n pointer-events: none;\r\n}\r\n\r\n.aicommerce-chat.aicommerce-open {\r\n opacity: 1;\r\n transform: scale(1) translateY(0);\r\n}\r\n\r\n/* Header */\r\n.aicommerce-header {\r\n background: linear-gradient(135deg, var(--aic-primary), var(--aic-primary-dark));\r\n color: white;\r\n padding: 16px 20px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n}\r\n\r\n.aicommerce-header-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n}\r\n\r\n.aicommerce-avatar {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.2);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 20px;\r\n overflow: hidden;\r\n}\r\n\r\n.aicommerce-avatar img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n}\r\n\r\n.aicommerce-header-text {\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n.aicommerce-bot-name {\r\n font-weight: 600;\r\n font-size: 16px;\r\n}\r\n\r\n.aicommerce-status {\r\n font-size: 12px;\r\n opacity: 0.9;\r\n}\r\n\r\n.aicommerce-close {\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.2);\r\n border: none;\r\n color: white;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 16px;\r\n transition: background 0.2s;\r\n}\r\n\r\n.aicommerce-close:hover {\r\n background: rgba(255, 255, 255, 0.3);\r\n}\r\n\r\n/* Messages */\r\n.aicommerce-messages {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 20px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n background: var(--aic-bg-secondary);\r\n}\r\n\r\n.aicommerce-message {\r\n max-width: 85%;\r\n animation: aic-slide-in 0.3s ease-out;\r\n}\r\n\r\n.aicommerce-message.aicommerce-user {\r\n align-self: flex-end;\r\n}\r\n\r\n.aicommerce-message.aicommerce-assistant {\r\n align-self: flex-start;\r\n}\r\n\r\n.aicommerce-message-content {\r\n padding: 12px 16px;\r\n border-radius: 16px;\r\n line-height: 1.5;\r\n}\r\n\r\n.aicommerce-user .aicommerce-message-content {\r\n background: var(--aic-primary);\r\n color: white;\r\n border-bottom-right-radius: 4px;\r\n}\r\n\r\n.aicommerce-assistant .aicommerce-message-content {\r\n background: var(--aic-bg);\r\n color: var(--aic-text);\r\n border-bottom-left-radius: 4px;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n@keyframes aic-slide-in {\r\n from { opacity: 0; transform: translateY(10px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n}\r\n\r\n/* Typing Indicator */\r\n.aicommerce-typing {\r\n display: flex;\r\n gap: 4px;\r\n padding: 12px 16px;\r\n background: var(--aic-bg);\r\n border-radius: 16px;\r\n width: fit-content;\r\n}\r\n\r\n.aicommerce-typing span {\r\n width: 8px;\r\n height: 8px;\r\n background: var(--aic-text-secondary);\r\n border-radius: 50%;\r\n animation: aic-bounce 1.4s infinite ease-in-out;\r\n}\r\n\r\n.aicommerce-typing span:nth-child(1) { animation-delay: -0.32s; }\r\n.aicommerce-typing span:nth-child(2) { animation-delay: -0.16s; }\r\n\r\n@keyframes aic-bounce {\r\n 0%, 80%, 100% { transform: scale(0); }\r\n 40% { transform: scale(1); }\r\n}\r\n\r\n/* Product Cards */\r\n.aicommerce-products {\r\n display: flex;\r\n gap: 16px;\r\n margin-top: 12px;\r\n overflow-x: auto;\r\n padding-bottom: 16px;\r\n width: 100%;\r\n max-width: 100%;\r\n cursor: grab;\r\n user-select: none;\r\n -webkit-user-select: none;\r\n scrollbar-width: none; /* Firefox */\r\n}\r\n.aicommerce-products::-webkit-scrollbar {\r\n display: none; /* Chrome/Safari */\r\n}\r\n\r\n.aicommerce-product-card {\r\n flex-shrink: 0;\r\n width: 280px;\r\n background: var(--aic-bg);\r\n border-radius: 12px;\r\n overflow: hidden;\r\n cursor: pointer;\r\n transition: all 0.2s;\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\r\n}\r\n\r\n.aicommerce-product-card:hover {\r\n transform: translateY(-2px);\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);\r\n}\r\n\r\n.aicommerce-product-image {\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n height: auto;\r\n object-fit: cover;\r\n}\r\n\r\n.aicommerce-product-placeholder {\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n height: auto;\r\n background: var(--aic-bg-secondary);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 32px;\r\n}\r\n\r\n.aicommerce-product-info {\r\n padding: 10px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n}\r\n\r\n.aicommerce-product-name {\r\n font-weight: 500;\r\n font-size: 13px;\r\n color: var(--aic-text);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n.aicommerce-product-price {\r\n font-weight: 600;\r\n font-size: 14px;\r\n color: var(--aic-primary);\r\n}\r\n\r\n.aicommerce-product-desc {\r\n font-size: 12px;\r\n color: var(--aic-text-secondary);\r\n line-height: 1.4;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n margin-top: 4px;\r\n}\r\n\r\n/* Audio Player */\r\n.aicommerce-audio-player {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n min-width: 240px;\r\n padding: 4px 0;\r\n}\r\n\r\n.aicommerce-audio-btn {\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: none;\r\n cursor: pointer;\r\n transition: all 0.2s;\r\n background: rgba(255, 255, 255, 0.25);\r\n color: white;\r\n flex-shrink: 0;\r\n padding: 0;\r\n}\r\n\r\n.aicommerce-audio-btn:hover {\r\n background: rgba(255, 255, 255, 0.35);\r\n transform: scale(1.05);\r\n}\r\n\r\n.aicommerce-audio-btn:active {\r\n transform: scale(0.95);\r\n}\r\n\r\n/* Invert colors for assistant (since background is white/gray) */\r\n.aicommerce-assistant .aicommerce-audio-btn {\r\n background: var(--aic-primary);\r\n color: white;\r\n}\r\n.aicommerce-assistant .aicommerce-audio-btn:hover {\r\n background: var(--aic-primary-dark);\r\n}\r\n\r\n.aicommerce-audio-waveform {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 6px;\r\n min-width: 0; /* Prevent overflow */\r\n}\r\n\r\n.aicommerce-waveform-bars {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n height: 24px;\r\n cursor: pointer;\r\n width: 100%;\r\n}\r\n\r\n.aicommerce-waveform-bar {\r\n width: 3px;\r\n border-radius: 2px;\r\n min-height: 3px;\r\n transition: background-color 0.1s;\r\n flex-shrink: 0;\r\n}\r\n\r\n.aicommerce-audio-time {\r\n display: flex;\r\n justify-content: space-between;\r\n font-size: 11px;\r\n font-weight: 500;\r\n}\r\n\r\n.aicommerce-user .aicommerce-audio-time {\r\n color: rgba(255, 255, 255, 0.8);\r\n}\r\n.aicommerce-assistant .aicommerce-audio-time {\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n/* RTL Support */\r\n.aicommerce-rtl {\r\n direction: rtl;\r\n text-align: right;\r\n}\r\n.aicommerce-ltr {\r\n direction: ltr;\r\n text-align: left;\r\n}\r\n\r\n/* Input Area */\r\n.aicommerce-input-container {\r\n padding: 16px 20px;\r\n background: var(--aic-bg);\r\n border-top: 1px solid var(--aic-border);\r\n display: flex;\r\n gap: 12px;\r\n}\r\n\r\n.aicommerce-input {\r\n flex: 1;\r\n padding: 12px 16px;\r\n border: 1px solid var(--aic-border);\r\n border-radius: 24px;\r\n background: var(--aic-bg-secondary);\r\n color: var(--aic-text);\r\n font-size: 14px;\r\n outline: none;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-input:focus {\r\n border-color: var(--aic-primary);\r\n box-shadow: 0 0 0 3px var(--aic-primary-light);\r\n}\r\n\r\n.aicommerce-input::placeholder {\r\n color: var(--aic-text-secondary);\r\n}\r\n\r\n.aicommerce-send {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n background: var(--aic-primary);\r\n border: none;\r\n color: white;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-send:hover:not(:disabled) {\r\n background: var(--aic-primary-dark);\r\n transform: scale(1.05);\r\n}\r\n\r\n.aicommerce-send:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n}\r\n\r\n/* Microphone Button */\r\n.aicommerce-mic {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n background: var(--aic-bg-secondary);\r\n border: 1px solid var(--aic-border);\r\n color: var(--aic-text-secondary);\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.2s;\r\n}\r\n\r\n.aicommerce-mic:hover:not(:disabled) {\r\n background: var(--aic-primary-light);\r\n border-color: var(--aic-primary);\r\n color: var(--aic-primary);\r\n}\r\n\r\n.aicommerce-mic.aicommerce-recording {\r\n background: #ef4444;\r\n border-color: #ef4444;\r\n color: white;\r\n animation: aic-recording-pulse 1s infinite;\r\n}\r\n\r\n.aicommerce-mic:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n}\r\n\r\n@keyframes aic-recording-pulse {\r\n 0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }\r\n 50% { transform: scale(1.05); box-shadow: 0 0 0 8px rgba(239, 68, 68, 0); }\r\n}\r\n\r\n/* Mobile Responsive */\r\n@media (max-width: 420px) {\r\n #aicommerce-widget {\r\n bottom: 16px;\r\n ${isLeft ? 'left: 16px;' : 'right: 16px;'}\r\n }\r\n \r\n .aicommerce-chat {\r\n width: calc(100vw - 32px);\r\n height: calc(100vh - 100px);\r\n border-radius: 12px;\r\n }\r\n \r\n .aicommerce-launcher {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n}\r\n\r\n/* Scrollbar */\r\n.aicommerce-messages::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-thumb {\r\n background: var(--aic-border);\r\n border-radius: 3px;\r\n}\r\n\r\n.aicommerce-messages::-webkit-scrollbar-thumb:hover {\r\n background: var(--aic-text-secondary);\r\n}\r\n`;\r\n}\r\n\r\n/**\r\n * Inject styles into the document\r\n */\r\nexport function injectStyles(css: string): HTMLStyleElement {\r\n const style = document.createElement('style');\r\n style.id = 'aicommerce-widget-styles';\r\n style.textContent = css;\r\n\r\n // Remove existing styles\r\n const existing = document.getElementById('aicommerce-widget-styles');\r\n if (existing) {\r\n existing.remove();\r\n }\r\n\r\n document.head.appendChild(style);\r\n return style;\r\n}\r\n","/**\r\n * AI Commerce Chat Widget\r\n * \r\n * Embeddable chat widget for e-commerce stores\r\n * Uses store's primaryColor for theming\r\n */\r\n\r\nimport { AICommerce } from './client';\r\nimport type {\r\n WidgetConfig,\r\n WidgetInstance,\r\n StoreConfig,\r\n Product,\r\n ChatResponse\r\n} from './types';\r\nimport { createWidgetStyles, injectStyles } from './widget-styles';\r\n\r\n// Widget state\r\ninterface WidgetState {\r\n isOpen: boolean;\r\n isLoading: boolean;\r\n isRecording: boolean;\r\n messages: Array<{\r\n role: 'user' | 'assistant';\r\n content: string;\r\n products?: Product[];\r\n audioUrl?: string; // Voice message URL\r\n audioDuration?: number;\r\n waveformBars?: number[];\r\n }>;\r\n storeConfig: StoreConfig | null;\r\n}\r\n\r\n/**\r\n * Create and initialize the AI Commerce chat widget\r\n */\r\nexport function createWidget(config: WidgetConfig): WidgetInstance {\r\n // Validate config\r\n if (!config.apiKey) {\r\n throw new Error('AICommerceWidget: apiKey is required');\r\n }\r\n\r\n // Initialize client\r\n const client = new AICommerce({\r\n apiKey: config.apiKey,\r\n storeId: config.storeId,\r\n baseUrl: config.baseUrl,\r\n });\r\n\r\n // Widget state\r\n const state: WidgetState = {\r\n isOpen: false,\r\n isLoading: true,\r\n isRecording: false,\r\n messages: [],\r\n storeConfig: null,\r\n };\r\n\r\n // Audio recording state\r\n let mediaRecorder: MediaRecorder | null = null;\r\n let audioChunks: Blob[] = [];\r\n\r\n // DOM elements\r\n let container: HTMLDivElement | null = null;\r\n let launcher: HTMLButtonElement | null = null;\r\n let chatWindow: HTMLDivElement | null = null;\r\n let styleElement: HTMLStyleElement | null = null;\r\n\r\n // Resolved config (merged with store config)\r\n let resolvedConfig: Required<Omit<WidgetConfig, 'storeId' | 'onOpen' | 'onClose' | 'onProductClick' | 'onMessage'>> &\r\n Pick<WidgetConfig, 'storeId' | 'onOpen' | 'onClose' | 'onProductClick' | 'onMessage'>;\r\n\r\n /**\r\n * Fetch store configuration\r\n */\r\n async function fetchStoreConfig(): Promise<StoreConfig | null> {\r\n try {\r\n const baseUrl = config.baseUrl || detectBaseUrl();\r\n const response = await fetch(`${baseUrl}/api/v1/store`, {\r\n headers: { 'x-api-key': config.apiKey },\r\n });\r\n\r\n if (!response.ok) return null;\r\n\r\n const data = await response.json();\r\n return data.store;\r\n } catch (error) {\r\n console.error('Failed to fetch store config:', error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Detect base URL\r\n */\r\n function detectBaseUrl(): string {\r\n if (typeof window !== 'undefined') {\r\n // Check for data attribute on script tag\r\n const script = document.querySelector('script[data-aicommerce-url]');\r\n if (script) {\r\n return script.getAttribute('data-aicommerce-url') || '';\r\n }\r\n }\r\n return 'https://api.aicommerce.dev';\r\n }\r\n\r\n /**\r\n * Initialize the widget\r\n */\r\n async function initialize(): Promise<void> {\r\n // Fetch store config\r\n state.storeConfig = await fetchStoreConfig();\r\n\r\n // Merge configs\r\n resolvedConfig = {\r\n apiKey: config.apiKey,\r\n storeId: config.storeId,\r\n baseUrl: config.baseUrl || detectBaseUrl(),\r\n position: config.position || 'bottom-right',\r\n theme: config.theme || 'auto',\r\n primaryColor: config.primaryColor || state.storeConfig?.primaryColor || '#6366f1',\r\n welcomeMessage: config.welcomeMessage || state.storeConfig?.welcomeMessage || 'Hi! How can I help you find the perfect product today?',\r\n botName: config.botName || state.storeConfig?.chatBotName || 'Shopping Assistant',\r\n zIndex: config.zIndex || 9999,\r\n buttonText: config.buttonText || '💬',\r\n hideLauncher: config.hideLauncher || false,\r\n onOpen: config.onOpen,\r\n onClose: config.onClose,\r\n onProductClick: config.onProductClick,\r\n onMessage: config.onMessage,\r\n };\r\n\r\n // Inject styles\r\n const styles = createWidgetStyles(resolvedConfig);\r\n styleElement = injectStyles(styles);\r\n\r\n // Create container\r\n container = document.createElement('div');\r\n container.id = 'aicommerce-widget';\r\n container.className = `aicommerce-widget aicommerce-${resolvedConfig.position} aicommerce-theme-${resolvedConfig.theme}`;\r\n document.body.appendChild(container);\r\n\r\n // Render widget\r\n render();\r\n\r\n // Add welcome message\r\n state.messages.push({\r\n role: 'assistant',\r\n content: resolvedConfig.welcomeMessage,\r\n });\r\n state.isLoading = false;\r\n render();\r\n }\r\n\r\n /**\r\n * Render the widget\r\n */\r\n function render(): void {\r\n if (!container) return;\r\n\r\n const html = `\r\n ${!resolvedConfig.hideLauncher ? `\r\n <button class=\"aicommerce-launcher ${state.isOpen ? 'aicommerce-hidden' : ''}\" aria-label=\"Open chat\">\r\n <span class=\"aicommerce-launcher-icon\">${resolvedConfig.buttonText}</span>\r\n </button>\r\n ` : ''}\r\n \r\n <div class=\"aicommerce-chat ${state.isOpen ? 'aicommerce-open' : 'aicommerce-closed'}\">\r\n <div class=\"aicommerce-header\">\r\n <div class=\"aicommerce-header-info\">\r\n <div class=\"aicommerce-avatar\">\r\n ${state.storeConfig?.logo\r\n ? `<img src=\"${state.storeConfig.logo}\" alt=\"${resolvedConfig.botName}\" />`\r\n : `<span>🤖</span>`\r\n }\r\n </div>\r\n <div class=\"aicommerce-header-text\">\r\n <span class=\"aicommerce-bot-name\">${resolvedConfig.botName}</span>\r\n <span class=\"aicommerce-status\">Online</span>\r\n </div>\r\n </div>\r\n <button class=\"aicommerce-close\" aria-label=\"Close chat\">✕</button>\r\n </div>\r\n \r\n <div class=\"aicommerce-messages\">\r\n ${state.messages.map((msg, index) => {\r\n const isRtl = isArabic(msg.content);\r\n const isUser = msg.role === 'user';\r\n\r\n return `\r\n <div class=\"aicommerce-message aicommerce-${msg.role}\">\r\n <div class=\"aicommerce-message-content ${isRtl ? 'aicommerce-rtl' : 'aicommerce-ltr'}\">\r\n ${msg.audioUrl ? renderAudioPlayer(msg, index, isUser) : escapeHtml(msg.content)}\r\n </div>\r\n ${msg.products && msg.products.length > 0 ? `\r\n <div class=\"aicommerce-products\">\r\n ${msg.products.map(product => `\r\n <div class=\"aicommerce-product-card\" data-product-id=\"${product.id}\">\r\n ${(product.image || product.imageUrl) ? `\r\n <img src=\"${product.image || product.imageUrl}\" alt=\"${escapeHtml(product.name)}\" class=\"aicommerce-product-image\" />\r\n ` : `\r\n <div class=\"aicommerce-product-placeholder\">📦</div>\r\n `}\r\n <div class=\"aicommerce-product-info\">\r\n <span class=\"aicommerce-product-name\" title=\"${escapeHtml(product.name)}\">${escapeHtml(product.name)}</span>\r\n ${product.description ? `<p class=\"aicommerce-product-desc\">${escapeHtml(product.description)}</p>` : ''}\r\n <span class=\"aicommerce-product-price\">${formatPrice(product.price, product.currency)}</span>\r\n </div>\r\n </div>\r\n `).join('')}\r\n </div>\r\n ` : ''}\r\n </div>\r\n `}).join('')}\r\n ${state.isLoading ? `\r\n <div class=\"aicommerce-message aicommerce-assistant\">\r\n <div class=\"aicommerce-typing\">\r\n <span></span><span></span><span></span>\r\n </div>\r\n </div>\r\n ` : ''}\r\n </div>\r\n \r\n <div class=\"aicommerce-input-container\">\r\n <input \r\n type=\"text\" \r\n class=\"aicommerce-input\" \r\n placeholder=\"Type your message...\"\r\n ${state.isLoading || state.isRecording ? 'disabled' : ''}\r\n />\r\n <button class=\"aicommerce-mic ${state.isRecording ? 'aicommerce-recording' : ''}\" ${state.isLoading ? 'disabled' : ''} aria-label=\"${state.isRecording ? 'Stop recording' : 'Voice input'}\">\r\n ${state.isRecording ? `\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\"/>\r\n </svg>\r\n ` : `\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"/>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"/>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"/>\r\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"/>\r\n </svg>\r\n `}\r\n </button>\r\n <button class=\"aicommerce-send\" ${state.isLoading || state.isRecording ? 'disabled' : ''} aria-label=\"Send message\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n `;\r\n\r\n container.innerHTML = html;\r\n\r\n // Attach event listeners\r\n attachEventListeners();\r\n\r\n // Scroll to bottom\r\n const messagesEl = container.querySelector('.aicommerce-messages');\r\n if (messagesEl) {\r\n messagesEl.scrollTop = messagesEl.scrollHeight;\r\n }\r\n }\r\n\r\n function renderAudioPlayer(msg: any, index: number, isUser: boolean): string {\r\n return `\r\n <div class=\"aicommerce-audio-player\" data-message-index=\"${index}\">\r\n <button class=\"aicommerce-audio-btn\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>\r\n </button>\r\n <div class=\"aicommerce-audio-waveform\">\r\n <div class=\"aicommerce-waveform-bars\">\r\n ${(msg.waveformBars || Array(40).fill(10)).map((height: number) => `\r\n <div class=\"aicommerce-waveform-bar\" style=\"height: ${height}%; background-color: ${isUser ? 'rgba(255,255,255,0.4)' : 'rgba(99,102,241,0.3)'}\"></div>\r\n `).join('')}\r\n </div>\r\n <div class=\"aicommerce-audio-time\">\r\n <span class=\"aicommerce-current-time\">0:00</span>\r\n <span>${formatTime(msg.audioDuration || 0)}</span>\r\n </div>\r\n </div>\r\n <audio src=\"${msg.audioUrl}\" preload=\"metadata\"></audio>\r\n </div>\r\n `;\r\n }\r\n\r\n /**\r\n * Attach event listeners\r\n */\r\n function attachEventListeners(): void {\r\n if (!container) return;\r\n\r\n // Launcher click\r\n const launcherEl = container.querySelector('.aicommerce-launcher');\r\n if (launcherEl) {\r\n launcherEl.addEventListener('click', () => open());\r\n }\r\n\r\n // Close button\r\n const closeEl = container.querySelector('.aicommerce-close');\r\n if (closeEl) {\r\n closeEl.addEventListener('click', () => close());\r\n }\r\n\r\n // Input\r\n const inputEl = container.querySelector('.aicommerce-input') as HTMLInputElement;\r\n const sendEl = container.querySelector('.aicommerce-send');\r\n\r\n if (inputEl) {\r\n inputEl.addEventListener('keypress', (e) => {\r\n if (e.key === 'Enter' && inputEl.value.trim()) {\r\n handleSend(inputEl.value.trim());\r\n inputEl.value = '';\r\n }\r\n });\r\n }\r\n\r\n if (sendEl && inputEl) {\r\n sendEl.addEventListener('click', () => {\r\n if (inputEl.value.trim()) {\r\n handleSend(inputEl.value.trim());\r\n inputEl.value = '';\r\n }\r\n });\r\n }\r\n\r\n // Microphone button\r\n const micEl = container.querySelector('.aicommerce-mic');\r\n if (micEl) {\r\n micEl.addEventListener('click', () => handleMicClick());\r\n }\r\n\r\n // Product clicks\r\n const productCards = container.querySelectorAll('.aicommerce-product-card');\r\n productCards.forEach(card => {\r\n card.addEventListener('click', () => {\r\n const productId = card.getAttribute('data-product-id');\r\n const product = state.messages\r\n .flatMap(m => m.products || [])\r\n .find(p => p.id === productId);\r\n\r\n if (product) {\r\n if (resolvedConfig.onProductClick) {\r\n resolvedConfig.onProductClick(product);\r\n } else if (product.url) {\r\n // Default behavior: open product URL in new tab\r\n window.open(product.url, '_blank', 'noopener,noreferrer');\r\n }\r\n }\r\n });\r\n });\r\n\r\n // Product Sliders (Drag to Scroll)\r\n const sliders = container.querySelectorAll('.aicommerce-products') as NodeListOf<HTMLElement>;\r\n sliders.forEach(slider => {\r\n let isDown = false;\r\n let startX = 0;\r\n let scrollLeft = 0;\r\n\r\n slider.addEventListener('mousedown', (e) => {\r\n isDown = true;\r\n slider.style.cursor = 'grabbing';\r\n startX = e.pageX - slider.offsetLeft;\r\n scrollLeft = slider.scrollLeft;\r\n });\r\n slider.addEventListener('mouseleave', () => {\r\n isDown = false;\r\n slider.style.cursor = 'grab';\r\n });\r\n slider.addEventListener('mouseup', () => {\r\n isDown = false;\r\n slider.style.cursor = 'grab';\r\n });\r\n slider.addEventListener('mousemove', (e) => {\r\n if (!isDown) return;\r\n e.preventDefault();\r\n const x = e.pageX - slider.offsetLeft;\r\n const walk = (x - startX) * 2; // scroll-fast\r\n slider.scrollLeft = scrollLeft - walk;\r\n });\r\n });\r\n\r\n // Audio Players\r\n const audioPlayers = container.querySelectorAll('.aicommerce-audio-player');\r\n audioPlayers.forEach(player => {\r\n const audio = player.querySelector('audio');\r\n const btn = player.querySelector('.aicommerce-audio-btn');\r\n const bars = player.querySelectorAll('.aicommerce-waveform-bar');\r\n const timeDisplay = player.querySelector('.aicommerce-current-time');\r\n\r\n if (!audio || !btn) return;\r\n\r\n // Toggle Play\r\n btn.addEventListener('click', () => {\r\n const isPlaying = !audio.paused;\r\n\r\n if (!isPlaying) {\r\n // Pause all others\r\n container?.querySelectorAll('audio').forEach((a: HTMLAudioElement) => {\r\n if (a !== audio && !a.paused) {\r\n a.pause();\r\n const parent = a.closest('.aicommerce-audio-player');\r\n const otherBtn = parent?.querySelector('.aicommerce-audio-btn');\r\n if (otherBtn) otherBtn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n }\r\n });\r\n\r\n audio.play();\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"6\" y=\"4\" width=\"4\" height=\"16\"></rect><rect x=\"14\" y=\"4\" width=\"4\" height=\"16\"></rect></svg>`;\r\n } else {\r\n audio.pause();\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n }\r\n });\r\n\r\n audio.addEventListener('timeupdate', () => {\r\n if (timeDisplay) timeDisplay.textContent = formatTime(audio.currentTime);\r\n\r\n if (audio.duration) {\r\n const progress = (audio.currentTime / audio.duration) * 100;\r\n bars.forEach((bar, i) => {\r\n const barPos = (i / bars.length) * 100;\r\n if (barPos <= progress) {\r\n (bar as HTMLElement).style.backgroundColor = player.closest('.aicommerce-user') ? 'rgba(255,255,255,1)' : 'var(--aic-primary)';\r\n } else {\r\n (bar as HTMLElement).style.backgroundColor = player.closest('.aicommerce-user') ? 'rgba(255,255,255,0.4)' : 'rgba(99,102,241,0.3)';\r\n }\r\n });\r\n }\r\n });\r\n\r\n audio.addEventListener('ended', () => {\r\n btn.innerHTML = `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"currentColor\" stroke-width=\"2\"><polygon points=\"5 3 19 12 5 21 5 3\"></polygon></svg>`;\r\n });\r\n\r\n const waveform = player.querySelector('.aicommerce-waveform-bars');\r\n if (waveform) {\r\n waveform.addEventListener('click', (e: any) => {\r\n const rect = waveform.getBoundingClientRect();\r\n const x = e.clientX - rect.left;\r\n const percent = x / rect.width;\r\n if (audio.duration) {\r\n audio.currentTime = percent * audio.duration;\r\n }\r\n });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Handle microphone button click\r\n */\r\n async function handleMicClick(): Promise<void> {\r\n if (state.isRecording) {\r\n // Stop recording\r\n if (mediaRecorder && mediaRecorder.state !== 'inactive') {\r\n mediaRecorder.stop();\r\n }\r\n } else {\r\n // Start recording\r\n try {\r\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\r\n audioChunks = [];\r\n\r\n mediaRecorder = new MediaRecorder(stream, {\r\n mimeType: MediaRecorder.isTypeSupported('audio/webm') ? 'audio/webm' : 'audio/mp4'\r\n });\r\n\r\n mediaRecorder.ondataavailable = (e) => {\r\n if (e.data.size > 0) {\r\n audioChunks.push(e.data);\r\n }\r\n };\r\n\r\n mediaRecorder.onstop = async () => {\r\n // Stop all tracks\r\n stream.getTracks().forEach(track => track.stop());\r\n\r\n if (audioChunks.length > 0) {\r\n const audioBlob = new Blob(audioChunks, { type: mediaRecorder?.mimeType || 'audio/webm' });\r\n await handleAudioSend(audioBlob);\r\n }\r\n\r\n state.isRecording = false;\r\n render();\r\n };\r\n\r\n mediaRecorder.start();\r\n state.isRecording = true;\r\n render();\r\n } catch (error) {\r\n console.error('Failed to start recording:', error);\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Unable to access microphone. Please check your permissions.',\r\n });\r\n render();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle sending audio message\r\n */\r\n async function handleAudioSend(audioBlob: Blob): Promise<ChatResponse> {\r\n // Create audio URL for playback\r\n const audioUrl = URL.createObjectURL(audioBlob);\r\n\r\n // Analyze audio for waveform\r\n let waveformBars: number[] = Array(40).fill(10);\r\n let audioDuration = 0;\r\n\r\n try {\r\n waveformBars = await analyzeAudio(audioBlob);\r\n\r\n // Get duration\r\n const audio = new Audio(audioUrl);\r\n await new Promise<void>((resolve) => {\r\n audio.onloadedmetadata = () => {\r\n audioDuration = audio.duration;\r\n resolve();\r\n };\r\n audio.onerror = () => resolve();\r\n });\r\n } catch (e) {\r\n console.error(\"Audio analysis failed\", e);\r\n }\r\n\r\n // Add user message with audio\r\n state.messages.push({\r\n role: 'user',\r\n content: 'Voice message',\r\n audioUrl,\r\n audioDuration,\r\n waveformBars\r\n });\r\n state.isLoading = true;\r\n render();\r\n\r\n try {\r\n const response = await client.chatWithAudio(audioBlob);\r\n\r\n // Add assistant message\r\n state.messages.push({\r\n role: 'assistant',\r\n content: response.reply,\r\n products: response.products,\r\n });\r\n\r\n if (resolvedConfig.onMessage) {\r\n resolvedConfig.onMessage('Voice message', response);\r\n }\r\n\r\n return response;\r\n } catch (error) {\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Sorry, I encountered an error processing your voice message. Please try again.',\r\n });\r\n throw error;\r\n } finally {\r\n state.isLoading = false;\r\n render();\r\n }\r\n }\r\n\r\n /**\r\n * Helpers\r\n */\r\n function isArabic(text: string): boolean {\r\n return /[\\u0600-\\u06FF\\u0750-\\u077F\\u08A0-\\u08FF\\uFB50-\\uFDFF\\uFE70-\\uFEFF]/.test(text);\r\n }\r\n\r\n function formatTime(seconds: number): string {\r\n const mins = Math.floor(seconds / 60);\r\n const secs = Math.floor(seconds % 60);\r\n return `${mins}:${secs.toString().padStart(2, '0')}`;\r\n }\r\n\r\n async function analyzeAudio(blob: Blob): Promise<number[]> {\r\n try {\r\n const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();\r\n const arrayBuffer = await blob.arrayBuffer();\r\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\r\n const channelData = audioBuffer.getChannelData(0);\r\n\r\n const bars = 40;\r\n const step = Math.floor(channelData.length / bars);\r\n const calculatedBars = [];\r\n\r\n for (let i = 0; i < bars; i++) {\r\n const start = i * step;\r\n const end = start + step;\r\n let sum = 0;\r\n for (let j = start; j < end; j++) {\r\n if (channelData[j]) sum += channelData[j] * channelData[j];\r\n }\r\n const rms = Math.sqrt(sum / step);\r\n const height = Math.min(100, Math.max(10, rms * 400));\r\n calculatedBars.push(height);\r\n }\r\n return calculatedBars;\r\n } catch (e) {\r\n console.error(\"Analysis error\", e);\r\n return Array.from({ length: 40 }, () => 20 + Math.random() * 60);\r\n }\r\n }\r\n\r\n /**\r\n * Handle sending a message\r\n */\r\n async function handleSend(message: string): Promise<ChatResponse> {\r\n // Add user message\r\n state.messages.push({ role: 'user', content: message });\r\n state.isLoading = true;\r\n render();\r\n\r\n try {\r\n const response = await client.chat(message);\r\n\r\n // Add assistant message\r\n state.messages.push({\r\n role: 'assistant',\r\n content: response.reply,\r\n products: response.products,\r\n });\r\n\r\n if (resolvedConfig.onMessage) {\r\n resolvedConfig.onMessage(message, response);\r\n }\r\n\r\n return response;\r\n } catch (error) {\r\n state.messages.push({\r\n role: 'assistant',\r\n content: 'Sorry, I encountered an error. Please try again.',\r\n });\r\n throw error;\r\n } finally {\r\n state.isLoading = false;\r\n render();\r\n }\r\n }\r\n\r\n /**\r\n * Open the widget\r\n */\r\n function open(): void {\r\n state.isOpen = true;\r\n render();\r\n resolvedConfig.onOpen?.();\r\n\r\n // Focus input\r\n setTimeout(() => {\r\n const input = container?.querySelector('.aicommerce-input') as HTMLInputElement;\r\n input?.focus();\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Close the widget\r\n */\r\n function close(): void {\r\n state.isOpen = false;\r\n render();\r\n resolvedConfig.onClose?.();\r\n }\r\n\r\n /**\r\n * Toggle the widget\r\n */\r\n function toggle(): void {\r\n if (state.isOpen) {\r\n close();\r\n } else {\r\n open();\r\n }\r\n }\r\n\r\n /**\r\n * Destroy the widget\r\n */\r\n function destroy(): void {\r\n if (container) {\r\n container.remove();\r\n container = null;\r\n }\r\n if (styleElement) {\r\n styleElement.remove();\r\n styleElement = null;\r\n }\r\n }\r\n\r\n /**\r\n * Update configuration\r\n */\r\n function updateConfig(newConfig: Partial<WidgetConfig>): void {\r\n Object.assign(resolvedConfig, newConfig);\r\n\r\n if (newConfig.primaryColor) {\r\n const styles = createWidgetStyles(resolvedConfig);\r\n if (styleElement) {\r\n styleElement.textContent = styles;\r\n }\r\n }\r\n\r\n render();\r\n }\r\n\r\n // Utility functions\r\n function escapeHtml(text: string): string {\r\n const div = document.createElement('div');\r\n div.textContent = text;\r\n return div.innerHTML;\r\n }\r\n\r\n function formatPrice(price: number, currency?: string): string {\r\n const symbols: Record<string, string> = {\r\n USD: '$', EUR: '€', GBP: '£', MAD: 'DH',\r\n SAR: 'SAR', AED: 'AED', JPY: '¥', CNY: '¥',\r\n };\r\n const symbol = symbols[currency || 'USD'] || currency || '$';\r\n return `${price.toFixed(2)} ${symbol}`;\r\n }\r\n\r\n // Initialize and return instance\r\n initialize();\r\n\r\n return {\r\n open,\r\n close,\r\n toggle,\r\n destroy,\r\n sendMessage: handleSend,\r\n updateConfig,\r\n };\r\n}\r\n\r\n/**\r\n * Global widget initialization for script tag usage\r\n */\r\nexport const AICommerceWidget = {\r\n init: createWidget,\r\n VERSION: '1.0.0',\r\n};\r\n\r\n// Auto-attach to window for UMD builds\r\nif (typeof window !== 'undefined') {\r\n (window as unknown as Record<string, unknown>).AICommerceWidget = AICommerceWidget;\r\n}\r\n","/**\r\n * AI Commerce SDK\r\n * \r\n * AI-powered product recommendations for e-commerce\r\n * \r\n * @packageDocumentation\r\n * @module @yassirbenmoussa/aicommerce-sdk\r\n * \r\n * @example\r\n * ```typescript\r\n * // npm usage - Client API\r\n * import { AICommerce } from '@yassirbenmoussa/aicommerce-sdk';\r\n * \r\n * const client = new AICommerce({ apiKey: 'your-api-key' });\r\n * const response = await client.chat('I need a laptop');\r\n * console.log(response.products);\r\n * ```\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Widget usage -->\r\n * <script src=\"https://cdn.aicommerce.dev/widget.min.js\"></script>\r\n * <script>\r\n * AICommerceWidget.init({\r\n * apiKey: 'your-api-key',\r\n * position: 'bottom-right',\r\n * theme: 'auto'\r\n * });\r\n * </script>\r\n * ```\r\n */\r\n\r\n// Export main client\r\nexport { AICommerce, AICommerceError } from './client';\r\n\r\n// Export widget\r\nexport { createWidget, AICommerceWidget } from './widget';\r\n\r\n// Export all types\r\nexport type {\r\n // Client types\r\n AICommerceConfig,\r\n ChatRequest,\r\n ChatResponse,\r\n ChatContext,\r\n Product,\r\n Session,\r\n APIError,\r\n EventType,\r\n EventCallback,\r\n // Widget types\r\n StoreConfig,\r\n WidgetConfig,\r\n WidgetInstance,\r\n} from './types';\r\n\r\n// Version\r\nexport const VERSION = '1.0.0';\r\n\r\n// For UMD builds, attach to window\r\nif (typeof window !== 'undefined') {\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerce = require('./client').AICommerce;\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerceError = require('./client').AICommerceError;\r\n // @ts-expect-error - Attaching to window for UMD\r\n window.AICommerceWidget = require('./widget').AICommerceWidget;\r\n}\r\n"]}
|