@akropolys/sdk 1.0.0 → 1.1.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commerce.ts","../src/api.ts","../src/stream.ts","../src/client.ts","../src/Provider.tsx","../src/hooks/useAkropolys.ts","../src/hooks/useSearch.ts","../src/hooks/useIngest.ts","../src/hooks/useListIngest.ts","../src/hooks/usePageIngest.ts","../src/hooks/useKiku.ts","../src/hooks/useCart.ts","../src/hooks/usePaymentPolling.ts"],"sourcesContent":["import { setSDKDefaultVertical } from './client';\nsetSDKDefaultVertical('commerce');\nexport * from './index';\n","import { Product, SearchResponse, IngestResponse, AkropolysError, CheckoutConfig, PaymentInitResponse, PaymentStatusResponse } from './types';\n\nconst MAX_RETRIES = 3;\nconst RETRY_DELAYS = [500, 1000, 2000]; // ms\n\nfunction log(level: 'info' | 'warn' | 'error', msg: string, data?: unknown) {\n const prefix = '[Akropolys]';\n if (level === 'error') console.error(prefix, msg, data ?? '');\n else if (level === 'warn') console.warn(prefix, msg, data ?? '');\n else console.log(prefix, msg, data ?? '');\n}\n\nasync function sleep(ms: number) {\n return new Promise(r => setTimeout(r, ms));\n}\n\nexport class AkropolysAPI {\n constructor(\n private apiUrl: string,\n private siteId: string,\n private apiToken: string,\n private getShopperId?: () => string | undefined,\n private getSessionId?: () => string | undefined,\n private vertical?: string\n ) {}\n\n private async post<T>(path: string, body: unknown, attempt = 0): Promise<T> {\n const url = `${this.apiUrl}${path}`;\n\n try {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Akropolys-Token': this.apiToken,\n 'X-Akropolys-Site': this.siteId,\n };\n\n const shopperId = this.getShopperId?.();\n if (shopperId) {\n headers['X-Akropolys-Shopper-Id'] = shopperId;\n }\n\n const sessionId = this.getSessionId?.();\n if (sessionId) {\n headers['X-Akropolys-Session-Id'] = sessionId;\n }\n\n if (typeof window !== 'undefined') {\n const phone = localStorage.getItem('akropolys_user_phone');\n if (phone) {\n headers['X-Akropolys-Shopper-Phone'] = phone;\n }\n }\n\n const res = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const text = await res.text();\n let message = text;\n try {\n const parsed = JSON.parse(text);\n if (parsed && typeof parsed.error === 'string') {\n message = parsed.error;\n }\n } catch {\n // keep original text\n }\n const err: AkropolysError = { status: res.status, message };\n\n // Don't retry 4xx — developer errors\n if (res.status >= 400 && res.status < 500) {\n log('error', `${path} failed [${res.status}]`, text);\n throw err;\n }\n\n // Retry 5xx\n if (attempt < MAX_RETRIES - 1) {\n log('warn', `${path} [${res.status}] retrying (${attempt + 1}/${MAX_RETRIES})...`);\n await sleep(RETRY_DELAYS[attempt]);\n return this.post(path, body, attempt + 1);\n }\n\n log('error', `${path} failed after ${MAX_RETRIES} attempts`, err);\n throw err;\n }\n\n return res.json();\n } catch (e) {\n // Network error (offline, DNS, etc.)\n if ((e as AkropolysError).status === undefined) {\n if (attempt < MAX_RETRIES - 1) {\n log('warn', `${path} network error, retrying (${attempt + 1}/${MAX_RETRIES})...`);\n await sleep(RETRY_DELAYS[attempt]);\n return this.post(path, body, attempt + 1);\n }\n log('error', `${path} unreachable after ${MAX_RETRIES} attempts`);\n }\n throw e;\n }\n }\n\n async ingest(product: Product): Promise<IngestResponse> {\n log('info', 'ingesting product', product.name);\n return this.post('/ingest', { siteId: this.siteId, product });\n }\n\n async ingestBatch(products: Product[]): Promise<IngestResponse> {\n log('info', `ingesting batch of ${products.length} products`);\n return this.post('/ingest/batch', { siteId: this.siteId, products });\n }\n\n async search(query: string, limit = 10): Promise<SearchResponse> {\n log('info', 'search query', query);\n return this.post('/search', { query, siteId: this.siteId, limit });\n }\n\n // Pure vector search — no LLM, instant results.\n async searchVector(query: string, limit = 10): Promise<SearchResponse> {\n return this.post('/search/vector', { query, siteId: this.siteId, limit });\n }\n\n // Autocomplete — pure in-memory Trie, <1ms, no Upstash call. Only true prefix matches.\n async searchAutocomplete(query: string, limit = 8): Promise<SearchResponse> {\n return this.post('/search/autocomplete', { query, siteId: this.siteId, limit });\n }\n\n // LLM chat — conversational search with history context.\n async chat(query: string, history: Array<{ role: 'user' | 'assistant'; content: string }> = []): Promise<{ answer: string; sources: any[]; intent?: string; checkout?: import('./types').CartPayload; action?: any }> {\n log('info', 'chat query', query);\n const path = !this.vertical || this.vertical === 'commerce' ? '/chat' : `/chat/${this.vertical}`;\n return this.post(path, { query, siteId: this.siteId, history });\n }\n\n // Streaming variant — returns the raw fetch Response.\n // The caller reads body as a ReadableStream of SSE frames.\n async chatStream(query: string, history: Array<{ role: 'user' | 'assistant'; content: string }> = [], signal?: AbortSignal): Promise<Response> {\n log('info', 'chatStream query', query);\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Akropolys-Token': this.apiToken,\n 'X-Akropolys-Site': this.siteId,\n };\n const shopperId = this.getShopperId?.();\n if (shopperId) headers['X-Akropolys-Shopper-Id'] = shopperId;\n const sessionId = this.getSessionId?.();\n if (sessionId) headers['X-Akropolys-Session-Id'] = sessionId;\n if (typeof window !== 'undefined') {\n const phone = localStorage.getItem('akropolys_user_phone');\n if (phone) headers['X-Akropolys-Shopper-Phone'] = phone;\n }\n const path = !this.vertical || this.vertical === 'commerce' ? '/chat/stream' : `/chat/stream/${this.vertical}`;\n const res = await fetch(`${this.apiUrl}${path}`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ query, siteId: this.siteId, history }),\n signal,\n });\n if (!res.ok || !res.body) {\n throw new Error(`Stream request failed: ${res.status}`);\n }\n return res;\n }\n\n // --- Cart System ---\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Akropolys-Token': this.apiToken,\n 'X-Akropolys-Site': this.siteId,\n };\n const shopperId = this.getShopperId?.();\n if (shopperId) headers['X-Akropolys-Shopper-Id'] = shopperId;\n const sessionId = this.getSessionId?.();\n if (sessionId) headers['X-Akropolys-Session-Id'] = sessionId;\n if (typeof window !== 'undefined') {\n const phone = localStorage.getItem('akropolys_user_phone');\n if (phone) {\n headers['X-Akropolys-Shopper-Phone'] = phone;\n }\n }\n return headers;\n }\n\n async getCart(): Promise<import('./types').CartPayload> {\n const res = await fetch(`${this.apiUrl}/cart?siteId=${this.siteId}`, {\n headers: this.buildHeaders()\n });\n if (!res.ok) throw new Error('Failed to fetch cart');\n return res.json();\n }\n\n async clearCart(): Promise<import('./types').CartPayload> {\n const res = await fetch(`${this.apiUrl}/cart?siteId=${this.siteId}`, {\n method: 'DELETE',\n headers: this.buildHeaders()\n });\n if (!res.ok) throw new Error('Failed to clear cart');\n return res.json();\n }\n\n async checkoutCart(): Promise<import('./types').CartPayload> {\n const res = await fetch(`${this.apiUrl}/cart/checkout`, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({ siteId: this.siteId })\n });\n if (!res.ok) throw new Error('Failed to checkout cart');\n return res.json();\n }\n\n async getCheckoutConfig(): Promise<CheckoutConfig> {\n const res = await fetch(`${this.apiUrl}/checkout/config?site_id=${this.siteId}`, {\n method: 'GET',\n headers: this.buildHeaders()\n });\n if (!res.ok) throw new Error('Failed to fetch checkout config');\n return res.json();\n }\n\n async initiatePayment(phoneNumber: string, email?: string, firstName?: string, lastName?: string): Promise<PaymentInitResponse> {\n const res = await fetch(`${this.apiUrl}/payment/initiate`, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({\n siteId: this.siteId,\n phoneNumber,\n email,\n firstName,\n lastName\n })\n });\n if (!res.ok) {\n const errText = await res.text();\n throw new Error('Failed to initiate payment: ' + errText);\n }\n return res.json();\n }\n\n async getPaymentStatus(ref: string): Promise<PaymentStatusResponse> {\n const res = await fetch(`${this.apiUrl}/payment/status?ref=${ref}`, {\n method: 'GET',\n headers: this.buildHeaders()\n });\n if (!res.ok) throw new Error('Failed to get payment status');\n return res.json();\n }\n}\n","import { CartPayload, ChatAction } from './types';\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n cartSnapshot?: CartPayload;\n actionType?: string;\n}\n\nexport interface ChatSource {\n id?: string;\n name: string;\n price?: string;\n currency?: string;\n category?: string;\n url?: string;\n image?: string;\n brand?: string;\n availability?: string;\n}\n\nexport interface ChatMetadata {\n intent: string;\n sources: ChatSource[];\n action?: ChatAction;\n checkout?: CartPayload;\n}\n\ninterface SSEFrame {\n event: string;\n data: string;\n}\n\nfunction parseSSEChunk(raw: string): SSEFrame[] {\n const frames: SSEFrame[] = [];\n const blocks = raw.split(/\\n\\n+/);\n for (const block of blocks) {\n if (!block.trim()) continue;\n let event = '';\n let data = '';\n for (const line of block.split('\\n')) {\n if (line.startsWith('event:')) event = line.slice(6).trim();\n else if (line.startsWith('data:')) data = line.slice(5);\n }\n if (data !== '') frames.push({ event, data });\n }\n return frames;\n}\n\nexport class KikuStream {\n private listeners: Record<string, Function[]> = {};\n private aborted = false;\n private responsePromise: Promise<Response>;\n private abortController: AbortController;\n\n constructor(responsePromise: Promise<Response>, abortController: AbortController) {\n this.responsePromise = responsePromise;\n this.abortController = abortController;\n this.startReading();\n }\n\n on(event: 'token' | 'meta' | 'done' | 'error', callback: Function): this {\n if (!this.listeners[event]) {\n this.listeners[event] = [];\n }\n this.listeners[event].push(callback);\n return this;\n }\n\n off(event: 'token' | 'meta' | 'done' | 'error', callback: Function): this {\n if (!this.listeners[event]) return this;\n this.listeners[event] = this.listeners[event].filter(cb => cb !== callback);\n return this;\n }\n\n destroy() {\n this.aborted = true;\n this.abortController.abort();\n }\n\n private emit(event: string, ...args: any[]) {\n const list = this.listeners[event];\n if (!list) return;\n for (const cb of list) {\n try {\n cb(...args);\n } catch (err) {\n console.error(`[Akropolys] Error in KikuStream event listener for \"${event}\":`, err);\n }\n }\n }\n\n private async startReading() {\n try {\n const response = await this.responsePromise;\n if (this.aborted) return;\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Response body is not readable');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n let accumulatedMessage = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done || this.aborted) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n const lastBoundary = buffer.lastIndexOf('\\n\\n');\n if (lastBoundary === -1) continue;\n\n const complete = buffer.slice(0, lastBoundary + 2);\n buffer = buffer.slice(lastBoundary + 2);\n\n const frames = parseSSEChunk(complete);\n\n for (const { event, data } of frames) {\n if (this.aborted) return;\n\n if (event === 'meta') {\n try {\n const meta: ChatMetadata = JSON.parse(data);\n this.emit('meta', meta);\n } catch {\n // ignore parse errors\n }\n continue;\n }\n\n if (event === 'done') {\n break;\n }\n\n if (event === 'error') {\n let msg = 'Stream error';\n try {\n msg = JSON.parse(data).error ?? msg;\n } catch {\n msg = data;\n }\n throw new Error(msg);\n }\n\n // Plain token — convert literal \\n to actual newline\n const token = data.replace(/\\\\n/g, '\\n');\n accumulatedMessage += token;\n this.emit('token', token);\n }\n }\n\n if (!this.aborted) {\n this.emit('done', accumulatedMessage);\n }\n } catch (err: any) {\n if (!this.aborted) {\n this.emit('error', err);\n }\n }\n }\n}\n","import { AkropolysConfig, Product, RawProductInput } from './types';\nimport { AkropolysAPI } from './api';\nimport { KikuStream } from './stream';\n\ndeclare const process: any;\n\nlet defaultVertical: string = 'commerce';\nexport function setSDKDefaultVertical(v: string) {\n defaultVertical = v;\n}\n\nfunction getEnvVar(key: string): string | undefined {\n if (key === 'NEXT_PUBLIC_AKROPOLYS_SITE_ID') {\n try { return process.env.NEXT_PUBLIC_AKROPOLYS_SITE_ID; } catch { /* ignore */ }\n }\n if (key === 'NEXT_PUBLIC_AKROPOLYS_API_URL') {\n try { return process.env.NEXT_PUBLIC_AKROPOLYS_API_URL; } catch { /* ignore */ }\n }\n if (key === 'NEXT_PUBLIC_AKROPOLYS_API_TOKEN') {\n try { return process.env.NEXT_PUBLIC_AKROPOLYS_API_TOKEN; } catch { /* ignore */ }\n }\n\n // Fallback check for Vite (import.meta.env)\n try {\n const metaEnv = (import.meta as any).env;\n if (metaEnv) {\n if (key === 'NEXT_PUBLIC_AKROPOLYS_SITE_ID') return metaEnv.NEXT_PUBLIC_AKROPOLYS_SITE_ID || metaEnv.VITE_AKROPOLYS_SITE_ID;\n if (key === 'NEXT_PUBLIC_AKROPOLYS_API_URL') return metaEnv.NEXT_PUBLIC_AKROPOLYS_API_URL || metaEnv.VITE_AKROPOLYS_API_URL;\n if (key === 'NEXT_PUBLIC_AKROPOLYS_API_TOKEN') return metaEnv.NEXT_PUBLIC_AKROPOLYS_API_TOKEN || metaEnv.VITE_AKROPOLYS_API_TOKEN;\n }\n } catch { /* ignore */ }\n\n if (typeof globalThis !== 'undefined') {\n const g = globalThis as any;\n if (g.process && g.process.env) {\n return g.process.env[key];\n }\n }\n return undefined;\n}\n\nfunction mapRawProduct(input: RawProductInput): Product | null {\n const name = input.name || input.title || input.productName || '';\n \n let price = '';\n let priceNumeric: number | undefined = undefined;\n\n if (input.price !== undefined) {\n if (typeof input.price === 'number') {\n priceNumeric = input.price;\n price = String(input.price);\n } else {\n price = input.price;\n const num = parseFloat(input.price.replace(/[^0-9.]/g, ''));\n priceNumeric = isNaN(num) ? undefined : num;\n }\n }\n if (input.priceNumeric !== undefined) {\n priceNumeric = input.priceNumeric;\n }\n\n let url = input.url || '';\n if (!url && typeof window !== 'undefined') {\n url = window.location.href;\n }\n\n let slug = input.slug || input.id || input.productId || '';\n if (!slug && url) {\n slug = url.split('/').filter(Boolean).pop() || '';\n }\n if (!slug && name) {\n slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');\n }\n\n let images: string[] = [];\n if (input.images) {\n images = input.images;\n } else if (input.image) {\n images = [input.image];\n } else if (input.listing_agent_photo) {\n // Property vertical: listing_agent_photo is the primary cover image\n images = [input.listing_agent_photo];\n } else if (input.thumbnail) {\n images = [input.thumbnail];\n }\n\n if (!name) {\n console.warn('[Akropolys] Validation warning: Product name/title is missing. Skipping:', input);\n return null;\n }\n if (!price) {\n console.warn('[Akropolys] Validation warning: Product price is missing. Skipping:', input);\n return null;\n }\n if (!url) {\n console.warn('[Akropolys] Validation warning: Product URL is missing. Skipping:', input);\n return null;\n }\n\n const coreKeys = new Set([\n 'name', 'title', 'productName', 'price', 'priceNumeric', 'url', 'image', 'thumbnail', \n 'images', 'slug', 'id', 'productId', 'brand', 'description', 'originalPrice', \n 'discount', 'currency', 'stock', 'availability', 'rating', 'reviewCount', \n 'category', 'subCategory', 'tags', 'specs', 'metadata'\n ]);\n\n const metadata: Record<string, any> = { ...input.metadata };\n for (const [key, value] of Object.entries(input)) {\n if (!coreKeys.has(key) && value !== undefined) {\n metadata[key] = value;\n }\n }\n\n return {\n name,\n price,\n url,\n brand: input.brand,\n description: input.description,\n originalPrice: input.originalPrice,\n discount: input.discount,\n currency: input.currency ?? 'KES',\n stock: input.stock,\n availability: input.availability,\n rating: input.rating,\n reviewCount: input.reviewCount,\n category: input.category,\n subCategory: input.subCategory,\n tags: input.tags,\n images: images.length > 0 ? images : undefined,\n specs: input.specs,\n priceNumeric,\n slug,\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n };\n}\n\nfunction generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nexport class AkropolysClient {\n readonly api: AkropolysAPI;\n readonly vertical: string;\n private ingestQueue: Product[] = [];\n private ingestTimer: ReturnType<typeof setTimeout> | null = null;\n private ingestedUrls = new Set<string>();\n private onlineHandler: (() => void) | null = null;\n private shopperId?: string;\n private sessionId: string = '';\n private authLoading?: boolean;\n public onCheckout?: (cart: import('./types').CartPayload) => void;\n public onError?: (error: import('./types').AkropolysError) => void;\n\n private static INGEST_CACHE_KEY = 'akropolys_ingested_v2';\n private static INGEST_CACHE_TTL = 24 * 60 * 60 * 1000; // 24h\n\n private loadIngestedCache() {\n if (typeof window === 'undefined') return;\n try {\n const raw = localStorage.getItem(AkropolysClient.INGEST_CACHE_KEY);\n if (!raw) return;\n const { ts, urls }: { ts: number; urls: string[] } = JSON.parse(raw);\n if (Date.now() - ts > AkropolysClient.INGEST_CACHE_TTL) {\n localStorage.removeItem(AkropolysClient.INGEST_CACHE_KEY);\n return;\n }\n this.ingestedUrls = new Set(urls);\n } catch { /* ignore */ }\n }\n\n private saveIngestedCache() {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(\n AkropolysClient.INGEST_CACHE_KEY,\n JSON.stringify({ ts: Date.now(), urls: [...this.ingestedUrls] })\n );\n } catch { /* ignore */ }\n }\n\n constructor(config: AkropolysConfig) {\n const siteId = config.siteId || getEnvVar('NEXT_PUBLIC_AKROPOLYS_SITE_ID') || '';\n const apiUrl = config.apiUrl || getEnvVar('NEXT_PUBLIC_AKROPOLYS_API_URL') || '';\n const apiToken = config.apiToken || getEnvVar('NEXT_PUBLIC_AKROPOLYS_API_TOKEN') || '';\n\n // Runtime validation — fail loudly so misconfiguration is never silent\n if (!siteId) console.error('[Akropolys] Missing siteId. Set it via <AkropolysProvider siteId=\"...\"> or NEXT_PUBLIC_AKROPOLYS_SITE_ID.');\n if (!apiUrl) console.error('[Akropolys] Missing apiUrl. Set it via <AkropolysProvider apiUrl=\"...\"> or NEXT_PUBLIC_AKROPOLYS_API_URL.');\n if (!apiToken) console.error('[Akropolys] Missing apiToken. Set it via <AkropolysProvider apiToken=\"...\"> or NEXT_PUBLIC_AKROPOLYS_API_TOKEN.');\n\n this.shopperId = config.shopperId;\n this.authLoading = config.authLoading;\n this.onCheckout = config.onCheckout;\n this.onError = config.onError;\n this.vertical = config.vertical || defaultVertical;\n this.initSession();\n this.loadIngestedCache();\n\n this.api = new AkropolysAPI(\n apiUrl,\n siteId,\n apiToken,\n () => this.getShopperId(),\n () => this.sessionId,\n this.vertical\n );\n instance = this;\n\n if (typeof window !== 'undefined') {\n this.onlineHandler = () => {\n console.log('[Akropolys] Connectivity restored, flushing queued ingestions.');\n this.flushQueue();\n };\n window.addEventListener('online', this.onlineHandler);\n }\n }\n\n chat(query: string, history: Array<{ role: 'user' | 'assistant'; content: string }> = []): KikuStream {\n const abortController = new AbortController();\n const responsePromise = this.api.chatStream(query, history, abortController.signal);\n return new KikuStream(responsePromise, abortController);\n }\n\n reRegister() {\n instance = this;\n }\n\n setShopperId(id: string | undefined) {\n this.shopperId = id;\n if (!this.authLoading) {\n this.flushQueue();\n }\n }\n\n setAuthLoading(loading: boolean) {\n const wasLoading = this.authLoading;\n this.authLoading = loading;\n if (wasLoading && !loading) {\n this.flushQueue();\n }\n }\n\n getShopperId(): string | undefined {\n return this.shopperId || 'guest_' + this.sessionId;\n }\n\n getSessionId(): string {\n return this.sessionId;\n }\n\n private initSession() {\n if (typeof window !== 'undefined' && window.sessionStorage) {\n try {\n let sid = window.sessionStorage.getItem('akropolys_session_id');\n if (!sid) {\n sid = generateUUID();\n window.sessionStorage.setItem('akropolys_session_id', sid);\n }\n this.sessionId = sid;\n return;\n } catch (e) {\n // Fallback if sessionStorage is disabled or private mode\n }\n }\n this.sessionId = generateUUID();\n }\n\n destroy() {\n if (typeof window !== 'undefined' && this.onlineHandler) {\n window.removeEventListener('online', this.onlineHandler);\n this.onlineHandler = null;\n }\n if (this.ingestTimer) {\n clearTimeout(this.ingestTimer);\n this.ingestTimer = null;\n }\n if (instance === this) instance = null;\n }\n\n async queueIngest(rawProduct: RawProductInput): Promise<void> {\n const product = mapRawProduct(rawProduct);\n if (!product) return;\n\n if (this.ingestedUrls.has(product.url)) {\n return; // already indexed in this session or today — skip\n }\n this.ingestedUrls.add(product.url);\n this.saveIngestedCache();\n\n this.ingestQueue.push(product);\n this.scheduleFlush();\n }\n\n async queueIngestBatch(rawProducts: RawProductInput[]): Promise<void> {\n rawProducts.forEach(p => {\n const product = mapRawProduct(p);\n if (!product) return;\n\n if (this.ingestedUrls.has(product.url)) {\n return;\n }\n this.ingestedUrls.add(product.url);\n this.ingestQueue.push(product);\n });\n\n if (this.ingestQueue.length > 0) {\n this.saveIngestedCache();\n this.scheduleFlush();\n }\n }\n\n private scheduleFlush() {\n if (this.ingestTimer) return;\n this.ingestTimer = setTimeout(() => {\n this.flushQueue();\n }, 300);\n }\n\n private async flushQueue() {\n this.ingestTimer = null;\n if (this.ingestQueue.length === 0) return;\n\n if (this.authLoading) {\n console.log('[Akropolys] Authentication is loading. Deferring ingestion flush.');\n return;\n }\n\n if (typeof navigator !== 'undefined' && !navigator.onLine) {\n console.warn('[Akropolys] Browser offline. Postponing ingestion.');\n return;\n }\n\n const batch = [...this.ingestQueue];\n this.ingestQueue = [];\n\n try {\n await this.api.ingestBatch(batch);\n } catch (e: any) {\n const akropolysError = {\n status: e.status || 500,\n message: e.message || 'Unknown network error'\n };\n\n if (this.onError) {\n try {\n this.onError(akropolysError);\n } catch (err) {\n console.error('[Akropolys] Error inside onError callback:', err);\n }\n }\n\n if (e.status && e.status >= 400 && e.status < 500) {\n console.error('[Akropolys] Ingestion discarded due to client error:', e.message);\n return;\n }\n\n // Re-queue and schedule another flush so items are not stuck forever\n console.warn('[Akropolys] Ingestion failed. Re-queuing to retry.', e);\n this.ingestQueue = [...batch, ...this.ingestQueue];\n this.scheduleFlush();\n }\n }\n}\n\nlet instance: AkropolysClient | null = null;\n\nexport function initAkropolys(config: AkropolysConfig): AkropolysClient {\n instance = new AkropolysClient(config);\n return instance;\n}\n\nexport function getAkropolysClient(): AkropolysClient {\n if (!instance) {\n const siteId = getEnvVar('NEXT_PUBLIC_AKROPOLYS_SITE_ID');\n const apiUrl = getEnvVar('NEXT_PUBLIC_AKROPOLYS_API_URL');\n const apiToken = getEnvVar('NEXT_PUBLIC_AKROPOLYS_API_TOKEN');\n\n if (siteId && apiUrl && apiToken) {\n instance = new AkropolysClient({ siteId, apiUrl, apiToken });\n } else {\n throw new Error('[Akropolys] Call initAkropolys() or set NEXT_PUBLIC_AKROPOLYS_* environment variables before using the client.');\n }\n }\n return instance;\n}\n","import React, { createContext, useContext, useEffect, useRef } from 'react';\nimport { AkropolysClient, getAkropolysClient } from './client';\nimport { AkropolysConfig } from './types';\n\nexport const AkropolysContext = createContext<AkropolysClient | null>(null);\n\ninterface AkropolysProviderProps extends AkropolysConfig {\n children: React.ReactNode;\n}\n\nexport function AkropolysProvider({\n siteId,\n apiUrl,\n apiToken,\n shopperId,\n vertical,\n authLoading,\n onCheckout,\n onError,\n children\n}: AkropolysProviderProps) {\n const clientRef = useRef<AkropolysClient | null>(null);\n\n if (!clientRef.current) {\n clientRef.current = new AkropolysClient({\n siteId,\n apiUrl,\n apiToken,\n shopperId,\n vertical,\n authLoading,\n onCheckout,\n onError\n });\n } else {\n clientRef.current.reRegister();\n }\n\n // Update shopperId dynamically when it changes\n useEffect(() => {\n clientRef.current?.setShopperId(shopperId);\n }, [shopperId]);\n\n // Update authLoading dynamically when it changes\n useEffect(() => {\n clientRef.current?.setAuthLoading(!!authLoading);\n }, [authLoading]);\n\n // Update dynamic callbacks\n useEffect(() => {\n if (clientRef.current) {\n clientRef.current.onError = onError;\n clientRef.current.onCheckout = onCheckout;\n }\n }, [onError, onCheckout]);\n\n // Ensure active instance is registered on mount\n useEffect(() => {\n clientRef.current?.reRegister();\n }, []);\n\n // Clean up\n useEffect(() => {\n return () => {\n clientRef.current?.destroy();\n };\n }, []);\n\n return (\n <AkropolysContext.Provider value={clientRef.current}>\n {children}\n </AkropolysContext.Provider>\n );\n}\n\nexport function useAkropolysContext(): AkropolysClient {\n const context = useContext(AkropolysContext);\n if (!context) {\n return getAkropolysClient();\n }\n return context;\n}\n","import { useRef } from 'react';\nimport { AkropolysConfig } from '../types';\nimport { AkropolysClient, initAkropolys } from '../client';\n\n/**\n * @deprecated Use <AkropolysProvider> instead to avoid SSR issues.\n */\nexport function useAkropolys(config: AkropolysConfig): AkropolysClient {\n const clientRef = useRef<AkropolysClient | null>(null);\n\n if (!clientRef.current) {\n console.warn('[Akropolys] useAkropolys() is deprecated. Please wrap your application in <AkropolysProvider> instead.');\n clientRef.current = initAkropolys(config);\n }\n\n return clientRef.current;\n}\n","import { useState, useCallback, useRef } from 'react';\nimport { SearchResult } from '../types';\nimport { useAkropolysContext } from '../Provider';\n\ninterface UseSearchReturn {\n results: SearchResult[];\n loading: boolean;\n error: string | null;\n search: (query: string, limit?: number) => Promise<void>;\n clear: () => void;\n}\n\nexport function useSearch(): UseSearchReturn {\n const client = useAkropolysContext();\n const [results, setResults] = useState<SearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n // Generation counter so stale responses from any in-flight requests don't overwrite newer ones\n const genRef = useRef(0);\n\n const search = useCallback(async (query: string, limit = 8) => {\n if (!query.trim()) { setResults([]); setLoading(false); return; }\n const gen = ++genRef.current;\n setLoading(true);\n setError(null);\n try {\n // searchAutocomplete = pure in-memory Trie, <1ms, no Upstash\n const res = await client.api.searchAutocomplete(query, limit);\n if (gen === genRef.current) {\n setResults(res.results ?? []);\n }\n } catch (e: unknown) {\n if (gen === genRef.current) {\n let msg = (e as any)?.message ?? 'Search failed';\n try {\n const parsed = JSON.parse(msg);\n if (parsed && parsed.error) {\n msg = parsed.error;\n }\n } catch {\n // keep original text\n }\n setError(msg);\n }\n } finally {\n if (gen === genRef.current) setLoading(false);\n }\n }, [client]);\n\n const clear = useCallback(() => {\n genRef.current++;\n setResults([]);\n setError(null);\n setLoading(false);\n }, []);\n\n return { results, loading, error, search, clear };\n}\n","import { useCallback } from 'react';\r\nimport { RawProductInput } from '../types';\r\nimport { useAkropolysContext } from '../Provider';\r\n\r\ninterface UseIngestReturn {\r\n ingest: (product: RawProductInput) => void;\r\n ingestBatch: (products: RawProductInput[]) => void;\r\n /**\r\n * @deprecated Ingest is fire-and-forget. This is always `false` and will be\r\n * removed in the next major version. Remove it from your destructuring.\r\n */\r\n loading: false;\r\n /**\r\n * @deprecated Ingest is fire-and-forget. This is always `null` and will be\r\n * removed in the next major version. Remove it from your destructuring.\r\n */\r\n error: null;\r\n}\r\n\r\n/**\r\n * useIngest — queue products for ingestion into the Huskel vector index.\r\n *\r\n * Ingest is intentionally **fire-and-forget**. The SDK has a built-in 24h\r\n * dedup cache (per URL) and an offline retry queue, so you don't need to\r\n * track loading/error state.\r\n *\r\n * ⚠️ Always call `ingestBatch` inside a `useEffect` with a ref guard to\r\n * prevent duplicate calls on re-renders (e.g. when auth state resolves):\r\n *\r\n * @example\r\n * const { ingestBatch } = useIngest();\r\n * const hasIngested = useRef(false);\r\n *\r\n * useEffect(() => {\r\n * if (hasIngested.current) return;\r\n * hasIngested.current = true;\r\n * ingestBatch(products);\r\n * // eslint-disable-next-line react-hooks/exhaustive-deps\r\n * }, []);\r\n */\r\n// Module-level cache to prevent duplicate ingestion requests in the same session\r\nconst recentlyIngested = new Set<string>();\r\n\r\nfunction getProductKey(p: RawProductInput): string | null {\r\n return p.url || p.id || p.productId || p.slug || p.name || p.title || p.productName || null;\r\n}\r\n\r\nexport function useIngest(): UseIngestReturn {\r\n const client = useAkropolysContext();\r\n\r\n const ingest = useCallback((product: RawProductInput) => {\r\n const key = getProductKey(product);\r\n if (key) {\r\n if (recentlyIngested.has(key)) return;\r\n recentlyIngested.add(key);\r\n }\r\n // Fire-and-forget — errors are logged internally by the client\r\n client.queueIngest(product).catch(() => {});\r\n }, [client]);\r\n\r\n const ingestBatch = useCallback((products: RawProductInput[]) => {\r\n const toIngest = products.filter(p => {\r\n const key = getProductKey(p);\r\n if (!key) return true;\r\n if (recentlyIngested.has(key)) return false;\r\n recentlyIngested.add(key);\r\n return true;\r\n });\r\n\r\n if (!toIngest.length) return;\r\n // Fire-and-forget — errors are logged internally by the client\r\n client.queueIngestBatch(toIngest).catch(() => {});\r\n }, [client]);\r\n\r\n // loading/error kept as stable literals for backwards compatibility.\r\n // They no longer trigger re-renders, which was the root cause of 429 floods.\r\n return { ingest, ingestBatch, loading: false, error: null };\r\n}\r\n","import { useEffect, useRef } from 'react';\nimport { RawProductInput } from '../types';\nimport { useIngest } from './useIngest';\n\n/**\n * useListIngest — drop this into any catalog or list page.\n * It automatically ingests all items in the array, using a built-in\n * component-lifecycle ref guard to prevent duplicate calls during mounts.\n *\n * @example\n * export function CategoryPage({ products }) {\n * useListIngest(products);\n * return <ProductGrid products={products} />;\n * }\n */\nexport function useListIngest(products: RawProductInput[] | null | undefined): void {\n const { ingestBatch } = useIngest();\n const processedIdsRef = useRef<Set<string>>(new Set());\n\n // Create a stable dependency key representing the items currently in the list\n const listKey = (products || [])\n .map((p) => p.url || p.id || p.productId || p.slug || p.name || p.title || p.productName || '')\n .join(',');\n\n useEffect(() => {\n if (!products || !products.length) return;\n\n // Filter out items that have already been queued in this component's mount lifecycle\n const newItems = products.filter((item) => {\n const id = item.id || item.productId || item.url || item.slug || item.name || item.title || item.productName;\n if (!id) return true; // Let the queue handle validation/deduplication if no identifier is present\n if (processedIdsRef.current.has(id)) {\n return false;\n }\n processedIdsRef.current.add(id);\n return true;\n });\n\n if (newItems.length > 0) {\n ingestBatch(newItems);\n }\n }, [listKey, ingestBatch]);\n}\n","import { useEffect, useRef } from 'react';\nimport { RawProductInput } from '../types';\nimport { getAkropolysClient } from '../client';\n\n/**\n * usePageIngest — drop this into any product page component.\n * The moment a customer's browser renders the page, the product is\n * automatically captured and queued for ingestion into the vector index.\n *\n * No configuration needed beyond <AkropolysProvider> in your layout.\n *\n * @example\n * // Product detail page — Next.js or React\n * export function ProductPage({ product }) {\n * usePageIngest({\n * name: product.title,\n * price: product.price,\n * url: window.location.href,\n * images: [product.thumbnail],\n * category: product.category,\n * });\n * return <div>...</div>;\n * }\n */\nexport function usePageIngest(product: RawProductInput | null | undefined): void {\n // Use url as the stable key — avoids re-ingesting on unrelated re-renders\n const ingestedRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (!product) return;\n\n // Resolve URL — falls back to window.location if not provided\n const url =\n product.url ||\n (typeof window !== 'undefined' ? window.location.href : '');\n\n // Guard: only ingest once per URL per component lifecycle\n if (ingestedRef.current === url) return;\n ingestedRef.current = url;\n\n try {\n getAkropolysClient().queueIngest({ ...product, url });\n } catch {\n // Client not initialised — silently skip\n }\n }, [product?.url ?? product?.name]);\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport { useAkropolysContext } from '../Provider';\nimport { ChatMessage, ChatSource } from '../stream';\nimport { ChatAction } from '../types';\n\ninterface UseKikuOptions {\n initialMessages?: ChatMessage[];\n onToken?: (token: string) => void;\n onMeta?: (meta: any) => void;\n onDone?: (fullMessage: string) => void;\n onError?: (error: Error) => void;\n}\n\ninterface UseKikuReturn {\n messages: ChatMessage[];\n sources: ChatSource[];\n loading: boolean;\n streaming: boolean;\n error: string | null;\n lastAction: ChatAction | null;\n lastIntent: string | null;\n send: (query: string, displayQuery?: string) => Promise<void>;\n reset: () => void;\n}\n\nexport function useKiku(options: UseKikuOptions = {}): UseKikuReturn {\n const client = useAkropolysContext();\n const [messages, setMessages] = useState<ChatMessage[]>(options.initialMessages ?? []);\n const [sources, setSources] = useState<ChatSource[]>([]);\n const [loading, setLoading] = useState(false);\n const [streaming, setStreaming] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [lastAction, setLastAction] = useState<ChatAction | null>(null);\n const [lastIntent, setLastIntent] = useState<string | null>(null);\n const activeStreamRef = useRef<any | null>(null);\n\n // Keep references to options callbacks to avoid hook dependencies issues\n const onTokenRef = useRef(options.onToken);\n const onMetaRef = useRef(options.onMeta);\n const onDoneRef = useRef(options.onDone);\n const onErrorRef = useRef(options.onError);\n\n useEffect(() => {\n onTokenRef.current = options.onToken;\n onMetaRef.current = options.onMeta;\n onDoneRef.current = options.onDone;\n onErrorRef.current = options.onError;\n }, [options.onToken, options.onMeta, options.onDone, options.onError]);\n\n // Clean up stream on unmount\n useEffect(() => {\n return () => {\n activeStreamRef.current?.destroy();\n };\n }, []);\n\n const send = useCallback(async (query: string, displayQuery?: string) => {\n if (!query.trim() || loading) return;\n\n // Abort previous stream if any\n activeStreamRef.current?.destroy();\n\n // Optimistically add user message\n const userMsg: ChatMessage = { role: 'user', content: displayQuery ?? query };\n setMessages(prev => [...prev, userMsg]);\n setLoading(true);\n setStreaming(false);\n setError(null);\n\n try {\n // History excludes the message we just added\n const history = messages.map(m => ({ role: m.role, content: m.content }));\n \n // Get the stream\n const stream = client.chat(query, history);\n activeStreamRef.current = stream;\n\n let messageInitialized = false;\n let lastMeta: any = null;\n\n stream.on('meta', (meta: any) => {\n lastMeta = meta;\n setSources(meta.sources ?? []);\n if (meta.intent) setLastIntent(meta.intent);\n if (meta.action) setLastAction(meta.action);\n \n onMetaRef.current?.(meta);\n });\n\n stream.on('token', (token: string) => {\n if (!messageInitialized) {\n setLoading(false);\n setStreaming(true);\n setMessages(prev => [...prev, { role: 'assistant', content: token }]);\n messageInitialized = true;\n } else {\n setMessages(prev => {\n const next = [...prev];\n if (next.length > 0 && next[next.length - 1].role === 'assistant') {\n next[next.length - 1] = {\n ...next[next.length - 1],\n content: next[next.length - 1].content + token,\n };\n }\n return next;\n });\n }\n\n onTokenRef.current?.(token);\n });\n\n stream.on('done', (fullMessage: string) => {\n setLoading(false);\n setStreaming(false);\n\n const metaAction = lastMeta?.action;\n const metaCheckout = lastMeta?.checkout;\n\n const isCartAction = metaAction?.type === 'add_to_cart'\n || metaAction?.type === 'remove_from_cart'\n || metaAction?.type === 'clear_cart'\n || metaAction?.type === 'view_cart';\n\n if (isCartAction || metaCheckout) {\n setMessages(prev => {\n const next = [...prev];\n if (next.length > 0 && next[next.length - 1].role === 'assistant') {\n next[next.length - 1] = {\n ...next[next.length - 1],\n cartSnapshot: metaCheckout,\n actionType: metaAction?.type,\n };\n }\n return next;\n });\n \n window.dispatchEvent(new CustomEvent('akropolys:cart_updated', { detail: metaCheckout }));\n }\n\n if (metaAction?.type === 'checkout') {\n window.dispatchEvent(new CustomEvent('akropolys:trigger_checkout', { detail: metaCheckout }));\n }\n if (metaAction?.type === 'awaiting_payment') {\n window.dispatchEvent(new CustomEvent('akropolys:awaiting_payment', { detail: metaAction }));\n }\n\n if (metaCheckout && client.onCheckout) {\n client.onCheckout(metaCheckout);\n }\n\n onDoneRef.current?.(fullMessage);\n });\n\n stream.on('error', (err: Error) => {\n setLoading(false);\n setStreaming(false);\n setError(err.message);\n // Remove the user query from message history on failure\n setMessages(prev => prev.slice(0, -1));\n onErrorRef.current?.(err);\n });\n\n } catch (err: any) {\n setLoading(false);\n setStreaming(false);\n setError(err?.message ?? 'Chat request failed');\n setMessages(prev => prev.slice(0, -1));\n onErrorRef.current?.(err);\n }\n }, [client, messages, loading]);\n\n const reset = useCallback(() => {\n activeStreamRef.current?.destroy();\n setMessages([]);\n setSources([]);\n setStreaming(false);\n setError(null);\n setLoading(false);\n setLastAction(null);\n setLastIntent(null);\n }, []);\n\n return { messages, sources, loading, streaming, error, lastAction, lastIntent, send, reset };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { useAkropolysContext } from '../Provider';\nimport { CartPayload } from '../types';\n\nexport function useCart() {\n const client = useAkropolysContext();\n const [cart, setCart] = useState<CartPayload | null>(null);\n const [loading, setLoading] = useState(false);\n\n const shopperId = client.getShopperId();\n\n const fetchCart = useCallback(async () => {\n if (!shopperId) return;\n setLoading(true);\n try {\n const res = await client.api.getCart();\n setCart(res);\n } catch (e) {\n console.error('[Akropolys] Failed to fetch cart', e);\n } finally {\n setLoading(false);\n }\n }, [client, shopperId]);\n\n useEffect(() => {\n fetchCart();\n \n const handleCartUpdate = (e: any) => {\n if (e.detail) {\n setCart(e.detail);\n } else {\n fetchCart();\n }\n };\n if (typeof window !== 'undefined') {\n window.addEventListener('akropolys:cart_updated', handleCartUpdate as EventListener);\n return () => window.removeEventListener('akropolys:cart_updated', handleCartUpdate as EventListener);\n }\n }, [fetchCart, shopperId]);\n\n return { cart, loading, fetchCart };\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { AkropolysAPI } from '../api';\n\nexport interface UsePaymentPollingProps {\n client: AkropolysAPI;\n merchantReference: string | null;\n onSuccess?: () => void;\n onFailure?: (errorMsg?: string) => void;\n intervalMs?: number;\n timeoutMs?: number;\n}\n\nexport function usePaymentPolling({\n client,\n merchantReference,\n onSuccess,\n onFailure,\n intervalMs = 3000,\n timeoutMs = 300000, // 5 minutes default\n}: UsePaymentPollingProps) {\n const [status, setStatus] = useState<'IDLE' | 'PENDING' | 'COMPLETED' | 'FAILED'>('IDLE');\n const [error, setError] = useState<string | null>(null);\n\n const onSuccessRef = useRef(onSuccess);\n const onFailureRef = useRef(onFailure);\n\n useEffect(() => {\n onSuccessRef.current = onSuccess;\n onFailureRef.current = onFailure;\n }, [onSuccess, onFailure]);\n\n useEffect(() => {\n if (!merchantReference) {\n setStatus('IDLE');\n setError(null);\n return;\n }\n\n setStatus('PENDING');\n setError(null);\n\n const startTime = Date.now();\n let timerId: ReturnType<typeof setTimeout> | null = null;\n\n async function checkStatus() {\n try {\n if (Date.now() - startTime >= timeoutMs) {\n setStatus('FAILED');\n setError('Payment session timed out');\n if (onFailureRef.current) onFailureRef.current('Payment session timed out');\n return;\n }\n\n const res = await client.getPaymentStatus(merchantReference as string);\n \n if (res.status === 'COMPLETED') {\n setStatus('COMPLETED');\n if (onSuccessRef.current) onSuccessRef.current();\n } else if (res.status === 'FAILED') {\n setStatus('FAILED');\n setError('Payment failed');\n if (onFailureRef.current) onFailureRef.current('Payment failed');\n } else {\n // Keep polling\n timerId = setTimeout(checkStatus, intervalMs);\n }\n } catch (err: any) {\n console.error('[Akropolys Polling Error]', err);\n // Treat transient network/parsing errors gracefully and retry\n timerId = setTimeout(checkStatus, intervalMs);\n }\n }\n\n // Start polling\n timerId = setTimeout(checkStatus, intervalMs);\n\n return () => {\n if (timerId) {\n clearTimeout(timerId);\n }\n };\n }, [client, merchantReference, intervalMs, timeoutMs]);\n\n return { status, error };\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","import_react","import_react","import_react","import_react","import_react"]}
1
+ {"version":3,"sources":["../src/commerce.ts","../src/api.ts","../src/stream.ts","../src/client.ts","../src/Provider.tsx","../src/hooks/useAkropolys.ts","../src/hooks/useSearch.ts","../src/hooks/useIngest.ts","../src/utils/TTLCache.ts","../src/hooks/useListIngest.ts","../src/hooks/usePageIngest.ts","../src/hooks/useKiku.ts","../src/hooks/useCart.ts","../src/hooks/usePaymentPolling.ts"],"sourcesContent":["import { setSDKDefaultVertical } from './client';\nsetSDKDefaultVertical('commerce');\nexport * from './index';\n","import { Product, SearchResponse, IngestResponse, AkropolysError, CheckoutConfig, PaymentInitResponse, PaymentStatusResponse } from './types';\n\nconst MAX_RETRIES = 3;\nconst RETRY_DELAYS = [500, 1000, 2000]; // ms\n\nfunction log(level: 'info' | 'warn' | 'error', msg: string, data?: unknown) {\n const prefix = '[Akropolys]';\n if (level === 'error') console.error(prefix, msg, data ?? '');\n else if (level === 'warn') console.warn(prefix, msg, data ?? '');\n else console.log(prefix, msg, data ?? '');\n}\n\nasync function sleep(ms: number) {\n return new Promise(r => setTimeout(r, ms));\n}\n\nexport class AkropolysAPI {\n constructor(\n private apiUrl: string,\n private siteId: string,\n private apiToken: string,\n private getShopperId?: () => string | undefined,\n private getSessionId?: () => string | undefined,\n private vertical?: string\n ) {}\n\n private async post<T>(path: string, body: unknown, attempt = 0): Promise<T> {\n const url = `${this.apiUrl}${path}`;\n\n try {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Akropolys-Token': this.apiToken,\n 'X-Akropolys-Site': this.siteId,\n };\n\n const shopperId = this.getShopperId?.();\n if (shopperId) {\n headers['X-Akropolys-Shopper-Id'] = shopperId;\n }\n\n const sessionId = this.getSessionId?.();\n if (sessionId) {\n headers['X-Akropolys-Session-Id'] = sessionId;\n }\n\n if (typeof window !== 'undefined') {\n const phone = localStorage.getItem('akropolys_user_phone');\n if (phone) {\n headers['X-Akropolys-Shopper-Phone'] = phone;\n }\n }\n\n const res = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const text = await res.text();\n let message = text;\n try {\n const parsed = JSON.parse(text);\n if (parsed && typeof parsed.error === 'string') {\n message = parsed.error;\n }\n } catch {\n // keep original text\n }\n const err: AkropolysError = { status: res.status, message };\n\n // Don't retry 4xx — developer errors\n if (res.status >= 400 && res.status < 500) {\n log('error', `${path} failed [${res.status}]`, text);\n throw err;\n }\n\n // Retry 5xx\n if (attempt < MAX_RETRIES - 1) {\n log('warn', `${path} [${res.status}] retrying (${attempt + 1}/${MAX_RETRIES})...`);\n await sleep(RETRY_DELAYS[attempt]);\n return this.post(path, body, attempt + 1);\n }\n\n log('error', `${path} failed after ${MAX_RETRIES} attempts`, err);\n throw err;\n }\n\n return res.json();\n } catch (e) {\n // Network error (offline, DNS, etc.)\n if ((e as AkropolysError).status === undefined) {\n if (attempt < MAX_RETRIES - 1) {\n log('warn', `${path} network error, retrying (${attempt + 1}/${MAX_RETRIES})...`);\n await sleep(RETRY_DELAYS[attempt]);\n return this.post(path, body, attempt + 1);\n }\n log('error', `${path} unreachable after ${MAX_RETRIES} attempts`);\n }\n throw e;\n }\n }\n\n async ingest(product: Record<string, any>): Promise<IngestResponse> {\n log('info', 'ingesting product', product.name || product.id || '');\n return this.post('/ingest', { siteId: this.siteId, product });\n }\n\n async ingestBatch(products: Record<string, any>[]): Promise<IngestResponse> {\n log('info', `ingesting batch of ${products.length} products`);\n return this.post('/ingest/batch', { siteId: this.siteId, products });\n }\n\n async search(query: string, limit = 10): Promise<SearchResponse> {\n log('info', 'search query', query);\n return this.post('/search', { query, siteId: this.siteId, limit });\n }\n\n // Pure vector search — no LLM, instant results.\n async searchVector(query: string, limit = 10): Promise<SearchResponse> {\n return this.post('/search/vector', { query, siteId: this.siteId, limit });\n }\n\n // Autocomplete — pure in-memory Trie, <1ms, no Upstash call. Only true prefix matches.\n async searchAutocomplete(query: string, limit = 8): Promise<SearchResponse> {\n return this.post('/search/autocomplete', { query, siteId: this.siteId, limit });\n }\n\n // LLM chat — conversational search with history context.\n async chat(query: string, history: Array<{ role: 'user' | 'assistant'; content: string }> = []): Promise<{ answer: string; sources: any[]; intent?: string; checkout?: import('./types').CartPayload; action?: any }> {\n log('info', 'chat query', query);\n const path = !this.vertical || this.vertical === 'commerce' ? '/chat' : `/chat/${this.vertical}`;\n return this.post(path, { query, siteId: this.siteId, history });\n }\n\n // Streaming variant — returns the raw fetch Response.\n // The caller reads body as a ReadableStream of SSE frames.\n async chatStream(query: string, history: Array<{ role: 'user' | 'assistant'; content: string }> = [], signal?: AbortSignal): Promise<Response> {\n log('info', 'chatStream query', query);\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Akropolys-Token': this.apiToken,\n 'X-Akropolys-Site': this.siteId,\n };\n const shopperId = this.getShopperId?.();\n if (shopperId) headers['X-Akropolys-Shopper-Id'] = shopperId;\n const sessionId = this.getSessionId?.();\n if (sessionId) headers['X-Akropolys-Session-Id'] = sessionId;\n if (typeof window !== 'undefined') {\n const phone = localStorage.getItem('akropolys_user_phone');\n if (phone) headers['X-Akropolys-Shopper-Phone'] = phone;\n }\n const path = !this.vertical || this.vertical === 'commerce' ? '/chat/stream' : `/chat/stream/${this.vertical}`;\n const res = await fetch(`${this.apiUrl}${path}`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ query, siteId: this.siteId, history }),\n signal,\n });\n if (!res.ok || !res.body) {\n throw new Error(`Stream request failed: ${res.status}`);\n }\n return res;\n }\n\n // --- Cart System ---\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Akropolys-Token': this.apiToken,\n 'X-Akropolys-Site': this.siteId,\n };\n const shopperId = this.getShopperId?.();\n if (shopperId) headers['X-Akropolys-Shopper-Id'] = shopperId;\n const sessionId = this.getSessionId?.();\n if (sessionId) headers['X-Akropolys-Session-Id'] = sessionId;\n if (typeof window !== 'undefined') {\n const phone = localStorage.getItem('akropolys_user_phone');\n if (phone) {\n headers['X-Akropolys-Shopper-Phone'] = phone;\n }\n }\n return headers;\n }\n\n async getCart(): Promise<import('./types').CartPayload> {\n const res = await fetch(`${this.apiUrl}/cart?siteId=${this.siteId}`, {\n headers: this.buildHeaders()\n });\n if (!res.ok) throw new Error('Failed to fetch cart');\n return res.json();\n }\n\n async clearCart(): Promise<import('./types').CartPayload> {\n const res = await fetch(`${this.apiUrl}/cart?siteId=${this.siteId}`, {\n method: 'DELETE',\n headers: this.buildHeaders()\n });\n if (!res.ok) throw new Error('Failed to clear cart');\n return res.json();\n }\n\n async checkoutCart(): Promise<import('./types').CartPayload> {\n const res = await fetch(`${this.apiUrl}/cart/checkout`, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({ siteId: this.siteId })\n });\n if (!res.ok) throw new Error('Failed to checkout cart');\n return res.json();\n }\n\n async getCheckoutConfig(): Promise<CheckoutConfig> {\n const res = await fetch(`${this.apiUrl}/checkout/config?site_id=${this.siteId}`, {\n method: 'GET',\n headers: this.buildHeaders()\n });\n if (!res.ok) throw new Error('Failed to fetch checkout config');\n return res.json();\n }\n\n async initiatePayment(phoneNumber: string, email?: string, firstName?: string, lastName?: string): Promise<PaymentInitResponse> {\n const res = await fetch(`${this.apiUrl}/payment/initiate`, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({\n siteId: this.siteId,\n phoneNumber,\n email,\n firstName,\n lastName\n })\n });\n if (!res.ok) {\n const errText = await res.text();\n throw new Error('Failed to initiate payment: ' + errText);\n }\n return res.json();\n }\n\n async getPaymentStatus(ref: string): Promise<PaymentStatusResponse> {\n const res = await fetch(`${this.apiUrl}/payment/status?ref=${ref}`, {\n method: 'GET',\n headers: this.buildHeaders()\n });\n if (!res.ok) throw new Error('Failed to get payment status');\n return res.json();\n }\n}\n","import { CartPayload, ChatAction } from './types';\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n cartSnapshot?: CartPayload;\n actionType?: string;\n}\n\nexport interface ChatSource {\n id?: string;\n name: string;\n price?: string;\n currency?: string;\n category?: string;\n url?: string;\n image?: string;\n brand?: string;\n availability?: string;\n}\n\nexport interface ChatMetadata {\n intent: string;\n sources: ChatSource[];\n action?: ChatAction;\n checkout?: CartPayload;\n}\n\ninterface SSEFrame {\n event: string;\n data: string;\n}\n\nfunction parseSSEChunk(raw: string): SSEFrame[] {\n const frames: SSEFrame[] = [];\n const blocks = raw.split(/\\n\\n+/);\n for (const block of blocks) {\n if (!block.trim()) continue;\n let event = '';\n let data = '';\n for (const line of block.split('\\n')) {\n if (line.startsWith('event:')) event = line.slice(6).trim();\n else if (line.startsWith('data:')) data = line.slice(5);\n }\n if (data !== '') frames.push({ event, data });\n }\n return frames;\n}\n\nexport class KikuStream {\n private listeners: Record<string, Function[]> = {};\n private aborted = false;\n private responsePromise: Promise<Response>;\n private abortController: AbortController;\n\n constructor(responsePromise: Promise<Response>, abortController: AbortController) {\n this.responsePromise = responsePromise;\n this.abortController = abortController;\n this.startReading();\n }\n\n on(event: 'token' | 'meta' | 'done' | 'error', callback: Function): this {\n if (!this.listeners[event]) {\n this.listeners[event] = [];\n }\n this.listeners[event].push(callback);\n return this;\n }\n\n off(event: 'token' | 'meta' | 'done' | 'error', callback: Function): this {\n if (!this.listeners[event]) return this;\n this.listeners[event] = this.listeners[event].filter(cb => cb !== callback);\n return this;\n }\n\n destroy() {\n this.aborted = true;\n this.abortController.abort();\n }\n\n private emit(event: string, ...args: any[]) {\n const list = this.listeners[event];\n if (!list) return;\n for (const cb of list) {\n try {\n cb(...args);\n } catch (err) {\n console.error(`[Akropolys] Error in KikuStream event listener for \"${event}\":`, err);\n }\n }\n }\n\n private async startReading() {\n try {\n const response = await this.responsePromise;\n if (this.aborted) return;\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Response body is not readable');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n let accumulatedMessage = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done || this.aborted) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n const lastBoundary = buffer.lastIndexOf('\\n\\n');\n if (lastBoundary === -1) continue;\n\n const complete = buffer.slice(0, lastBoundary + 2);\n buffer = buffer.slice(lastBoundary + 2);\n\n const frames = parseSSEChunk(complete);\n\n for (const { event, data } of frames) {\n if (this.aborted) return;\n\n if (event === 'meta') {\n try {\n const meta: ChatMetadata = JSON.parse(data);\n this.emit('meta', meta);\n } catch {\n // ignore parse errors\n }\n continue;\n }\n\n if (event === 'done') {\n break;\n }\n\n if (event === 'error') {\n let msg = 'Stream error';\n try {\n msg = JSON.parse(data).error ?? msg;\n } catch {\n msg = data;\n }\n throw new Error(msg);\n }\n\n // Plain token — convert literal \\n to actual newline\n const token = data.replace(/\\\\n/g, '\\n');\n accumulatedMessage += token;\n this.emit('token', token);\n }\n }\n\n if (!this.aborted) {\n this.emit('done', accumulatedMessage);\n }\n } catch (err: any) {\n if (!this.aborted) {\n this.emit('error', err);\n }\n }\n }\n}\n","import { AkropolysConfig } from './types';\nimport { AkropolysAPI } from './api';\nimport { KikuStream } from './stream';\n\ndeclare const process: any;\n\nlet defaultVertical: string = 'commerce';\nexport function setSDKDefaultVertical(v: string) {\n defaultVertical = v;\n}\n\nfunction getEnvVar(key: string): string | undefined {\n if (key === 'NEXT_PUBLIC_AKROPOLYS_SITE_ID') {\n try { return process.env.NEXT_PUBLIC_AKROPOLYS_SITE_ID; } catch { /* ignore */ }\n }\n if (key === 'NEXT_PUBLIC_AKROPOLYS_API_URL') {\n try { return process.env.NEXT_PUBLIC_AKROPOLYS_API_URL; } catch { /* ignore */ }\n }\n if (key === 'NEXT_PUBLIC_AKROPOLYS_API_TOKEN') {\n try { return process.env.NEXT_PUBLIC_AKROPOLYS_API_TOKEN; } catch { /* ignore */ }\n }\n\n // Fallback check for Vite (import.meta.env)\n try {\n const metaEnv = (import.meta as any).env;\n if (metaEnv) {\n if (key === 'NEXT_PUBLIC_AKROPOLYS_SITE_ID') return metaEnv.NEXT_PUBLIC_AKROPOLYS_SITE_ID || metaEnv.VITE_AKROPOLYS_SITE_ID;\n if (key === 'NEXT_PUBLIC_AKROPOLYS_API_URL') return metaEnv.NEXT_PUBLIC_AKROPOLYS_API_URL || metaEnv.VITE_AKROPOLYS_API_URL;\n if (key === 'NEXT_PUBLIC_AKROPOLYS_API_TOKEN') return metaEnv.NEXT_PUBLIC_AKROPOLYS_API_TOKEN || metaEnv.VITE_AKROPOLYS_API_TOKEN;\n }\n } catch { /* ignore */ }\n\n if (typeof globalThis !== 'undefined') {\n const g = globalThis as any;\n if (g.process && g.process.env) {\n return g.process.env[key];\n }\n }\n return undefined;\n}\n\nfunction generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nexport class AkropolysClient {\n readonly api: AkropolysAPI;\n readonly vertical: string;\n private ingestQueue: Record<string, any>[] = [];\n private ingestTimer: ReturnType<typeof setTimeout> | null = null;\n private ingestedUrls = new Set<string>();\n private onlineHandler: (() => void) | null = null;\n private shopperId?: string;\n private sessionId: string = '';\n private authLoading?: boolean;\n public onCheckout?: (cart: import('./types').CartPayload) => void;\n public onError?: (error: import('./types').AkropolysError) => void;\n\n private isFlushing = false;\n private retryCount = 0;\n\n private static INGEST_CACHE_KEY = 'akropolys_ingested_v2';\n private static INGEST_CACHE_TTL = 24 * 60 * 60 * 1000; // 24h\n\n private loadIngestedCache() {\n if (typeof window === 'undefined') return;\n try {\n const raw = localStorage.getItem(AkropolysClient.INGEST_CACHE_KEY);\n if (!raw) return;\n const { ts, urls }: { ts: number; urls: string[] } = JSON.parse(raw);\n if (Date.now() - ts > AkropolysClient.INGEST_CACHE_TTL) {\n localStorage.removeItem(AkropolysClient.INGEST_CACHE_KEY);\n return;\n }\n this.ingestedUrls = new Set(urls);\n } catch { /* ignore */ }\n }\n\n private saveIngestedCache() {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(\n AkropolysClient.INGEST_CACHE_KEY,\n JSON.stringify({ ts: Date.now(), urls: [...this.ingestedUrls] })\n );\n } catch { /* ignore */ }\n }\n\n constructor(config: AkropolysConfig) {\n const siteId = config.siteId || getEnvVar('NEXT_PUBLIC_AKROPOLYS_SITE_ID') || '';\n const apiUrl = config.apiUrl || getEnvVar('NEXT_PUBLIC_AKROPOLYS_API_URL') || '';\n const apiToken = config.apiToken || getEnvVar('NEXT_PUBLIC_AKROPOLYS_API_TOKEN') || '';\n\n // Runtime validation — fail loudly so misconfiguration is never silent\n if (!siteId) console.error('[Akropolys] Missing siteId. Set it via <AkropolysProvider siteId=\"...\"> or NEXT_PUBLIC_AKROPOLYS_SITE_ID.');\n if (!apiUrl) console.error('[Akropolys] Missing apiUrl. Set it via <AkropolysProvider apiUrl=\"...\"> or NEXT_PUBLIC_AKROPOLYS_API_URL.');\n if (!apiToken) console.error('[Akropolys] Missing apiToken. Set it via <AkropolysProvider apiToken=\"...\"> or NEXT_PUBLIC_AKROPOLYS_API_TOKEN.');\n\n this.shopperId = config.shopperId;\n this.authLoading = config.authLoading;\n this.onCheckout = config.onCheckout;\n this.onError = config.onError;\n this.vertical = config.vertical || defaultVertical;\n this.initSession();\n this.loadIngestedCache();\n\n this.api = new AkropolysAPI(\n apiUrl,\n siteId,\n apiToken,\n () => this.getShopperId(),\n () => this.sessionId,\n this.vertical\n );\n instance = this;\n\n if (typeof window !== 'undefined') {\n this.onlineHandler = () => {\n console.log('[Akropolys] Connectivity restored, flushing queued ingestions.');\n this.flushQueue();\n };\n window.addEventListener('online', this.onlineHandler);\n }\n }\n\n chat(query: string, history: Array<{ role: 'user' | 'assistant'; content: string }> = []): KikuStream {\n const abortController = new AbortController();\n const responsePromise = this.api.chatStream(query, history, abortController.signal);\n return new KikuStream(responsePromise, abortController);\n }\n\n reRegister() {\n instance = this;\n if (typeof window !== 'undefined' && !this.onlineHandler) {\n this.onlineHandler = () => this.flushQueue();\n window.addEventListener('online', this.onlineHandler);\n }\n }\n\n setShopperId(id: string | undefined) {\n this.shopperId = id;\n if (!this.authLoading) {\n this.flushQueue();\n }\n }\n\n setAuthLoading(loading: boolean) {\n const wasLoading = this.authLoading;\n this.authLoading = loading;\n if (wasLoading && !loading) {\n this.flushQueue();\n }\n }\n\n getShopperId(): string | undefined {\n return this.shopperId || 'guest_' + this.sessionId;\n }\n\n getSessionId(): string {\n return this.sessionId;\n }\n\n private initSession() {\n if (typeof window !== 'undefined' && window.sessionStorage) {\n try {\n let sid = window.sessionStorage.getItem('akropolys_session_id');\n if (!sid) {\n sid = generateUUID();\n window.sessionStorage.setItem('akropolys_session_id', sid);\n }\n this.sessionId = sid;\n return;\n } catch (e) {\n // Fallback if sessionStorage is disabled or private mode\n }\n }\n this.sessionId = generateUUID();\n }\n\n destroy() {\n if (typeof window !== 'undefined' && this.onlineHandler) {\n window.removeEventListener('online', this.onlineHandler);\n this.onlineHandler = null;\n }\n if (this.ingestTimer) {\n clearTimeout(this.ingestTimer);\n this.ingestTimer = null;\n }\n if (instance === this) instance = null;\n }\n\n async queueIngest(rawItem: Record<string, any>): Promise<void> {\n // 1. Identity resolution\n const id = rawItem.id ?? rawItem.productId ?? rawItem.slug ?? rawItem.url ?? rawItem.name ?? '';\n const url = rawItem.url || (typeof window !== 'undefined' ? window.location.href : '');\n\n if (!id && !url) {\n console.warn('[Akropolys] Ingestion warning: Item is missing both a stable identifier and a URL. Skipping.');\n return;\n }\n\n // 2. URL deduplication\n if (url) {\n if (this.ingestedUrls.has(url)) {\n return;\n }\n this.ingestedUrls.add(url);\n this.saveIngestedCache();\n }\n\n // 3. Enqueue raw\n this.ingestQueue.push(rawItem);\n this.scheduleFlush();\n }\n\n async queueIngestBatch(rawItems: Record<string, any>[]): Promise<void> {\n let hasNew = false;\n rawItems.forEach(rawItem => {\n const id = rawItem.id ?? rawItem.productId ?? rawItem.slug ?? rawItem.url ?? rawItem.name ?? '';\n const url = rawItem.url || (typeof window !== 'undefined' ? window.location.href : '');\n\n if (!id && !url) {\n console.warn('[Akropolys] Ingestion warning: Item is missing both a stable identifier and a URL. Skipping.');\n return;\n }\n\n if (url) {\n if (this.ingestedUrls.has(url)) {\n return;\n }\n this.ingestedUrls.add(url);\n hasNew = true;\n }\n\n this.ingestQueue.push(rawItem);\n });\n\n if (hasNew) {\n this.saveIngestedCache();\n }\n if (this.ingestQueue.length > 0) {\n this.scheduleFlush();\n }\n }\n\n private scheduleFlush() {\n if (this.ingestTimer || this.isFlushing) return;\n this.ingestTimer = setTimeout(() => {\n this.flushQueue();\n }, 300);\n }\n\n private async flushQueue() {\n if (this.isFlushing) return;\n this.isFlushing = true;\n\n if (this.ingestTimer) {\n clearTimeout(this.ingestTimer);\n this.ingestTimer = null;\n }\n\n if (this.authLoading) {\n console.log('[Akropolys] Authentication is loading. Deferring ingestion flush.');\n this.isFlushing = false;\n return;\n }\n\n if (typeof navigator !== 'undefined' && !navigator.onLine) {\n console.warn('[Akropolys] Browser offline. Postponing ingestion.');\n this.isFlushing = false;\n return;\n }\n\n const maxBatchSize = 50;\n\n try {\n while (this.ingestQueue.length > 0) {\n const batch = this.ingestQueue.slice(0, maxBatchSize);\n\n try {\n await this.api.ingestBatch(batch);\n // Only on success (2xx) — dequeue confirmed items\n this.ingestQueue.splice(0, batch.length);\n this.retryCount = 0; // reset retry counter on success\n } catch (e: any) {\n const status = e.status || 500;\n const message = e.message || 'Unknown network error';\n\n if (this.onError) {\n try {\n this.onError({ status, message });\n } catch (err) {\n console.error('[Akropolys] Error inside onError callback:', err);\n }\n }\n\n if (status >= 400 && status < 500 && status !== 429) {\n // Permanent failure — discard and log warning\n console.error('[Akropolys] Ingestion discarded due to client error:', message);\n this.ingestQueue.splice(0, batch.length);\n continue; // Continue processing subsequent batches if any\n } else {\n // Temporary failure (5xx, timeout, 429) — keep items, break loop, retry later\n console.warn('[Akropolys] Ingestion temporarily failed. Retrying later.', message);\n this.scheduleFlushWithBackoff();\n break;\n }\n }\n }\n } finally {\n this.isFlushing = false;\n }\n }\n\n private scheduleFlushWithBackoff() {\n if (this.ingestTimer) return;\n const baseDelay = 1000; // 1s\n const jitter = Math.random() * 1000;\n const delay = Math.min(baseDelay * Math.pow(2, this.retryCount), 30000) + jitter;\n this.retryCount++;\n this.ingestTimer = setTimeout(() => {\n this.flushQueue();\n }, delay);\n }\n}\n\nlet instance: AkropolysClient | null = null;\n\nexport function initAkropolys(config: AkropolysConfig): AkropolysClient {\n instance = new AkropolysClient(config);\n return instance;\n}\n\nexport function getAkropolysClient(): AkropolysClient {\n if (!instance) {\n const siteId = getEnvVar('NEXT_PUBLIC_AKROPOLYS_SITE_ID');\n const apiUrl = getEnvVar('NEXT_PUBLIC_AKROPOLYS_API_URL');\n const apiToken = getEnvVar('NEXT_PUBLIC_AKROPOLYS_API_TOKEN');\n\n if (siteId && apiUrl && apiToken) {\n instance = new AkropolysClient({ siteId, apiUrl, apiToken });\n } else {\n throw new Error('[Akropolys] Call initAkropolys() or set NEXT_PUBLIC_AKROPOLYS_* environment variables before using the client.');\n }\n }\n return instance;\n}\n","import React, { createContext, useContext, useEffect, useRef } from 'react';\nimport { AkropolysClient, getAkropolysClient } from './client';\nimport { AkropolysConfig } from './types';\n\nexport const AkropolysContext = createContext<AkropolysClient | null>(null);\n\ninterface AkropolysProviderProps extends AkropolysConfig {\n children: React.ReactNode;\n}\n\nexport function AkropolysProvider({\n siteId,\n apiUrl,\n apiToken,\n shopperId,\n vertical,\n authLoading,\n onCheckout,\n onError,\n children\n}: AkropolysProviderProps) {\n const clientRef = useRef<AkropolysClient | null>(null);\n\n if (!clientRef.current) {\n clientRef.current = new AkropolysClient({\n siteId,\n apiUrl,\n apiToken,\n shopperId,\n vertical,\n authLoading,\n onCheckout,\n onError\n });\n } else {\n clientRef.current.reRegister();\n }\n\n // Update shopperId dynamically when it changes\n useEffect(() => {\n clientRef.current?.setShopperId(shopperId);\n }, [shopperId]);\n\n // Update authLoading dynamically when it changes\n useEffect(() => {\n clientRef.current?.setAuthLoading(!!authLoading);\n }, [authLoading]);\n\n // Update dynamic callbacks\n useEffect(() => {\n if (clientRef.current) {\n clientRef.current.onError = onError;\n clientRef.current.onCheckout = onCheckout;\n }\n }, [onError, onCheckout]);\n\n // Ensure active instance is registered on mount\n useEffect(() => {\n clientRef.current?.reRegister();\n }, []);\n\n // Clean up\n useEffect(() => {\n return () => {\n clientRef.current?.destroy();\n };\n }, []);\n\n return (\n <AkropolysContext.Provider value={clientRef.current}>\n {children}\n </AkropolysContext.Provider>\n );\n}\n\nexport function useAkropolysContext(): AkropolysClient {\n const context = useContext(AkropolysContext);\n if (!context) {\n return getAkropolysClient();\n }\n return context;\n}\n","import { useRef } from 'react';\nimport { AkropolysConfig } from '../types';\nimport { AkropolysClient, initAkropolys } from '../client';\n\n/**\n * @deprecated Use <AkropolysProvider> instead to avoid SSR issues.\n */\nexport function useAkropolys(config: AkropolysConfig): AkropolysClient {\n const clientRef = useRef<AkropolysClient | null>(null);\n\n if (!clientRef.current) {\n console.warn('[Akropolys] useAkropolys() is deprecated. Please wrap your application in <AkropolysProvider> instead.');\n clientRef.current = initAkropolys(config);\n }\n\n return clientRef.current;\n}\n","import { useState, useCallback, useRef } from 'react';\nimport { SearchResult } from '../types';\nimport { useAkropolysContext } from '../Provider';\n\ninterface UseSearchReturn {\n results: SearchResult[];\n loading: boolean;\n error: string | null;\n search: (query: string, limit?: number) => Promise<void>;\n clear: () => void;\n}\n\nexport function useSearch(): UseSearchReturn {\n const client = useAkropolysContext();\n const [results, setResults] = useState<SearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n // Generation counter so stale responses from any in-flight requests don't overwrite newer ones\n const genRef = useRef(0);\n\n const search = useCallback(async (query: string, limit = 8) => {\n if (!query.trim()) { setResults([]); setLoading(false); return; }\n const gen = ++genRef.current;\n setLoading(true);\n setError(null);\n try {\n // searchAutocomplete = pure in-memory Trie, <1ms, no Upstash\n const res = await client.api.searchAutocomplete(query, limit);\n if (gen === genRef.current) {\n setResults(res.results ?? []);\n }\n } catch (e: unknown) {\n if (gen === genRef.current) {\n let msg = (e as any)?.message ?? 'Search failed';\n try {\n const parsed = JSON.parse(msg);\n if (parsed && parsed.error) {\n msg = parsed.error;\n }\n } catch {\n // keep original text\n }\n setError(msg);\n }\n } finally {\n if (gen === genRef.current) setLoading(false);\n }\n }, [client]);\n\n const clear = useCallback(() => {\n genRef.current++;\n setResults([]);\n setError(null);\n setLoading(false);\n }, []);\n\n return { results, loading, error, search, clear };\n}\n","import { useCallback } from 'react';\nimport { useAkropolysContext } from '../Provider';\nimport { TTLCache } from '../utils/TTLCache';\n\nexport type RawItem = Record<string, any>;\n\ninterface UseIngestReturn {\n ingest: (product: RawItem) => void;\n ingestBatch: (products: RawItem[]) => void;\n /**\n * @deprecated Ingest is fire-and-forget. This is always `false` and will be\n * removed in the next major version. Remove it from your destructuring.\n */\n loading: false;\n /**\n * @deprecated Ingest is fire-and-forget. This is always `null` and will be\n * removed in the next major version. Remove it from your destructuring.\n */\n error: null;\n}\n\n// Module-level TTL cache (24 hours TTL) to prevent duplicate ingestion requests in the same session\nconst recentlyIngested = new TTLCache<string>(24 * 60 * 60 * 1000);\n\nfunction getProductKey(p: RawItem): string | null {\n return p.id || p.productId || p.slug || p.url || p.name || p.title || p.productName || null;\n}\n\nexport function useIngest(): UseIngestReturn {\n const client = useAkropolysContext();\n\n const ingest = useCallback((product: RawItem) => {\n const key = getProductKey(product);\n if (key) {\n if (recentlyIngested.has(key)) return;\n recentlyIngested.add(key);\n }\n // Fire-and-forget — errors are logged internally by the client\n client.queueIngest(product).catch(() => {});\n }, [client]);\n\n const ingestBatch = useCallback((products: RawItem[]) => {\n const toIngest = products.filter(p => {\n const key = getProductKey(p);\n if (!key) return true;\n if (recentlyIngested.has(key)) return false;\n recentlyIngested.add(key);\n return true;\n });\n\n if (!toIngest.length) return;\n // Fire-and-forget — errors are logged internally by the client\n client.queueIngestBatch(toIngest).catch(() => {});\n }, [client]);\n\n // loading/error kept as stable literals for backwards compatibility.\n return { ingest, ingestBatch, loading: false, error: null };\n}\n","export class TTLCache<T> {\n private cache = new Map<T, number>();\n private ttl: number;\n\n constructor(ttlMs: number = 24 * 60 * 60 * 1000) {\n this.ttl = ttlMs;\n }\n\n add(key: T): void {\n this.cache.set(key, Date.now());\n this.evictExpired();\n }\n\n has(key: T): boolean {\n const timestamp = this.cache.get(key);\n if (timestamp === undefined) return false;\n\n if (Date.now() - timestamp > this.ttl) {\n this.cache.delete(key);\n return false;\n }\n return true;\n }\n\n private evictExpired(): void {\n const now = Date.now();\n for (const [key, timestamp] of this.cache.entries()) {\n if (now - timestamp > this.ttl) {\n this.cache.delete(key);\n }\n }\n }\n}\n","import { useEffect, useRef } from 'react';\nimport { useIngest } from './useIngest';\n\n/**\n * useListIngest — drop this into any collection, catalog, or list component.\n * It automatically ingests all items in the array, using a built-in\n * component-lifecycle ref guard to prevent duplicate calls during mounts.\n *\n * @example\n * export function CategoryPage({ products }) {\n * useListIngest(products);\n * return <ProductGrid products={products} />;\n * }\n */\nexport function useListIngest(items: Record<string, any>[] | null | undefined): void {\n const { ingestBatch } = useIngest();\n const processedIdsRef = useRef<Set<string>>(new Set());\n\n // Create a stable dependency key representing the items currently in the list\n const listKey = (items || [])\n .map((p) => p.id ?? p.productId ?? p.slug ?? p.url ?? p.name ?? '')\n .join(',');\n\n useEffect(() => {\n if (!items || !items.length) return;\n\n // Filter out items that have already been queued in this component's mount lifecycle\n const newItems = items.filter((item) => {\n const id = item.id ?? item.productId ?? item.slug ?? item.url ?? item.name ?? '';\n if (!id) return true; // Let the queue handle validation/deduplication if no identifier is present\n if (processedIdsRef.current.has(id)) {\n return false;\n }\n processedIdsRef.current.add(id);\n return true;\n });\n\n if (newItems.length > 0) {\n ingestBatch(newItems);\n }\n }, [listKey, ingestBatch]);\n}\n","import { useEffect, useRef } from 'react';\nimport { getAkropolysClient } from '../client';\n\ndeclare const process: any;\n\n/**\n * usePageIngest — drop this into any page component.\n * The moment a customer's browser renders the page, the item is\n * automatically captured and queued for ingestion.\n *\n * @example\n * export function ProductPage({ product }) {\n * usePageIngest(product);\n * return <div>...</div>;\n * }\n */\nexport function usePageIngest(product: Record<string, any> | null | undefined): void {\n const lastIngestedKey = useRef<string | null>(null);\n\n // Fallback chain for unique identification across all verticals\n const uniqueId = product\n ? (product.id ?? product.productId ?? product.slug ?? product.url ?? '')\n : '';\n\n useEffect(() => {\n if (!product || !uniqueId) return;\n if (lastIngestedKey.current === uniqueId) return;\n\n lastIngestedKey.current = uniqueId;\n\n try {\n getAkropolysClient().queueIngest(product);\n } catch (err) {\n if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production') {\n console.warn('[Akropolys] Ingestion failed inside usePageIngest:', err);\n }\n }\n }, [uniqueId]);\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport { useAkropolysContext } from '../Provider';\nimport { ChatMessage, ChatSource } from '../stream';\nimport { ChatAction } from '../types';\n\ninterface UseKikuOptions {\n initialMessages?: ChatMessage[];\n onToken?: (token: string) => void;\n onMeta?: (meta: any) => void;\n onDone?: (fullMessage: string) => void;\n onError?: (error: Error) => void;\n}\n\ninterface UseKikuReturn {\n messages: ChatMessage[];\n sources: ChatSource[];\n loading: boolean;\n streaming: boolean;\n error: string | null;\n lastAction: ChatAction | null;\n lastIntent: string | null;\n send: (query: string, displayQuery?: string) => Promise<void>;\n reset: () => void;\n}\n\nexport function useKiku(options: UseKikuOptions = {}): UseKikuReturn {\n const client = useAkropolysContext();\n const [messages, setMessages] = useState<ChatMessage[]>(options.initialMessages ?? []);\n const [sources, setSources] = useState<ChatSource[]>([]);\n const [loading, setLoading] = useState(false);\n const [streaming, setStreaming] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [lastAction, setLastAction] = useState<ChatAction | null>(null);\n const [lastIntent, setLastIntent] = useState<string | null>(null);\n const activeStreamRef = useRef<any | null>(null);\n\n // Keep references to options callbacks to avoid hook dependencies issues\n const onTokenRef = useRef(options.onToken);\n const onMetaRef = useRef(options.onMeta);\n const onDoneRef = useRef(options.onDone);\n const onErrorRef = useRef(options.onError);\n\n useEffect(() => {\n onTokenRef.current = options.onToken;\n onMetaRef.current = options.onMeta;\n onDoneRef.current = options.onDone;\n onErrorRef.current = options.onError;\n }, [options.onToken, options.onMeta, options.onDone, options.onError]);\n\n // Clean up stream on unmount\n useEffect(() => {\n return () => {\n activeStreamRef.current?.destroy();\n };\n }, []);\n\n const send = useCallback(async (query: string, displayQuery?: string) => {\n if (!query.trim() || loading) return;\n\n // Abort previous stream if any\n activeStreamRef.current?.destroy();\n\n // Optimistically add user message\n const userMsg: ChatMessage = { role: 'user', content: displayQuery ?? query };\n setMessages(prev => [...prev, userMsg]);\n setLoading(true);\n setStreaming(false);\n setError(null);\n\n try {\n // History excludes the message we just added\n const history = messages.map(m => ({ role: m.role, content: m.content }));\n \n // Get the stream\n const stream = client.chat(query, history);\n activeStreamRef.current = stream;\n\n let messageInitialized = false;\n let lastMeta: any = null;\n\n stream.on('meta', (meta: any) => {\n lastMeta = meta;\n setSources(meta.sources ?? []);\n if (meta.intent) setLastIntent(meta.intent);\n if (meta.action) setLastAction(meta.action);\n \n onMetaRef.current?.(meta);\n });\n\n stream.on('token', (token: string) => {\n if (!messageInitialized) {\n setLoading(false);\n setStreaming(true);\n setMessages(prev => [...prev, { role: 'assistant', content: token }]);\n messageInitialized = true;\n } else {\n setMessages(prev => {\n const next = [...prev];\n if (next.length > 0 && next[next.length - 1].role === 'assistant') {\n next[next.length - 1] = {\n ...next[next.length - 1],\n content: next[next.length - 1].content + token,\n };\n }\n return next;\n });\n }\n\n onTokenRef.current?.(token);\n });\n\n stream.on('done', (fullMessage: string) => {\n setLoading(false);\n setStreaming(false);\n\n const metaAction = lastMeta?.action;\n const metaCheckout = lastMeta?.checkout;\n\n const isCartAction = metaAction?.type === 'add_to_cart'\n || metaAction?.type === 'remove_from_cart'\n || metaAction?.type === 'clear_cart'\n || metaAction?.type === 'view_cart';\n\n if (isCartAction || metaCheckout) {\n setMessages(prev => {\n const next = [...prev];\n if (next.length > 0 && next[next.length - 1].role === 'assistant') {\n next[next.length - 1] = {\n ...next[next.length - 1],\n cartSnapshot: metaCheckout,\n actionType: metaAction?.type,\n };\n }\n return next;\n });\n \n window.dispatchEvent(new CustomEvent('akropolys:cart_updated', { detail: metaCheckout }));\n }\n\n if (metaAction?.type === 'checkout') {\n window.dispatchEvent(new CustomEvent('akropolys:trigger_checkout', { detail: metaCheckout }));\n }\n if (metaAction?.type === 'awaiting_payment') {\n window.dispatchEvent(new CustomEvent('akropolys:awaiting_payment', { detail: metaAction }));\n }\n\n if (metaCheckout && client.onCheckout) {\n client.onCheckout(metaCheckout);\n }\n\n onDoneRef.current?.(fullMessage);\n });\n\n stream.on('error', (err: Error) => {\n setLoading(false);\n setStreaming(false);\n setError(err.message);\n // Remove the user query from message history on failure\n setMessages(prev => prev.slice(0, -1));\n onErrorRef.current?.(err);\n });\n\n } catch (err: any) {\n setLoading(false);\n setStreaming(false);\n setError(err?.message ?? 'Chat request failed');\n setMessages(prev => prev.slice(0, -1));\n onErrorRef.current?.(err);\n }\n }, [client, messages, loading]);\n\n const reset = useCallback(() => {\n activeStreamRef.current?.destroy();\n setMessages([]);\n setSources([]);\n setStreaming(false);\n setError(null);\n setLoading(false);\n setLastAction(null);\n setLastIntent(null);\n }, []);\n\n return { messages, sources, loading, streaming, error, lastAction, lastIntent, send, reset };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport { useAkropolysContext } from '../Provider';\nimport { CartPayload } from '../types';\n\nexport function useCart() {\n const client = useAkropolysContext();\n const [cart, setCart] = useState<CartPayload | null>(null);\n const [loading, setLoading] = useState(false);\n\n const shopperId = client.getShopperId();\n\n const fetchCart = useCallback(async () => {\n if (!shopperId) return;\n setLoading(true);\n try {\n const res = await client.api.getCart();\n setCart(res);\n } catch (e) {\n console.error('[Akropolys] Failed to fetch cart', e);\n } finally {\n setLoading(false);\n }\n }, [client, shopperId]);\n\n useEffect(() => {\n fetchCart();\n \n const handleCartUpdate = (e: any) => {\n if (e.detail) {\n setCart(e.detail);\n } else {\n fetchCart();\n }\n };\n if (typeof window !== 'undefined') {\n window.addEventListener('akropolys:cart_updated', handleCartUpdate as EventListener);\n return () => window.removeEventListener('akropolys:cart_updated', handleCartUpdate as EventListener);\n }\n }, [fetchCart, shopperId]);\n\n return { cart, loading, fetchCart };\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { AkropolysAPI } from '../api';\n\nexport interface UsePaymentPollingProps {\n client: AkropolysAPI;\n merchantReference: string | null;\n onSuccess?: () => void;\n onFailure?: (errorMsg?: string) => void;\n intervalMs?: number;\n timeoutMs?: number;\n}\n\nexport function usePaymentPolling({\n client,\n merchantReference,\n onSuccess,\n onFailure,\n intervalMs = 3000,\n timeoutMs = 300000, // 5 minutes default\n}: UsePaymentPollingProps) {\n const [status, setStatus] = useState<'IDLE' | 'PENDING' | 'COMPLETED' | 'FAILED'>('IDLE');\n const [error, setError] = useState<string | null>(null);\n\n const onSuccessRef = useRef(onSuccess);\n const onFailureRef = useRef(onFailure);\n\n useEffect(() => {\n onSuccessRef.current = onSuccess;\n onFailureRef.current = onFailure;\n }, [onSuccess, onFailure]);\n\n useEffect(() => {\n if (!merchantReference) {\n setStatus('IDLE');\n setError(null);\n return;\n }\n\n setStatus('PENDING');\n setError(null);\n\n const startTime = Date.now();\n let timerId: ReturnType<typeof setTimeout> | null = null;\n\n async function checkStatus() {\n try {\n if (Date.now() - startTime >= timeoutMs) {\n setStatus('FAILED');\n setError('Payment session timed out');\n if (onFailureRef.current) onFailureRef.current('Payment session timed out');\n return;\n }\n\n const res = await client.getPaymentStatus(merchantReference as string);\n \n if (res.status === 'COMPLETED') {\n setStatus('COMPLETED');\n if (onSuccessRef.current) onSuccessRef.current();\n } else if (res.status === 'FAILED') {\n setStatus('FAILED');\n setError('Payment failed');\n if (onFailureRef.current) onFailureRef.current('Payment failed');\n } else {\n // Keep polling\n timerId = setTimeout(checkStatus, intervalMs);\n }\n } catch (err: any) {\n console.error('[Akropolys Polling Error]', err);\n // Treat transient network/parsing errors gracefully and retry\n timerId = setTimeout(checkStatus, intervalMs);\n }\n }\n\n // Start polling\n timerId = setTimeout(checkStatus, intervalMs);\n\n return () => {\n if (timerId) {\n clearTimeout(timerId);\n }\n };\n }, [client, merchantReference, intervalMs, timeoutMs]);\n\n return { status, error };\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","import_react","import_react","import_react","import_react","import_react"]}
package/dist/commerce.mjs CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  usePageIngest,
17
17
  usePaymentPolling,
18
18
  useSearch
19
- } from "./chunk-FBM65EZM.mjs";
19
+ } from "./chunk-QSRD6T65.mjs";
20
20
 
21
21
  // src/commerce.ts
22
22
  setSDKDefaultVertical("commerce");
package/dist/index.d.mts CHANGED
@@ -163,8 +163,8 @@ declare class AkropolysAPI {
163
163
  private vertical?;
164
164
  constructor(apiUrl: string, siteId: string, apiToken: string, getShopperId?: (() => string | undefined) | undefined, getSessionId?: (() => string | undefined) | undefined, vertical?: string | undefined);
165
165
  private post;
166
- ingest(product: Product): Promise<IngestResponse>;
167
- ingestBatch(products: Product[]): Promise<IngestResponse>;
166
+ ingest(product: Record<string, any>): Promise<IngestResponse>;
167
+ ingestBatch(products: Record<string, any>[]): Promise<IngestResponse>;
168
168
  search(query: string, limit?: number): Promise<SearchResponse>;
169
169
  searchVector(query: string, limit?: number): Promise<SearchResponse>;
170
170
  searchAutocomplete(query: string, limit?: number): Promise<SearchResponse>;
@@ -240,6 +240,8 @@ declare class AkropolysClient {
240
240
  private authLoading?;
241
241
  onCheckout?: (cart: CartPayload) => void;
242
242
  onError?: (error: AkropolysError) => void;
243
+ private isFlushing;
244
+ private retryCount;
243
245
  private static INGEST_CACHE_KEY;
244
246
  private static INGEST_CACHE_TTL;
245
247
  private loadIngestedCache;
@@ -256,10 +258,11 @@ declare class AkropolysClient {
256
258
  getSessionId(): string;
257
259
  private initSession;
258
260
  destroy(): void;
259
- queueIngest(rawProduct: RawProductInput): Promise<void>;
260
- queueIngestBatch(rawProducts: RawProductInput[]): Promise<void>;
261
+ queueIngest(rawItem: Record<string, any>): Promise<void>;
262
+ queueIngestBatch(rawItems: Record<string, any>[]): Promise<void>;
261
263
  private scheduleFlush;
262
264
  private flushQueue;
265
+ private scheduleFlushWithBackoff;
263
266
  }
264
267
  declare function initAkropolys(config: AkropolysConfig): AkropolysClient;
265
268
  declare function getAkropolysClient(): AkropolysClient;
@@ -284,9 +287,10 @@ interface UseSearchReturn {
284
287
  }
285
288
  declare function useSearch(): UseSearchReturn;
286
289
 
290
+ type RawItem = Record<string, any>;
287
291
  interface UseIngestReturn {
288
- ingest: (product: RawProductInput) => void;
289
- ingestBatch: (products: RawProductInput[]) => void;
292
+ ingest: (product: RawItem) => void;
293
+ ingestBatch: (products: RawItem[]) => void;
290
294
  /**
291
295
  * @deprecated Ingest is fire-and-forget. This is always `false` and will be
292
296
  * removed in the next major version. Remove it from your destructuring.
@@ -301,7 +305,7 @@ interface UseIngestReturn {
301
305
  declare function useIngest(): UseIngestReturn;
302
306
 
303
307
  /**
304
- * useListIngest — drop this into any catalog or list page.
308
+ * useListIngest — drop this into any collection, catalog, or list component.
305
309
  * It automatically ingests all items in the array, using a built-in
306
310
  * component-lifecycle ref guard to prevent duplicate calls during mounts.
307
311
  *
@@ -311,29 +315,20 @@ declare function useIngest(): UseIngestReturn;
311
315
  * return <ProductGrid products={products} />;
312
316
  * }
313
317
  */
314
- declare function useListIngest(products: RawProductInput[] | null | undefined): void;
318
+ declare function useListIngest(items: Record<string, any>[] | null | undefined): void;
315
319
 
316
320
  /**
317
- * usePageIngest — drop this into any product page component.
318
- * The moment a customer's browser renders the page, the product is
319
- * automatically captured and queued for ingestion into the vector index.
320
- *
321
- * No configuration needed beyond <AkropolysProvider> in your layout.
321
+ * usePageIngest — drop this into any page component.
322
+ * The moment a customer's browser renders the page, the item is
323
+ * automatically captured and queued for ingestion.
322
324
  *
323
325
  * @example
324
- * // Product detail page — Next.js or React
325
326
  * export function ProductPage({ product }) {
326
- * usePageIngest({
327
- * name: product.title,
328
- * price: product.price,
329
- * url: window.location.href,
330
- * images: [product.thumbnail],
331
- * category: product.category,
332
- * });
327
+ * usePageIngest(product);
333
328
  * return <div>...</div>;
334
329
  * }
335
330
  */
336
- declare function usePageIngest(product: RawProductInput | null | undefined): void;
331
+ declare function usePageIngest(product: Record<string, any> | null | undefined): void;
337
332
 
338
333
  interface UseKikuOptions {
339
334
  initialMessages?: ChatMessage[];
package/dist/index.d.ts CHANGED
@@ -163,8 +163,8 @@ declare class AkropolysAPI {
163
163
  private vertical?;
164
164
  constructor(apiUrl: string, siteId: string, apiToken: string, getShopperId?: (() => string | undefined) | undefined, getSessionId?: (() => string | undefined) | undefined, vertical?: string | undefined);
165
165
  private post;
166
- ingest(product: Product): Promise<IngestResponse>;
167
- ingestBatch(products: Product[]): Promise<IngestResponse>;
166
+ ingest(product: Record<string, any>): Promise<IngestResponse>;
167
+ ingestBatch(products: Record<string, any>[]): Promise<IngestResponse>;
168
168
  search(query: string, limit?: number): Promise<SearchResponse>;
169
169
  searchVector(query: string, limit?: number): Promise<SearchResponse>;
170
170
  searchAutocomplete(query: string, limit?: number): Promise<SearchResponse>;
@@ -240,6 +240,8 @@ declare class AkropolysClient {
240
240
  private authLoading?;
241
241
  onCheckout?: (cart: CartPayload) => void;
242
242
  onError?: (error: AkropolysError) => void;
243
+ private isFlushing;
244
+ private retryCount;
243
245
  private static INGEST_CACHE_KEY;
244
246
  private static INGEST_CACHE_TTL;
245
247
  private loadIngestedCache;
@@ -256,10 +258,11 @@ declare class AkropolysClient {
256
258
  getSessionId(): string;
257
259
  private initSession;
258
260
  destroy(): void;
259
- queueIngest(rawProduct: RawProductInput): Promise<void>;
260
- queueIngestBatch(rawProducts: RawProductInput[]): Promise<void>;
261
+ queueIngest(rawItem: Record<string, any>): Promise<void>;
262
+ queueIngestBatch(rawItems: Record<string, any>[]): Promise<void>;
261
263
  private scheduleFlush;
262
264
  private flushQueue;
265
+ private scheduleFlushWithBackoff;
263
266
  }
264
267
  declare function initAkropolys(config: AkropolysConfig): AkropolysClient;
265
268
  declare function getAkropolysClient(): AkropolysClient;
@@ -284,9 +287,10 @@ interface UseSearchReturn {
284
287
  }
285
288
  declare function useSearch(): UseSearchReturn;
286
289
 
290
+ type RawItem = Record<string, any>;
287
291
  interface UseIngestReturn {
288
- ingest: (product: RawProductInput) => void;
289
- ingestBatch: (products: RawProductInput[]) => void;
292
+ ingest: (product: RawItem) => void;
293
+ ingestBatch: (products: RawItem[]) => void;
290
294
  /**
291
295
  * @deprecated Ingest is fire-and-forget. This is always `false` and will be
292
296
  * removed in the next major version. Remove it from your destructuring.
@@ -301,7 +305,7 @@ interface UseIngestReturn {
301
305
  declare function useIngest(): UseIngestReturn;
302
306
 
303
307
  /**
304
- * useListIngest — drop this into any catalog or list page.
308
+ * useListIngest — drop this into any collection, catalog, or list component.
305
309
  * It automatically ingests all items in the array, using a built-in
306
310
  * component-lifecycle ref guard to prevent duplicate calls during mounts.
307
311
  *
@@ -311,29 +315,20 @@ declare function useIngest(): UseIngestReturn;
311
315
  * return <ProductGrid products={products} />;
312
316
  * }
313
317
  */
314
- declare function useListIngest(products: RawProductInput[] | null | undefined): void;
318
+ declare function useListIngest(items: Record<string, any>[] | null | undefined): void;
315
319
 
316
320
  /**
317
- * usePageIngest — drop this into any product page component.
318
- * The moment a customer's browser renders the page, the product is
319
- * automatically captured and queued for ingestion into the vector index.
320
- *
321
- * No configuration needed beyond <AkropolysProvider> in your layout.
321
+ * usePageIngest — drop this into any page component.
322
+ * The moment a customer's browser renders the page, the item is
323
+ * automatically captured and queued for ingestion.
322
324
  *
323
325
  * @example
324
- * // Product detail page — Next.js or React
325
326
  * export function ProductPage({ product }) {
326
- * usePageIngest({
327
- * name: product.title,
328
- * price: product.price,
329
- * url: window.location.href,
330
- * images: [product.thumbnail],
331
- * category: product.category,
332
- * });
327
+ * usePageIngest(product);
333
328
  * return <div>...</div>;
334
329
  * }
335
330
  */
336
- declare function usePageIngest(product: RawProductInput | null | undefined): void;
331
+ declare function usePageIngest(product: Record<string, any> | null | undefined): void;
337
332
 
338
333
  interface UseKikuOptions {
339
334
  initialMessages?: ChatMessage[];