paprflare-sdk 0.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/utils.ts","../../src/react/store/store.ts","../../src/react/client/client.ts"],"names":["generateId","prefix","id","nanoid","createChatStore","create","subscribeWithSelector","set","message","state","updates","msg","isStreaming","error","artifact","toolCall","result","lastMessage","idx","usage","metadata","usePaprFlare","config","store","useRef","messages","currentMessage","artifacts","currentArtifact","toolCalls","abortControllerRef","sendMessage","useCallback","content","options","userMessage","chatConfig","response","processStream","errorMessage","regenerate","lastUserMessage","stop","clear","append","setMessages","newMessages","executeToolCall","toolResult","useEffect","body","callbacks","reader","decoder","buffer","assistantMessageId","currentArtifactContent","done","value","lines","line","data","event","finalMessage"],"mappings":"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","file":"index.js","sourcesContent":["import { nanoid } from 'nanoid';\r\nimport stringify from 'fast-json-stable-stringify';\r\nimport type { Message } from '../types';\r\n\r\n/**\r\n * Generate a unique ID\r\n */\r\nexport function generateId(prefix?: string): string {\r\n const id = nanoid();\r\n return prefix ? `${prefix}_${id}` : id;\r\n}\r\n\r\n/**\r\n * Create a stable hash for cache keys\r\n */\r\nexport function createCacheKey(data: unknown): string {\r\n return stringify(data);\r\n}\r\n\r\n/**\r\n * Format messages for provider APIs\r\n */\r\nexport function formatMessages(messages: Message[]): Message[] {\r\n return messages.map((msg) => ({\r\n ...msg,\r\n id: msg.id || generateId('msg'),\r\n timestamp: msg.timestamp || Date.now(),\r\n }));\r\n}\r\n\r\n/**\r\n * Retry with exponential backoff\r\n */\r\nexport async function retry<T>(\r\n fn: () => Promise<T>,\r\n options: {\r\n maxAttempts: number;\r\n initialDelay: number;\r\n maxDelay: number;\r\n backoffMultiplier: number;\r\n onRetry?: (attempt: number, error: Error) => void;\r\n }\r\n): Promise<T> {\r\n let lastError: Error;\r\n let delay = options.initialDelay;\r\n\r\n for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n lastError = error as Error;\r\n\r\n if (attempt === options.maxAttempts) {\r\n throw lastError;\r\n }\r\n\r\n if (options.onRetry) {\r\n options.onRetry(attempt, lastError);\r\n }\r\n\r\n await sleep(Math.min(delay, options.maxDelay));\r\n delay *= options.backoffMultiplier;\r\n }\r\n }\r\n\r\n throw lastError!;\r\n}\r\n\r\n/**\r\n * Sleep for a given duration\r\n */\r\nexport function sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/**\r\n * Chunk an array into smaller arrays\r\n */\r\nexport function chunk<T>(array: T[], size: number): T[][] {\r\n const chunks: T[][] = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n chunks.push(array.slice(i, i + size));\r\n }\r\n return chunks;\r\n}\r\n\r\n/**\r\n * Debounce a function\r\n */\r\nexport function debounce<T extends (...args: any[]) => any>(\r\n fn: T,\r\n delay: number\r\n): (...args: Parameters<T>) => void {\r\n let timeoutId: NodeJS.Timeout;\r\n\r\n return (...args: Parameters<T>) => {\r\n clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => fn(...args), delay);\r\n };\r\n}\r\n\r\n/**\r\n * Throttle a function\r\n */\r\nexport function throttle<T extends (...args: any[]) => any>(\r\n fn: T,\r\n limit: number\r\n): (...args: Parameters<T>) => void {\r\n let inThrottle: boolean;\r\n\r\n return (...args: Parameters<T>) => {\r\n if (!inThrottle) {\r\n fn(...args);\r\n inThrottle = true;\r\n setTimeout(() => (inThrottle = false), limit);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Safely parse JSON\r\n */\r\nexport function safeJsonParse<T = unknown>(json: string): T | null {\r\n try {\r\n return JSON.parse(json) as T;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a value is a plain object\r\n */\r\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\r\n return (\r\n typeof value === 'object' &&\r\n value !== null &&\r\n value.constructor === Object\r\n );\r\n}\r\n\r\n/**\r\n * Deep merge objects\r\n */\r\nexport function deepMerge<T extends Record<string, any>>(\r\n target: T,\r\n ...sources: Partial<T>[]\r\n): T {\r\n if (!sources.length) return target;\r\n\r\n const source = sources.shift();\r\n\r\n if (isPlainObject(target) && isPlainObject(source)) {\r\n for (const key in source) {\r\n if (isPlainObject(source[key])) {\r\n if (!target[key]) Object.assign(target, { [key]: {} });\r\n deepMerge(target[key], source[key] as any);\r\n } else {\r\n Object.assign(target, { [key]: source[key] });\r\n }\r\n }\r\n }\r\n\r\n return deepMerge(target, ...sources);\r\n}\r\n\r\n/**\r\n * Convert async generator to array\r\n */\r\nexport async function streamToArray<T>(\r\n stream: AsyncGenerator<T>\r\n): Promise<T[]> {\r\n const result: T[] = [];\r\n for await (const item of stream) {\r\n result.push(item);\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Measure execution time\r\n */\r\nexport async function measureTime<T>(\r\n fn: () => Promise<T>\r\n): Promise<{ result: T; duration: number }> {\r\n const start = performance.now();\r\n const result = await fn();\r\n const duration = performance.now() - start;\r\n return { result, duration };\r\n}","import { create } from 'zustand';\r\nimport { subscribeWithSelector } from 'zustand/middleware';\r\nimport type { ChatState } from '../../types';\r\n\r\n/**\r\n * Create chat store with Zustand\r\n */\r\nexport const createChatStore = () =>\r\n create<ChatState>()(\r\n subscribeWithSelector((set) => ({\r\n messages: [],\r\n currentMessage: '',\r\n isStreaming: false,\r\n error: null,\r\n artifacts: [],\r\n currentArtifact: null,\r\n toolCalls: [],\r\n usage: null,\r\n metadata: {},\r\n\r\n addMessage: (message) =>\r\n set((state) => ({\r\n messages: [...state.messages, message],\r\n })),\r\n\r\n updateMessage: (id, updates) =>\r\n set((state) => ({\r\n messages: state.messages.map((msg) =>\r\n msg.id === id ? { ...msg, ...updates } : msg\r\n ),\r\n })),\r\n\r\n setCurrentMessage: (message) =>\r\n set({ currentMessage: message }),\r\n\r\n setStreaming: (isStreaming) =>\r\n set({ isStreaming }),\r\n\r\n setError: (error) =>\r\n set({ error }),\r\n\r\n addArtifact: (artifact) =>\r\n set((state) => ({\r\n artifacts: [...state.artifacts, artifact],\r\n })),\r\n\r\n setCurrentArtifact: (artifact) =>\r\n set({ currentArtifact: artifact }),\r\n\r\n addToolCall: (toolCall) =>\r\n set((state) => ({\r\n toolCalls: [...state.toolCalls, toolCall],\r\n })),\r\n\r\n addToolResult: (result) =>\r\n set((state) => {\r\n const lastMessage = state.messages[state.messages.length - 1];\r\n if (lastMessage && lastMessage.role === 'assistant') {\r\n return {\r\n messages: state.messages.map((msg, idx) =>\r\n idx === state.messages.length - 1\r\n ? {\r\n ...msg,\r\n toolResults: [...(msg.toolResults || []), result],\r\n }\r\n : msg\r\n ),\r\n };\r\n }\r\n return state;\r\n }),\r\n\r\n setUsage: (usage) =>\r\n set({ usage }),\r\n\r\n setMetadata: (metadata) =>\r\n set((state) => ({\r\n metadata: { ...state.metadata, ...metadata },\r\n })),\r\n\r\n reset: () =>\r\n set({\r\n messages: [],\r\n currentMessage: '',\r\n isStreaming: false,\r\n error: null,\r\n artifacts: [],\r\n currentArtifact: null,\r\n toolCalls: [],\r\n usage: null,\r\n metadata: {},\r\n }),\r\n }))\r\n );\r\n\r\n","import { useRef, useCallback, useEffect } from 'react';\r\nimport { generateId } from '../../utils';\r\nimport type { Artifact, ChatConfig, ChatState, Message, StreamEvent, ToolCall, ToolResult, UsePaprFlareConfig } from '../../types';\r\nimport { createChatStore } from '../store/store';\r\n/**\r\n * Unified PaprFlare React hook\r\n * Handles all AI interactions with optimized state management using Zustand\r\n */\r\nexport function usePaprFlare(config: UsePaprFlareConfig) {\r\n // Create store instance (stable reference)\r\n const storeRef = useRef(createChatStore());\r\n const store = storeRef.current;\r\n\r\n // Use Zustand store\r\n const messages = store((state) => state.messages);\r\n const currentMessage = store((state) => state.currentMessage);\r\n const isStreaming = store((state) => state.isStreaming);\r\n const error = store((state) => state.error);\r\n const artifacts = store((state) => state.artifacts);\r\n const currentArtifact = store((state) => state.currentArtifact);\r\n const toolCalls = store((state) => state.toolCalls);\r\n const usage = store((state) => state.usage);\r\n const metadata = store((state) => state.metadata);\r\n\r\n // Abort controller ref\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n\r\n /**\r\n * Send a message and stream the response\r\n */\r\n const sendMessage = useCallback(\r\n async (\r\n content: string,\r\n options?: Partial<ChatConfig>\r\n ): Promise<void> => {\r\n if (isStreaming) {\r\n throw new Error('Already streaming a response');\r\n }\r\n\r\n try {\r\n // Add user message\r\n const userMessage: Message = {\r\n id: generateId('msg'),\r\n role: 'user',\r\n content,\r\n timestamp: Date.now(),\r\n };\r\n\r\n store.getState().addMessage(userMessage);\r\n store.getState().setStreaming(true);\r\n store.getState().setError(null);\r\n store.getState().setCurrentMessage('');\r\n\r\n // Create abort controller\r\n abortControllerRef.current = new AbortController();\r\n\r\n // Merge configurations\r\n const chatConfig: ChatConfig = {\r\n ...config.defaultConfig,\r\n ...options,\r\n stream: true,\r\n };\r\n\r\n // Make API request\r\n const response = await fetch(config.apiEndpoint, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...(config.apiKey && { Authorization: `Bearer ${config.apiKey}` }),\r\n ...config.headers,\r\n },\r\n body: JSON.stringify({\r\n messages: [...messages, userMessage],\r\n ...chatConfig,\r\n }),\r\n signal: abortControllerRef.current.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`API error: ${response.statusText}`);\r\n }\r\n\r\n // Process stream\r\n await processStream(response.body!, store.getState(), {\r\n onError: config.onError,\r\n onComplete: config.onComplete,\r\n onArtifact: config.onArtifact,\r\n onToolCall: config.onToolCall,\r\n });\r\n } catch (error: any) {\r\n if (error.name === 'AbortError') {\r\n // Aborted, ignore\r\n return;\r\n }\r\n\r\n const errorMessage = error.message || 'Unknown error occurred';\r\n store.getState().setError(errorMessage);\r\n\r\n if (config.onError) {\r\n config.onError(error);\r\n }\r\n } finally {\r\n store.getState().setStreaming(false);\r\n abortControllerRef.current = null;\r\n }\r\n },\r\n [isStreaming, messages, config]\r\n );\r\n\r\n /**\r\n * Regenerate last response\r\n */\r\n const regenerate = useCallback(async (): Promise<void> => {\r\n if (messages.length === 0) return;\r\n\r\n // Remove last assistant message\r\n const lastUserMessage = [...messages]\r\n .reverse()\r\n .find((msg) => msg.role === 'user');\r\n\r\n if (lastUserMessage) {\r\n await sendMessage(lastUserMessage.content);\r\n }\r\n }, [messages, sendMessage]);\r\n\r\n /**\r\n * Stop streaming\r\n */\r\n const stop = useCallback(() => {\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n }, []);\r\n\r\n /**\r\n * Clear conversation\r\n */\r\n const clear = useCallback(() => {\r\n store.getState().reset();\r\n }, [store]);\r\n\r\n /**\r\n * Append to messages\r\n */\r\n const append = useCallback(\r\n (message: Message) => {\r\n store.getState().addMessage(message);\r\n },\r\n [store]\r\n );\r\n\r\n /**\r\n * Set messages\r\n */\r\n const setMessages = useCallback(\r\n (newMessages: Message[]) => {\r\n store.getState().reset();\r\n newMessages.forEach((msg) => store.getState().addMessage(msg));\r\n },\r\n [store]\r\n );\r\n\r\n /**\r\n * Execute tool call\r\n */\r\n const executeToolCall = useCallback(\r\n async (toolCall: ToolCall, result: unknown): Promise<void> => {\r\n const toolResult: ToolResult = {\r\n toolCallId: toolCall.id,\r\n result,\r\n };\r\n\r\n store.getState().addToolResult(toolResult);\r\n },\r\n [store]\r\n );\r\n\r\n // Cleanup on unmount\r\n useEffect(() => {\r\n return () => {\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n };\r\n }, []);\r\n\r\n return {\r\n // State\r\n messages,\r\n currentMessage,\r\n isStreaming,\r\n error,\r\n artifacts,\r\n currentArtifact,\r\n toolCalls,\r\n usage,\r\n metadata,\r\n\r\n // Actions\r\n sendMessage,\r\n regenerate,\r\n stop,\r\n clear,\r\n append,\r\n setMessages,\r\n executeToolCall,\r\n\r\n // Store (for advanced use)\r\n store,\r\n };\r\n}\r\n\r\n/**\r\n * Process SSE stream\r\n */\r\nasync function processStream(\r\n body: ReadableStream<Uint8Array>,\r\n state: ChatState,\r\n callbacks: {\r\n onError?: (error: Error) => void;\r\n onComplete?: (message: Message) => void;\r\n onArtifact?: (artifact: Artifact) => void;\r\n onToolCall?: (toolCall: ToolCall) => void;\r\n }\r\n): Promise<void> {\r\n const reader = body.getReader();\r\n const decoder = new TextDecoder();\r\n\r\n let buffer = '';\r\n let assistantMessageId = generateId('msg');\r\n let currentArtifactContent = '';\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n const lines = buffer.split('\\n');\r\n buffer = lines.pop() || '';\r\n\r\n for (const line of lines) {\r\n if (!line.trim() || !line.startsWith('data: ')) continue;\r\n\r\n const data = line.slice(6);\r\n if (data === '[DONE]') continue;\r\n\r\n try {\r\n const event = JSON.parse(data) as StreamEvent;\r\n\r\n switch (event.type) {\r\n case 'text-delta':\r\n state.setCurrentMessage(state.currentMessage + event.delta);\r\n break;\r\n\r\n case 'tool-call-start':\r\n state.addToolCall(event.toolCall);\r\n if (callbacks.onToolCall) {\r\n callbacks.onToolCall(event.toolCall);\r\n }\r\n break;\r\n\r\n case 'tool-call-end':\r\n // Tool call complete\r\n break;\r\n\r\n case 'tool-result':\r\n state.addToolResult(event.result);\r\n break;\r\n\r\n case 'artifact-start':\r\n currentArtifactContent = '';\r\n state.setCurrentArtifact({\r\n ...event.artifact,\r\n content: '',\r\n });\r\n break;\r\n\r\n case 'artifact-delta':\r\n currentArtifactContent += event.delta;\r\n if (state.currentArtifact) {\r\n state.setCurrentArtifact({\r\n ...state.currentArtifact,\r\n content: currentArtifactContent,\r\n });\r\n }\r\n break;\r\n\r\n case 'artifact-end':\r\n state.addArtifact(event.artifact);\r\n state.setCurrentArtifact(null);\r\n if (callbacks.onArtifact) {\r\n callbacks.onArtifact(event.artifact);\r\n }\r\n break;\r\n\r\n case 'usage':\r\n state.setUsage(event.usage);\r\n break;\r\n\r\n case 'metadata':\r\n state.setMetadata(event.metadata);\r\n break;\r\n\r\n case 'error':\r\n state.setError(event.error);\r\n if (callbacks.onError) {\r\n callbacks.onError(new Error(event.error));\r\n }\r\n break;\r\n\r\n case 'done':\r\n const finalMessage: Message = {\r\n ...event.finalMessage,\r\n id: assistantMessageId,\r\n };\r\n state.addMessage(finalMessage);\r\n state.setCurrentMessage('');\r\n\r\n if (callbacks.onComplete) {\r\n callbacks.onComplete(finalMessage);\r\n }\r\n break;\r\n }\r\n } catch (error) {\r\n console.error('Failed to parse event:', error);\r\n }\r\n }\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n}"]}
@@ -0,0 +1,3 @@
1
+ import {useRef,useCallback,useEffect}from'react';import'tiktoken';import {nanoid}from'nanoid';import'fast-json-stable-stringify';import'eventemitter3';import'eventsource-parser';import {create}from'zustand';import {subscribeWithSelector}from'zustand/middleware';function h(r){let t=nanoid();return `${r}_${t}`}var w=()=>create()(subscribeWithSelector(r=>({messages:[],currentMessage:"",isStreaming:false,error:null,artifacts:[],currentArtifact:null,toolCalls:[],usage:null,metadata:{},addMessage:t=>r(e=>({messages:[...e.messages,t]})),updateMessage:(t,e)=>r(a=>({messages:a.messages.map(s=>s.id===t?{...s,...e}:s)})),setCurrentMessage:t=>r({currentMessage:t}),setStreaming:t=>r({isStreaming:t}),setError:t=>r({error:t}),addArtifact:t=>r(e=>({artifacts:[...e.artifacts,t]})),setCurrentArtifact:t=>r({currentArtifact:t}),addToolCall:t=>r(e=>({toolCalls:[...e.toolCalls,t]})),addToolResult:t=>r(e=>{let a=e.messages[e.messages.length-1];return a&&a.role==="assistant"?{messages:e.messages.map((s,c)=>c===e.messages.length-1?{...s,toolResults:[...s.toolResults||[],t]}:s)}:e}),setUsage:t=>r({usage:t}),setMetadata:t=>r(e=>({metadata:{...e.metadata,...t}})),reset:()=>r({messages:[],currentMessage:"",isStreaming:false,error:null,artifacts:[],currentArtifact:null,toolCalls:[],usage:null,metadata:{}})})));function ie(r){let e=useRef(w()).current,a=e(n=>n.messages),s=e(n=>n.currentMessage),c=e(n=>n.isStreaming),v=e(n=>n.error),d=e(n=>n.artifacts),y=e(n=>n.currentArtifact),E=e(n=>n.toolCalls),p=e(n=>n.usage),f=e(n=>n.metadata),i=useRef(null),o=useCallback(async(n,u)=>{if(c)throw new Error("Already streaming a response");try{let l={id:h("msg"),role:"user",content:n,timestamp:Date.now()};e.getState().addMessage(l),e.getState().setStreaming(!0),e.getState().setError(null),e.getState().setCurrentMessage(""),i.current=new AbortController;let T={...r.defaultConfig,...u,stream:!0},S=await fetch(r.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json",...r.apiKey&&{Authorization:`Bearer ${r.apiKey}`},...r.headers},body:JSON.stringify({messages:[...a,l],...T}),signal:i.current.signal});if(!S.ok)throw new Error(`API error: ${S.statusText}`);await N(S.body,e.getState(),{onError:r.onError,onComplete:r.onComplete,onArtifact:r.onArtifact,onToolCall:r.onToolCall});}catch(l){if(l.name==="AbortError")return;let T=l.message||"Unknown error occurred";e.getState().setError(T),r.onError&&r.onError(l);}finally{e.getState().setStreaming(false),i.current=null;}},[c,a,r]),g=useCallback(async()=>{if(a.length===0)return;let n=[...a].reverse().find(u=>u.role==="user");n&&await o(n.content);},[a,o]),b=useCallback(()=>{i.current&&i.current.abort();},[]),A=useCallback(()=>{e.getState().reset();},[e]),x=useCallback(n=>{e.getState().addMessage(n);},[e]),k=useCallback(n=>{e.getState().reset(),n.forEach(u=>e.getState().addMessage(u));},[e]),R=useCallback(async(n,u)=>{let l={toolCallId:n.id,result:u};e.getState().addToolResult(l);},[e]);return useEffect(()=>()=>{i.current&&i.current.abort();},[]),{messages:a,currentMessage:s,isStreaming:c,error:v,artifacts:d,currentArtifact:y,toolCalls:E,usage:p,metadata:f,sendMessage:o,regenerate:g,stop:b,clear:A,append:x,setMessages:k,executeToolCall:R,store:e}}async function N(r,t,e){let a=r.getReader(),s=new TextDecoder,c="",v=h("msg"),d="";try{for(;;){let{done:y,value:E}=await a.read();if(y)break;c+=s.decode(E,{stream:!0});let p=c.split(`
2
+ `);c=p.pop()||"";for(let f of p){if(!f.trim()||!f.startsWith("data: "))continue;let i=f.slice(6);if(i!=="[DONE]")try{let o=JSON.parse(i);switch(o.type){case "text-delta":t.setCurrentMessage(t.currentMessage+o.delta);break;case "tool-call-start":t.addToolCall(o.toolCall),e.onToolCall&&e.onToolCall(o.toolCall);break;case "tool-call-end":break;case "tool-result":t.addToolResult(o.result);break;case "artifact-start":d="",t.setCurrentArtifact({...o.artifact,content:""});break;case "artifact-delta":d+=o.delta,t.currentArtifact&&t.setCurrentArtifact({...t.currentArtifact,content:d});break;case "artifact-end":t.addArtifact(o.artifact),t.setCurrentArtifact(null),e.onArtifact&&e.onArtifact(o.artifact);break;case "usage":t.setUsage(o.usage);break;case "metadata":t.setMetadata(o.metadata);break;case "error":t.setError(o.error),e.onError&&e.onError(new Error(o.error));break;case "done":let g={...o.finalMessage,id:v};t.addMessage(g),t.setCurrentMessage(""),e.onComplete&&e.onComplete(g);break}}catch(o){console.error("Failed to parse event:",o);}}}}finally{a.releaseLock();}}export{w as createChatStore,ie as usePaprFlare};//# sourceMappingURL=index.mjs.map
3
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/utils.ts","../../src/react/store/store.ts","../../src/react/client/client.ts"],"names":["generateId","prefix","id","nanoid","createChatStore","create","subscribeWithSelector","set","message","state","updates","msg","isStreaming","error","artifact","toolCall","result","lastMessage","idx","usage","metadata","usePaprFlare","config","store","useRef","messages","currentMessage","artifacts","currentArtifact","toolCalls","abortControllerRef","sendMessage","useCallback","content","options","userMessage","chatConfig","response","processStream","errorMessage","regenerate","lastUserMessage","stop","clear","append","setMessages","newMessages","executeToolCall","toolResult","useEffect","body","callbacks","reader","decoder","buffer","assistantMessageId","currentArtifactContent","done","value","lines","line","data","event","finalMessage"],"mappings":"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","file":"index.mjs","sourcesContent":["import { nanoid } from 'nanoid';\r\nimport stringify from 'fast-json-stable-stringify';\r\nimport type { Message } from '../types';\r\n\r\n/**\r\n * Generate a unique ID\r\n */\r\nexport function generateId(prefix?: string): string {\r\n const id = nanoid();\r\n return prefix ? `${prefix}_${id}` : id;\r\n}\r\n\r\n/**\r\n * Create a stable hash for cache keys\r\n */\r\nexport function createCacheKey(data: unknown): string {\r\n return stringify(data);\r\n}\r\n\r\n/**\r\n * Format messages for provider APIs\r\n */\r\nexport function formatMessages(messages: Message[]): Message[] {\r\n return messages.map((msg) => ({\r\n ...msg,\r\n id: msg.id || generateId('msg'),\r\n timestamp: msg.timestamp || Date.now(),\r\n }));\r\n}\r\n\r\n/**\r\n * Retry with exponential backoff\r\n */\r\nexport async function retry<T>(\r\n fn: () => Promise<T>,\r\n options: {\r\n maxAttempts: number;\r\n initialDelay: number;\r\n maxDelay: number;\r\n backoffMultiplier: number;\r\n onRetry?: (attempt: number, error: Error) => void;\r\n }\r\n): Promise<T> {\r\n let lastError: Error;\r\n let delay = options.initialDelay;\r\n\r\n for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n lastError = error as Error;\r\n\r\n if (attempt === options.maxAttempts) {\r\n throw lastError;\r\n }\r\n\r\n if (options.onRetry) {\r\n options.onRetry(attempt, lastError);\r\n }\r\n\r\n await sleep(Math.min(delay, options.maxDelay));\r\n delay *= options.backoffMultiplier;\r\n }\r\n }\r\n\r\n throw lastError!;\r\n}\r\n\r\n/**\r\n * Sleep for a given duration\r\n */\r\nexport function sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/**\r\n * Chunk an array into smaller arrays\r\n */\r\nexport function chunk<T>(array: T[], size: number): T[][] {\r\n const chunks: T[][] = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n chunks.push(array.slice(i, i + size));\r\n }\r\n return chunks;\r\n}\r\n\r\n/**\r\n * Debounce a function\r\n */\r\nexport function debounce<T extends (...args: any[]) => any>(\r\n fn: T,\r\n delay: number\r\n): (...args: Parameters<T>) => void {\r\n let timeoutId: NodeJS.Timeout;\r\n\r\n return (...args: Parameters<T>) => {\r\n clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => fn(...args), delay);\r\n };\r\n}\r\n\r\n/**\r\n * Throttle a function\r\n */\r\nexport function throttle<T extends (...args: any[]) => any>(\r\n fn: T,\r\n limit: number\r\n): (...args: Parameters<T>) => void {\r\n let inThrottle: boolean;\r\n\r\n return (...args: Parameters<T>) => {\r\n if (!inThrottle) {\r\n fn(...args);\r\n inThrottle = true;\r\n setTimeout(() => (inThrottle = false), limit);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Safely parse JSON\r\n */\r\nexport function safeJsonParse<T = unknown>(json: string): T | null {\r\n try {\r\n return JSON.parse(json) as T;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a value is a plain object\r\n */\r\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\r\n return (\r\n typeof value === 'object' &&\r\n value !== null &&\r\n value.constructor === Object\r\n );\r\n}\r\n\r\n/**\r\n * Deep merge objects\r\n */\r\nexport function deepMerge<T extends Record<string, any>>(\r\n target: T,\r\n ...sources: Partial<T>[]\r\n): T {\r\n if (!sources.length) return target;\r\n\r\n const source = sources.shift();\r\n\r\n if (isPlainObject(target) && isPlainObject(source)) {\r\n for (const key in source) {\r\n if (isPlainObject(source[key])) {\r\n if (!target[key]) Object.assign(target, { [key]: {} });\r\n deepMerge(target[key], source[key] as any);\r\n } else {\r\n Object.assign(target, { [key]: source[key] });\r\n }\r\n }\r\n }\r\n\r\n return deepMerge(target, ...sources);\r\n}\r\n\r\n/**\r\n * Convert async generator to array\r\n */\r\nexport async function streamToArray<T>(\r\n stream: AsyncGenerator<T>\r\n): Promise<T[]> {\r\n const result: T[] = [];\r\n for await (const item of stream) {\r\n result.push(item);\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Measure execution time\r\n */\r\nexport async function measureTime<T>(\r\n fn: () => Promise<T>\r\n): Promise<{ result: T; duration: number }> {\r\n const start = performance.now();\r\n const result = await fn();\r\n const duration = performance.now() - start;\r\n return { result, duration };\r\n}","import { create } from 'zustand';\r\nimport { subscribeWithSelector } from 'zustand/middleware';\r\nimport type { ChatState } from '../../types';\r\n\r\n/**\r\n * Create chat store with Zustand\r\n */\r\nexport const createChatStore = () =>\r\n create<ChatState>()(\r\n subscribeWithSelector((set) => ({\r\n messages: [],\r\n currentMessage: '',\r\n isStreaming: false,\r\n error: null,\r\n artifacts: [],\r\n currentArtifact: null,\r\n toolCalls: [],\r\n usage: null,\r\n metadata: {},\r\n\r\n addMessage: (message) =>\r\n set((state) => ({\r\n messages: [...state.messages, message],\r\n })),\r\n\r\n updateMessage: (id, updates) =>\r\n set((state) => ({\r\n messages: state.messages.map((msg) =>\r\n msg.id === id ? { ...msg, ...updates } : msg\r\n ),\r\n })),\r\n\r\n setCurrentMessage: (message) =>\r\n set({ currentMessage: message }),\r\n\r\n setStreaming: (isStreaming) =>\r\n set({ isStreaming }),\r\n\r\n setError: (error) =>\r\n set({ error }),\r\n\r\n addArtifact: (artifact) =>\r\n set((state) => ({\r\n artifacts: [...state.artifacts, artifact],\r\n })),\r\n\r\n setCurrentArtifact: (artifact) =>\r\n set({ currentArtifact: artifact }),\r\n\r\n addToolCall: (toolCall) =>\r\n set((state) => ({\r\n toolCalls: [...state.toolCalls, toolCall],\r\n })),\r\n\r\n addToolResult: (result) =>\r\n set((state) => {\r\n const lastMessage = state.messages[state.messages.length - 1];\r\n if (lastMessage && lastMessage.role === 'assistant') {\r\n return {\r\n messages: state.messages.map((msg, idx) =>\r\n idx === state.messages.length - 1\r\n ? {\r\n ...msg,\r\n toolResults: [...(msg.toolResults || []), result],\r\n }\r\n : msg\r\n ),\r\n };\r\n }\r\n return state;\r\n }),\r\n\r\n setUsage: (usage) =>\r\n set({ usage }),\r\n\r\n setMetadata: (metadata) =>\r\n set((state) => ({\r\n metadata: { ...state.metadata, ...metadata },\r\n })),\r\n\r\n reset: () =>\r\n set({\r\n messages: [],\r\n currentMessage: '',\r\n isStreaming: false,\r\n error: null,\r\n artifacts: [],\r\n currentArtifact: null,\r\n toolCalls: [],\r\n usage: null,\r\n metadata: {},\r\n }),\r\n }))\r\n );\r\n\r\n","import { useRef, useCallback, useEffect } from 'react';\r\nimport { generateId } from '../../utils';\r\nimport type { Artifact, ChatConfig, ChatState, Message, StreamEvent, ToolCall, ToolResult, UsePaprFlareConfig } from '../../types';\r\nimport { createChatStore } from '../store/store';\r\n/**\r\n * Unified PaprFlare React hook\r\n * Handles all AI interactions with optimized state management using Zustand\r\n */\r\nexport function usePaprFlare(config: UsePaprFlareConfig) {\r\n // Create store instance (stable reference)\r\n const storeRef = useRef(createChatStore());\r\n const store = storeRef.current;\r\n\r\n // Use Zustand store\r\n const messages = store((state) => state.messages);\r\n const currentMessage = store((state) => state.currentMessage);\r\n const isStreaming = store((state) => state.isStreaming);\r\n const error = store((state) => state.error);\r\n const artifacts = store((state) => state.artifacts);\r\n const currentArtifact = store((state) => state.currentArtifact);\r\n const toolCalls = store((state) => state.toolCalls);\r\n const usage = store((state) => state.usage);\r\n const metadata = store((state) => state.metadata);\r\n\r\n // Abort controller ref\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n\r\n /**\r\n * Send a message and stream the response\r\n */\r\n const sendMessage = useCallback(\r\n async (\r\n content: string,\r\n options?: Partial<ChatConfig>\r\n ): Promise<void> => {\r\n if (isStreaming) {\r\n throw new Error('Already streaming a response');\r\n }\r\n\r\n try {\r\n // Add user message\r\n const userMessage: Message = {\r\n id: generateId('msg'),\r\n role: 'user',\r\n content,\r\n timestamp: Date.now(),\r\n };\r\n\r\n store.getState().addMessage(userMessage);\r\n store.getState().setStreaming(true);\r\n store.getState().setError(null);\r\n store.getState().setCurrentMessage('');\r\n\r\n // Create abort controller\r\n abortControllerRef.current = new AbortController();\r\n\r\n // Merge configurations\r\n const chatConfig: ChatConfig = {\r\n ...config.defaultConfig,\r\n ...options,\r\n stream: true,\r\n };\r\n\r\n // Make API request\r\n const response = await fetch(config.apiEndpoint, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...(config.apiKey && { Authorization: `Bearer ${config.apiKey}` }),\r\n ...config.headers,\r\n },\r\n body: JSON.stringify({\r\n messages: [...messages, userMessage],\r\n ...chatConfig,\r\n }),\r\n signal: abortControllerRef.current.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`API error: ${response.statusText}`);\r\n }\r\n\r\n // Process stream\r\n await processStream(response.body!, store.getState(), {\r\n onError: config.onError,\r\n onComplete: config.onComplete,\r\n onArtifact: config.onArtifact,\r\n onToolCall: config.onToolCall,\r\n });\r\n } catch (error: any) {\r\n if (error.name === 'AbortError') {\r\n // Aborted, ignore\r\n return;\r\n }\r\n\r\n const errorMessage = error.message || 'Unknown error occurred';\r\n store.getState().setError(errorMessage);\r\n\r\n if (config.onError) {\r\n config.onError(error);\r\n }\r\n } finally {\r\n store.getState().setStreaming(false);\r\n abortControllerRef.current = null;\r\n }\r\n },\r\n [isStreaming, messages, config]\r\n );\r\n\r\n /**\r\n * Regenerate last response\r\n */\r\n const regenerate = useCallback(async (): Promise<void> => {\r\n if (messages.length === 0) return;\r\n\r\n // Remove last assistant message\r\n const lastUserMessage = [...messages]\r\n .reverse()\r\n .find((msg) => msg.role === 'user');\r\n\r\n if (lastUserMessage) {\r\n await sendMessage(lastUserMessage.content);\r\n }\r\n }, [messages, sendMessage]);\r\n\r\n /**\r\n * Stop streaming\r\n */\r\n const stop = useCallback(() => {\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n }, []);\r\n\r\n /**\r\n * Clear conversation\r\n */\r\n const clear = useCallback(() => {\r\n store.getState().reset();\r\n }, [store]);\r\n\r\n /**\r\n * Append to messages\r\n */\r\n const append = useCallback(\r\n (message: Message) => {\r\n store.getState().addMessage(message);\r\n },\r\n [store]\r\n );\r\n\r\n /**\r\n * Set messages\r\n */\r\n const setMessages = useCallback(\r\n (newMessages: Message[]) => {\r\n store.getState().reset();\r\n newMessages.forEach((msg) => store.getState().addMessage(msg));\r\n },\r\n [store]\r\n );\r\n\r\n /**\r\n * Execute tool call\r\n */\r\n const executeToolCall = useCallback(\r\n async (toolCall: ToolCall, result: unknown): Promise<void> => {\r\n const toolResult: ToolResult = {\r\n toolCallId: toolCall.id,\r\n result,\r\n };\r\n\r\n store.getState().addToolResult(toolResult);\r\n },\r\n [store]\r\n );\r\n\r\n // Cleanup on unmount\r\n useEffect(() => {\r\n return () => {\r\n if (abortControllerRef.current) {\r\n abortControllerRef.current.abort();\r\n }\r\n };\r\n }, []);\r\n\r\n return {\r\n // State\r\n messages,\r\n currentMessage,\r\n isStreaming,\r\n error,\r\n artifacts,\r\n currentArtifact,\r\n toolCalls,\r\n usage,\r\n metadata,\r\n\r\n // Actions\r\n sendMessage,\r\n regenerate,\r\n stop,\r\n clear,\r\n append,\r\n setMessages,\r\n executeToolCall,\r\n\r\n // Store (for advanced use)\r\n store,\r\n };\r\n}\r\n\r\n/**\r\n * Process SSE stream\r\n */\r\nasync function processStream(\r\n body: ReadableStream<Uint8Array>,\r\n state: ChatState,\r\n callbacks: {\r\n onError?: (error: Error) => void;\r\n onComplete?: (message: Message) => void;\r\n onArtifact?: (artifact: Artifact) => void;\r\n onToolCall?: (toolCall: ToolCall) => void;\r\n }\r\n): Promise<void> {\r\n const reader = body.getReader();\r\n const decoder = new TextDecoder();\r\n\r\n let buffer = '';\r\n let assistantMessageId = generateId('msg');\r\n let currentArtifactContent = '';\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n const lines = buffer.split('\\n');\r\n buffer = lines.pop() || '';\r\n\r\n for (const line of lines) {\r\n if (!line.trim() || !line.startsWith('data: ')) continue;\r\n\r\n const data = line.slice(6);\r\n if (data === '[DONE]') continue;\r\n\r\n try {\r\n const event = JSON.parse(data) as StreamEvent;\r\n\r\n switch (event.type) {\r\n case 'text-delta':\r\n state.setCurrentMessage(state.currentMessage + event.delta);\r\n break;\r\n\r\n case 'tool-call-start':\r\n state.addToolCall(event.toolCall);\r\n if (callbacks.onToolCall) {\r\n callbacks.onToolCall(event.toolCall);\r\n }\r\n break;\r\n\r\n case 'tool-call-end':\r\n // Tool call complete\r\n break;\r\n\r\n case 'tool-result':\r\n state.addToolResult(event.result);\r\n break;\r\n\r\n case 'artifact-start':\r\n currentArtifactContent = '';\r\n state.setCurrentArtifact({\r\n ...event.artifact,\r\n content: '',\r\n });\r\n break;\r\n\r\n case 'artifact-delta':\r\n currentArtifactContent += event.delta;\r\n if (state.currentArtifact) {\r\n state.setCurrentArtifact({\r\n ...state.currentArtifact,\r\n content: currentArtifactContent,\r\n });\r\n }\r\n break;\r\n\r\n case 'artifact-end':\r\n state.addArtifact(event.artifact);\r\n state.setCurrentArtifact(null);\r\n if (callbacks.onArtifact) {\r\n callbacks.onArtifact(event.artifact);\r\n }\r\n break;\r\n\r\n case 'usage':\r\n state.setUsage(event.usage);\r\n break;\r\n\r\n case 'metadata':\r\n state.setMetadata(event.metadata);\r\n break;\r\n\r\n case 'error':\r\n state.setError(event.error);\r\n if (callbacks.onError) {\r\n callbacks.onError(new Error(event.error));\r\n }\r\n break;\r\n\r\n case 'done':\r\n const finalMessage: Message = {\r\n ...event.finalMessage,\r\n id: assistantMessageId,\r\n };\r\n state.addMessage(finalMessage);\r\n state.setCurrentMessage('');\r\n\r\n if (callbacks.onComplete) {\r\n callbacks.onComplete(finalMessage);\r\n }\r\n break;\r\n }\r\n } catch (error) {\r\n console.error('Failed to parse event:', error);\r\n }\r\n }\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n}"]}
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "paprflare-sdk",
3
+ "version": "0.0.1",
4
+ "description": "Production-ready AI streaming SDK",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./react": {
15
+ "types": "./dist/react/index.d.ts",
16
+ "import": "./dist/react/index.mjs",
17
+ "require": "./dist/react/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsup",
25
+ "dev": "tsup --watch",
26
+ "test": "vitest",
27
+ "lint": "eslint src",
28
+ "type-check": "tsc --noEmit"
29
+ },
30
+ "keywords": [
31
+ "ai",
32
+ "streaming",
33
+ "llm",
34
+ "chat",
35
+ "artifacts",
36
+ "tools"
37
+ ],
38
+ "author": "PaprFlare",
39
+ "license": "MIT",
40
+ "dependencies": {
41
+ "@types/react": "^19.2.13",
42
+ "async-mutex": "^0.5.0",
43
+ "eventemitter3": "^5.0.4",
44
+ "eventsource-parser": "^3.0.6",
45
+ "fast-json-stable-stringify": "^2.1.0",
46
+ "h3": "^2.0.1-rc.14",
47
+ "ioredis": "^5.9.2",
48
+ "lru-cache": "^11.2.5",
49
+ "nanoid": "^5.1.6",
50
+ "p-queue": "^9.1.0",
51
+ "p-retry": "^7.1.1",
52
+ "p-timeout": "^7.0.1",
53
+ "quick-lru": "^7.3.0",
54
+ "stream-chain": "^3.4.0",
55
+ "streaming-iterables": "^8.0.1",
56
+ "tiktoken": "^1.0.22",
57
+ "use-deep-compare-effect": "^1.8.1",
58
+ "xstate": "^5.26.0",
59
+ "zod": "^4.3.6",
60
+ "zustand": "^5.0.11"
61
+ },
62
+ "devDependencies": {
63
+ "@types/node": "^25.2.2",
64
+ "eslint": "^10.0.0",
65
+ "tsup": "^8.5.1",
66
+ "typescript": "^5.9.3",
67
+ "vitest": "^4.0.18"
68
+ },
69
+ "peerDependencies": {
70
+ "react": "^19.2.4"
71
+ },
72
+ "peerDependenciesMeta": {
73
+ "react": {
74
+ "optional": true
75
+ }
76
+ }
77
+ }