paprflare-sdk 0.0.20 → 0.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -441,11 +441,8 @@ interface ChatState {
441
441
  messages: Message[];
442
442
  isStreaming: boolean;
443
443
  error: string | null;
444
- currentStreamingMessage: Message | null;
445
444
  addMessage: (message: Message) => void;
446
445
  updateMessage: (id: string, updates: Partial<Message>) => void;
447
- updateCurrentStreamingMessage: (message: Message) => void;
448
- clearCurrentStreamingMessage: () => void;
449
446
  setStreaming: (isStreaming: boolean) => void;
450
447
  setError: (error: string | null) => void;
451
448
  reset: () => void;
package/dist/index.d.ts CHANGED
@@ -441,11 +441,8 @@ interface ChatState {
441
441
  messages: Message[];
442
442
  isStreaming: boolean;
443
443
  error: string | null;
444
- currentStreamingMessage: Message | null;
445
444
  addMessage: (message: Message) => void;
446
445
  updateMessage: (id: string, updates: Partial<Message>) => void;
447
- updateCurrentStreamingMessage: (message: Message) => void;
448
- clearCurrentStreamingMessage: () => void;
449
446
  setStreaming: (isStreaming: boolean) => void;
450
447
  setError: (error: string | null) => void;
451
448
  reset: () => void;
@@ -79,11 +79,8 @@ interface ChatState {
79
79
  messages: Message[];
80
80
  isStreaming: boolean;
81
81
  error: string | null;
82
- currentStreamingMessage: Message | null;
83
82
  addMessage: (message: Message) => void;
84
83
  updateMessage: (id: string, updates: Partial<Message>) => void;
85
- updateCurrentStreamingMessage: (message: Message) => void;
86
- clearCurrentStreamingMessage: () => void;
87
84
  setStreaming: (isStreaming: boolean) => void;
88
85
  setError: (error: string | null) => void;
89
86
  reset: () => void;
@@ -79,11 +79,8 @@ interface ChatState {
79
79
  messages: Message[];
80
80
  isStreaming: boolean;
81
81
  error: string | null;
82
- currentStreamingMessage: Message | null;
83
82
  addMessage: (message: Message) => void;
84
83
  updateMessage: (id: string, updates: Partial<Message>) => void;
85
- updateCurrentStreamingMessage: (message: Message) => void;
86
- clearCurrentStreamingMessage: () => void;
87
84
  setStreaming: (isStreaming: boolean) => void;
88
85
  setError: (error: string | null) => void;
89
86
  reset: () => void;
@@ -1,3 +1,3 @@
1
- 'use strict';var react=require('react'),nanoid=require('nanoid'),zustand=require('zustand'),middleware=require('zustand/middleware');function M(s){let r=nanoid.nanoid();return `${s}_${r}`}var h=()=>zustand.create()(middleware.subscribeWithSelector(s=>({messages:[],isStreaming:false,error:null,currentStreamingMessage:null,addMessage:r=>s(t=>({messages:[...t.messages,r]})),updateMessage:(r,t)=>s(o=>({messages:o.messages.map(l=>l.id===r?{...l,...t}:l)})),updateCurrentStreamingMessage:r=>s({currentStreamingMessage:r}),clearCurrentStreamingMessage:()=>s({currentStreamingMessage:null}),setStreaming:r=>s({isStreaming:r}),setError:r=>s({error:r}),reset:()=>s({messages:[],isStreaming:false,error:null,currentStreamingMessage:null})})));function P(s){let t=react.useRef(h()).current,o=t(a=>a.messages),l=t(a=>a.isStreaming),u=t(a=>a.error),e=react.useRef(null),i=react.useCallback(async(a,c)=>{if(l)throw new Error("Already streaming a response");try{let n={id:M("msg"),role:"user",content:a,timestamp:Date.now()};t.getState().addMessage(n),t.getState().setStreaming(!0),t.getState().setError(null),e.current=new AbortController;let g=await fetch(s.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json",...s.headers},body:JSON.stringify({messages:[...o,n],stream:!0,...c}),signal:e.current.signal});if(!g.ok)throw new Error(`API error: ${g.statusText}`);await x(g.body,t.getState(),s);}catch(n){if(n.name==="AbortError")return;let g=n.message||"Unknown error occurred";t.getState().setError(g),s.onError&&s.onError(n);}finally{t.getState().setStreaming(false),e.current=null;}},[l,o,s,t]),S=react.useCallback(async()=>{if(o.length===0)return;let a=[...o].reverse().find(n=>n.role==="user");if(!a)return;let c=o.filter((n,g)=>!(n.role==="assistant"&&g===o.length-1));t.getState().reset(),c.forEach(n=>t.getState().addMessage(n)),await i(a.content);},[o,i,t]),C=react.useCallback(()=>{e.current&&e.current.abort();},[]),f=react.useCallback(()=>{t.getState().reset();},[t]),d=react.useCallback(a=>{t.getState().addMessage(a);},[t]),p=react.useCallback(a=>{t.getState().reset(),a.forEach(c=>t.getState().addMessage(c));},[t]);return react.useEffect(()=>()=>{e.current&&e.current.abort();},[]),{messages:o,isStreaming:l,error:u,sendMessage:i,regenerate:S,stop:C,clear:f,append:d,setMessages:p,store:t}}async function x(s,r,t){let o=s.getReader(),l=new TextDecoder,u="",e={id:M("msg"),role:"assistant",content:"",timestamp:Date.now()},i=-1;try{for(;;){let{done:S,value:C}=await o.read();if(S)break;u+=l.decode(C,{stream:!0});let f=u.split(`
2
- `);u=f.pop()||"";for(let d of f){if(!d.trim()||!d.startsWith("data: "))continue;let p=d.slice(6);if(p!=="[DONE]")try{let a=JSON.parse(p);switch(a.type){case "text-delta":e.content+=a.delta,r.updateCurrentStreamingMessage(e);break;case "tool-call-start":e.toolCalls||(e.toolCalls=[]),e.toolCalls.push(a.toolCall),r.updateCurrentStreamingMessage(e),t.onToolCall&&t.onToolCall(a.toolCall);break;case "tool-call-end":r.updateCurrentStreamingMessage(e);break;case "tool-result":e.toolResults||(e.toolResults=[]),e.toolResults.push(a.result),r.updateCurrentStreamingMessage(e);break;case "artifact-start":e.metadata||(e.metadata={}),e.metadata.artifacts||(e.metadata.artifacts=[]),e.metadata.artifacts.push({...a.artifact,content:""}),i=e.metadata.artifacts.length-1,r.updateCurrentStreamingMessage(e);break;case "artifact-delta":if(e.metadata?.artifacts&&i>=0){let n=e.metadata.artifacts;n[i].content+=a.delta,r.updateCurrentStreamingMessage(e);}break;case "artifact-end":if(e.metadata?.artifacts&&i>=0){let n=e.metadata.artifacts;n[i]={...n[i],...a.artifact},r.updateCurrentStreamingMessage(e),t.onArtifact&&t.onArtifact(a.artifact);}i=-1;break;case "metadata":e.metadata||(e.metadata={}),e.metadata={...e.metadata,...a.metadata},r.updateCurrentStreamingMessage(e);break;case "usage":e.metadata||(e.metadata={}),e.metadata.usage=a.usage,r.updateCurrentStreamingMessage(e);break;case "error":r.setError(a.error),t.onError&&t.onError(new Error(a.error));break;case "done":let c={...e,...a.finalMessage};r.addMessage(c),r.clearCurrentStreamingMessage(),t.onComplete&&t.onComplete(c);break}}catch(a){console.error("Failed to parse SSE event:",a);}}}}finally{o.releaseLock();}}function O(s){return ()=>P(s)}exports.createChatStore=h;exports.createUsePaprFlare=O;exports.usePaprFlare=P;//# sourceMappingURL=index.js.map
1
+ 'use strict';var react=require('react'),nanoid=require('nanoid'),zustand=require('zustand'),middleware=require('zustand/middleware');function b(o){let c=nanoid.nanoid();return `${o}_${c}`}var w=()=>zustand.create()(middleware.subscribeWithSelector(o=>({messages:[],isStreaming:false,error:null,addMessage:c=>o(e=>({messages:[...e.messages,c]})),updateMessage:(c,e)=>o(g=>({messages:g.messages.map(d=>d.id===c?{...d,...e}:d)})),setStreaming:c=>o({isStreaming:c}),setError:c=>o({error:c}),reset:()=>o({messages:[],isStreaming:false,error:null})})));function P(o){let e=react.useRef(w()).current,g=e(l=>l.messages),d=e(l=>l.isStreaming),p=e(l=>l.error),s=react.useRef(null),m=react.useRef(null),M=react.useCallback(async(l,r)=>{if(d)throw new Error("Already streaming a response");try{let t={id:b("msg"),role:"user",content:l,timestamp:Date.now()};e.getState().addMessage(t),e.getState().setStreaming(!0),e.getState().setError(null),s.current=new AbortController;let n=await fetch(o.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json",...o.headers},body:JSON.stringify({messages:[...g,t],stream:!0,...r}),signal:s.current.signal});if(!n.ok)throw new Error(`API error: ${n.statusText}`);if(!n.body)throw new Error("Response body is null");await R(n.body,e.getState,o);}catch(t){if(t.name==="AbortError")return;let n=t.message||"Unknown error occurred";e.getState().setError(n),o.onError&&o.onError(t);}finally{e.getState().setStreaming(false),m.current=null,s.current=null;}},[d,g,o,e]),S=react.useCallback(async()=>{if(g.length===0)return;let l=g.map((t,n)=>({msg:t,idx:n})).reverse().find(({msg:t})=>t.role==="user");if(!l)return;let r=g.slice(0,l.idx+1);e.getState().reset(),r.forEach(t=>e.getState().addMessage(t)),await M(l.msg.content);},[g,M,e]),f=react.useCallback(()=>{s.current&&s.current.abort();},[]),h=react.useCallback(()=>{e.getState().reset();},[e]),a=react.useCallback(l=>{e.getState().addMessage(l);},[e]),i=react.useCallback(l=>{e.getState().reset(),l.forEach(r=>e.getState().addMessage(r));},[e]);return react.useEffect(()=>()=>{s.current&&s.current.abort();},[]),{messages:g,isStreaming:d,error:p,sendMessage:M,regenerate:S,stop:f,clear:h,append:a,setMessages:i,store:e}}async function R(o,c,e){let g=o.getReader(),d=new TextDecoder,p="",s=null;try{for(;;){let{done:m,value:M}=await g.read();if(m)break;p+=d.decode(M,{stream:!0});let S=p.split(`
2
+ `);p=S.pop()||"";for(let f of S){if(!f.trim()||!f.startsWith("data: "))continue;let h=f.slice(6).trim();if(h!=="[DONE]")try{let a=JSON.parse(h);console.log("Received event:",a);let i=c();switch(a.type){case "message-start":let l={id:a.messageId||b("msg"),role:"assistant",content:"",timestamp:Date.now()};s=l.id,i.addMessage(l),console.log("Created message:",s);break;case "text-delta":if(s){let r=i.messages.find(t=>t.id===s);r&&(i.updateMessage(s,{content:r.content+a.delta}),console.log("Updated content:",r.content+a.delta));}break;case "text-complete":console.log("Text complete:",a.fullText);break;case "message-complete":if(s&&a.message&&(i.updateMessage(s,{...a.message,isComplete:!0}),e.onComplete)){let r=i.messages.find(t=>t.id===s);r&&e.onComplete(r);}break;case "tool-call-start":if(s){let r=i.messages.find(t=>t.id===s);i.updateMessage(s,{toolCalls:[...r?.toolCalls||[],a.toolCall]}),e.onToolCall&&e.onToolCall(a.toolCall);}break;case "tool-result":if(s){let r=i.messages.find(t=>t.id===s);i.updateMessage(s,{toolResults:[...r?.toolResults||[],a.result]});}break;case "artifact-start":if(s){let r=i.messages.find(n=>n.id===s),t=r?.metadata?.artifacts||[];i.updateMessage(s,{metadata:{...r?.metadata||{},artifacts:[...t,{...a.artifact,content:""}]}});}break;case "artifact-delta":if(s){let r=i.messages.find(C=>C.id===s),t=[...r?.metadata?.artifacts||[]],n=t.length-1;n>=0&&(t[n]={...t[n],content:t[n].content+a.delta},i.updateMessage(s,{metadata:{...r?.metadata||{},artifacts:t}}));}break;case "artifact-end":if(s){let r=i.messages.find(C=>C.id===s),t=[...r?.metadata?.artifacts||[]],n=t.length-1;n>=0&&(t[n]={...t[n],...a.artifact},i.updateMessage(s,{metadata:{...r?.metadata||{},artifacts:t}}),e.onArtifact&&e.onArtifact(a.artifact));}break;case "error":i.setError(a.error),e.onError&&e.onError(new Error(a.error));break;default:console.log("Unknown event type:",a.type);}}catch(a){console.error("Failed to parse SSE event:",a,"Line:",f);}}}}catch(m){throw console.error("Stream processing error:",m),m}finally{g.releaseLock();}}function N(o){return ()=>P(o)}exports.createChatStore=w;exports.createUsePaprFlare=N;exports.usePaprFlare=P;//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/utils/index.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","usePaprFlare","config","store","useRef","messages","abortControllerRef","sendMessage","useCallback","content","options","userMessage","response","processStream","errorMessage","regenerate","lastUserMessage","filteredMessages","idx","stop","clear","append","setMessages","newMessages","useEffect","body","reader","decoder","buffer","currentMessage","currentArtifactIndex","done","value","lines","line","data","event","artifacts","finalMessage","createUsePaprFlare"],"mappings":"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","file":"index.js","sourcesContent":["import { nanoid } from \"nanoid\";\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}","import { create } from 'zustand';\r\nimport { subscribeWithSelector } from 'zustand/middleware';\r\nimport type { ChatState } from '../../types';\r\n\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 isStreaming: false,\r\n error: null,\r\n currentStreamingMessage: null,\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 updateCurrentStreamingMessage: (message) =>\r\n set({ currentStreamingMessage: message }),\r\n\r\n clearCurrentStreamingMessage: () =>\r\n set({ currentStreamingMessage: null }),\r\n\r\n setStreaming: (isStreaming) => set({ isStreaming }),\r\n\r\n setError: (error) => set({ error }),\r\n\r\n reset: () =>\r\n set({\r\n messages: [],\r\n isStreaming: false,\r\n error: null,\r\n currentStreamingMessage: null,\r\n }),\r\n }))\r\n );","import { useRef, useCallback, useEffect } from 'react';\r\nimport { generateId } from '../utils';\r\nimport type { Message, ChatConfig, UsePaprFlareConfig, StreamEvent } from '../../types';\r\nimport { createChatStore } from '../store/store';\r\n\r\n/**\r\n * Simplified PaprFlare React hook\r\n * Everything flows through messages - unified state management\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 // Core state - simplified to essentials\r\n const messages = store((state) => state.messages);\r\n const isStreaming = store((state) => state.isStreaming);\r\n const error = store((state) => state.error);\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 (content: string, options?: Partial<ChatConfig>): 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\r\n // Create abort controller\r\n abortControllerRef.current = new AbortController();\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.headers,\r\n },\r\n body: JSON.stringify({\r\n messages: [...messages, userMessage],\r\n stream: true,\r\n ...options,\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(), config);\r\n } catch (error: any) {\r\n if (error.name === 'AbortError') return;\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, store]\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 // Find last user message\r\n const lastUserMessage = [...messages]\r\n .reverse()\r\n .find((msg) => msg.role === 'user');\r\n\r\n if (!lastUserMessage) return;\r\n\r\n // Remove last assistant message if exists\r\n const filteredMessages = messages.filter(\r\n (msg, idx) =>\r\n !(msg.role === 'assistant' && idx === messages.length - 1)\r\n );\r\n\r\n // Update messages and resend\r\n store.getState().reset();\r\n filteredMessages.forEach((msg) => store.getState().addMessage(msg));\r\n\r\n await sendMessage(lastUserMessage.content);\r\n }, [messages, sendMessage, store]);\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 message\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 // 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 - simplified\r\n messages,\r\n isStreaming,\r\n error,\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\r\n // Store (for advanced use)\r\n store,\r\n };\r\n}\r\n\r\n/**\r\n * Process SSE stream - builds complete messages with all data unified\r\n */\r\nasync function processStream(\r\n body: ReadableStream<Uint8Array>,\r\n state: any,\r\n config: UsePaprFlareConfig\r\n): Promise<void> {\r\n const reader = body.getReader();\r\n const decoder = new TextDecoder();\r\n\r\n let buffer = '';\r\n\r\n // Build assistant message progressively\r\n let currentMessage: Message = {\r\n id: generateId('msg'),\r\n role: 'assistant',\r\n content: '',\r\n timestamp: Date.now(),\r\n };\r\n\r\n // Track current artifact being built\r\n let currentArtifactIndex = -1;\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 // Append text to message content\r\n currentMessage.content += event.delta;\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'tool-call-start':\r\n // Add tool call to message\r\n if (!currentMessage.toolCalls) {\r\n currentMessage.toolCalls = [];\r\n }\r\n currentMessage.toolCalls.push(event.toolCall);\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n\r\n // Call callback if provided\r\n if (config.onToolCall) {\r\n config.onToolCall(event.toolCall);\r\n }\r\n break;\r\n\r\n case 'tool-call-end':\r\n // Tool call complete - already in message\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'tool-result':\r\n // Add tool result to message\r\n if (!currentMessage.toolResults) {\r\n currentMessage.toolResults = [];\r\n }\r\n currentMessage.toolResults.push(event.result);\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'artifact-start':\r\n // Initialize artifact in message metadata\r\n if (!currentMessage.metadata) {\r\n currentMessage.metadata = {};\r\n }\r\n if (!currentMessage.metadata.artifacts) {\r\n currentMessage.metadata.artifacts = [];\r\n }\r\n\r\n // Add new artifact\r\n (currentMessage.metadata.artifacts as any[]).push({\r\n ...event.artifact,\r\n content: '',\r\n });\r\n\r\n currentArtifactIndex = (currentMessage.metadata.artifacts as any[]).length - 1;\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'artifact-delta':\r\n // Update current artifact content\r\n if (\r\n currentMessage.metadata?.artifacts &&\r\n currentArtifactIndex >= 0\r\n ) {\r\n const artifacts = currentMessage.metadata.artifacts as any[];\r\n artifacts[currentArtifactIndex].content += event.delta;\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n }\r\n break;\r\n\r\n case 'artifact-end':\r\n // Finalize artifact\r\n if (\r\n currentMessage.metadata?.artifacts &&\r\n currentArtifactIndex >= 0\r\n ) {\r\n const artifacts = currentMessage.metadata.artifacts as any[];\r\n artifacts[currentArtifactIndex] = {\r\n ...artifacts[currentArtifactIndex],\r\n ...event.artifact,\r\n };\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n\r\n // Call callback if provided\r\n if (config.onArtifact) {\r\n config.onArtifact(event.artifact);\r\n }\r\n }\r\n currentArtifactIndex = -1;\r\n break;\r\n\r\n case 'metadata':\r\n // Merge custom metadata\r\n if (!currentMessage.metadata) {\r\n currentMessage.metadata = {};\r\n }\r\n currentMessage.metadata = {\r\n ...currentMessage.metadata,\r\n ...event.metadata,\r\n };\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'usage':\r\n // Add usage to metadata\r\n if (!currentMessage.metadata) {\r\n currentMessage.metadata = {};\r\n }\r\n currentMessage.metadata.usage = event.usage;\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'error':\r\n state.setError(event.error);\r\n if (config.onError) {\r\n config.onError(new Error(event.error));\r\n }\r\n break;\r\n\r\n case 'done':\r\n // Finalize and add complete message\r\n const finalMessage: Message = {\r\n ...currentMessage,\r\n ...event.finalMessage,\r\n };\r\n\r\n state.addMessage(finalMessage);\r\n state.clearCurrentStreamingMessage();\r\n\r\n if (config.onComplete) {\r\n config.onComplete(finalMessage);\r\n }\r\n break;\r\n }\r\n } catch (error) {\r\n console.error('Failed to parse SSE event:', error);\r\n }\r\n }\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create configured hook\r\n */\r\nexport function createUsePaprFlare(config: UsePaprFlareConfig) {\r\n return () => usePaprFlare(config);\r\n}"]}
1
+ {"version":3,"sources":["../../src/react/utils/index.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","usePaprFlare","config","store","useRef","messages","abortControllerRef","streamingMessageIdRef","sendMessage","useCallback","content","options","userMessage","response","processStream","errorMessage","regenerate","lastUserMessageIndex","idx","newMessages","stop","clear","append","setMessages","useEffect","body","getState","reader","decoder","buffer","messageId","done","value","lines","line","data","event","assistantMessage","currentMsg","m","finalMsg","msgWithToolCall","msgForArtifact","existingArtifacts","msgWithArtifact","artifacts","lastIndex","msgWithArtifactEnd","artifactsEnd","createUsePaprFlare"],"mappings":"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","file":"index.js","sourcesContent":["import { nanoid } from \"nanoid\";\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}","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 isStreaming: false,\r\n error: null,\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 setStreaming: (isStreaming) => set({ isStreaming }),\r\n\r\n setError: (error) => set({ error }),\r\n\r\n reset: () =>\r\n set({\r\n messages: [],\r\n isStreaming: false,\r\n error: null,\r\n }),\r\n }))\r\n );","import { useRef, useCallback, useEffect } from 'react';\r\nimport { generateId } from '../utils';\r\nimport type { Message, ChatConfig, UsePaprFlareConfig } from '../../types';\r\nimport { createChatStore } from '../store/store';\r\n\r\n/**\r\n * Simplified PaprFlare React hook\r\n * Everything flows through messages - unified state management\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 // Core state - simplified to essentials\r\n const messages = store((state) => state.messages);\r\n const isStreaming = store((state) => state.isStreaming);\r\n const error = store((state) => state.error);\r\n\r\n // Abort controller ref\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n\r\n // Track current streaming message ID\r\n const streamingMessageIdRef = useRef<string | 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 (content: string, options?: Partial<ChatConfig>): 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\r\n // Create abort controller\r\n abortControllerRef.current = new AbortController();\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.headers,\r\n },\r\n body: JSON.stringify({\r\n messages: [...messages, userMessage],\r\n stream: true,\r\n ...options,\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 if (!response.body) {\r\n throw new Error('Response body is null');\r\n }\r\n\r\n // Process stream\r\n await processStream(\r\n response.body,\r\n store.getState,\r\n config\r\n );\r\n } catch (error: any) {\r\n if (error.name === 'AbortError') {\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 streamingMessageIdRef.current = null;\r\n abortControllerRef.current = null;\r\n }\r\n },\r\n [isStreaming, messages, config, store]\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 // Find last user message\r\n const lastUserMessageIndex = messages\r\n .map((msg, idx) => ({ msg, idx }))\r\n .reverse()\r\n .find(({ msg }) => msg.role === 'user');\r\n\r\n if (!lastUserMessageIndex) return;\r\n\r\n // Remove all messages after the last user message\r\n const newMessages = messages.slice(0, lastUserMessageIndex.idx + 1);\r\n\r\n store.getState().reset();\r\n newMessages.forEach((msg) => store.getState().addMessage(msg));\r\n\r\n await sendMessage(lastUserMessageIndex.msg.content);\r\n }, [messages, sendMessage, store]);\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 message\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 // 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 - simplified\r\n messages,\r\n isStreaming,\r\n error,\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\r\n // Store (for advanced use)\r\n store,\r\n };\r\n}\r\n\r\n/**\r\n * Process SSE stream - updates message in place\r\n * Handles your server's event format: message-start, text-delta, text-complete, message-complete\r\n */\r\nasync function processStream(\r\n body: ReadableStream<Uint8Array>,\r\n getState: () => any,\r\n config: UsePaprFlareConfig\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 messageId: string | null = null;\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).trim();\r\n if (data === '[DONE]') continue;\r\n\r\n try {\r\n const event = JSON.parse(data);\r\n console.log('Received event:', event); // Debug log\r\n\r\n const state = getState();\r\n\r\n switch (event.type) {\r\n case 'message-start':\r\n // Create empty assistant message\r\n const assistantMessage: Message = {\r\n id: event.messageId || generateId('msg'),\r\n role: 'assistant',\r\n content: '',\r\n timestamp: Date.now(),\r\n };\r\n\r\n messageId = assistantMessage.id;\r\n state.addMessage(assistantMessage);\r\n console.log('Created message:', messageId); // Debug log\r\n break;\r\n\r\n case 'text-delta':\r\n // Append text to message content\r\n if (messageId) {\r\n const currentMsg = state.messages.find((m: Message) => m.id === messageId);\r\n if (currentMsg) {\r\n state.updateMessage(messageId, {\r\n content: currentMsg.content + event.delta,\r\n });\r\n console.log('Updated content:', currentMsg.content + event.delta); // Debug log\r\n }\r\n }\r\n break;\r\n\r\n case 'text-complete':\r\n // Optional: can be used to verify final text\r\n console.log('Text complete:', event.fullText);\r\n break;\r\n\r\n case 'message-complete':\r\n // Finalize message\r\n if (messageId && event.message) {\r\n state.updateMessage(messageId, {\r\n ...event.message,\r\n isComplete: true,\r\n });\r\n\r\n if (config.onComplete) {\r\n const finalMsg = state.messages.find((m: Message) => m.id === messageId);\r\n if (finalMsg) {\r\n config.onComplete(finalMsg);\r\n }\r\n }\r\n }\r\n break;\r\n\r\n case 'tool-call-start':\r\n if (messageId) {\r\n const currentMsg = state.messages.find((m: Message) => m.id === messageId);\r\n state.updateMessage(messageId, {\r\n toolCalls: [...(currentMsg?.toolCalls || []), event.toolCall],\r\n });\r\n\r\n if (config.onToolCall) {\r\n config.onToolCall(event.toolCall);\r\n }\r\n }\r\n break;\r\n\r\n case 'tool-result':\r\n if (messageId) {\r\n const msgWithToolCall = state.messages.find((m: Message) => m.id === messageId);\r\n state.updateMessage(messageId, {\r\n toolResults: [...(msgWithToolCall?.toolResults || []), event.result],\r\n });\r\n }\r\n break;\r\n\r\n case 'artifact-start':\r\n if (messageId) {\r\n const msgForArtifact = state.messages.find((m: Message) => m.id === messageId);\r\n const existingArtifacts = msgForArtifact?.metadata?.artifacts || [];\r\n\r\n state.updateMessage(messageId, {\r\n metadata: {\r\n ...(msgForArtifact?.metadata || {}),\r\n artifacts: [\r\n ...existingArtifacts,\r\n { ...event.artifact, content: '' },\r\n ],\r\n },\r\n });\r\n }\r\n break;\r\n\r\n case 'artifact-delta':\r\n if (messageId) {\r\n const msgWithArtifact = state.messages.find((m: Message) => m.id === messageId);\r\n const artifacts = [...(msgWithArtifact?.metadata?.artifacts || [])];\r\n const lastIndex = artifacts.length - 1;\r\n\r\n if (lastIndex >= 0) {\r\n artifacts[lastIndex] = {\r\n ...artifacts[lastIndex],\r\n content: artifacts[lastIndex].content + event.delta,\r\n };\r\n\r\n state.updateMessage(messageId, {\r\n metadata: {\r\n ...(msgWithArtifact?.metadata || {}),\r\n artifacts,\r\n },\r\n });\r\n }\r\n }\r\n break;\r\n\r\n case 'artifact-end':\r\n if (messageId) {\r\n const msgWithArtifactEnd = state.messages.find((m: Message) => m.id === messageId);\r\n const artifactsEnd = [...(msgWithArtifactEnd?.metadata?.artifacts || [])];\r\n const lastIndex = artifactsEnd.length - 1;\r\n\r\n if (lastIndex >= 0) {\r\n artifactsEnd[lastIndex] = {\r\n ...artifactsEnd[lastIndex],\r\n ...event.artifact,\r\n };\r\n\r\n state.updateMessage(messageId, {\r\n metadata: {\r\n ...(msgWithArtifactEnd?.metadata || {}),\r\n artifacts: artifactsEnd,\r\n },\r\n });\r\n\r\n if (config.onArtifact) {\r\n config.onArtifact(event.artifact);\r\n }\r\n }\r\n }\r\n break;\r\n\r\n case 'error':\r\n state.setError(event.error);\r\n if (config.onError) {\r\n config.onError(new Error(event.error));\r\n }\r\n break;\r\n\r\n default:\r\n console.log('Unknown event type:', event.type);\r\n }\r\n } catch (error) {\r\n console.error('Failed to parse SSE event:', error, 'Line:', line);\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n console.error('Stream processing error:', error);\r\n throw error;\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create configured hook\r\n */\r\nexport function createUsePaprFlare(config: UsePaprFlareConfig) {\r\n return () => usePaprFlare(config);\r\n}"]}
@@ -1,3 +1,3 @@
1
- import {useRef,useCallback,useEffect}from'react';import {nanoid}from'nanoid';import {create}from'zustand';import {subscribeWithSelector}from'zustand/middleware';function M(s){let r=nanoid();return `${s}_${r}`}var h=()=>create()(subscribeWithSelector(s=>({messages:[],isStreaming:false,error:null,currentStreamingMessage:null,addMessage:r=>s(t=>({messages:[...t.messages,r]})),updateMessage:(r,t)=>s(o=>({messages:o.messages.map(l=>l.id===r?{...l,...t}:l)})),updateCurrentStreamingMessage:r=>s({currentStreamingMessage:r}),clearCurrentStreamingMessage:()=>s({currentStreamingMessage:null}),setStreaming:r=>s({isStreaming:r}),setError:r=>s({error:r}),reset:()=>s({messages:[],isStreaming:false,error:null,currentStreamingMessage:null})})));function P(s){let t=useRef(h()).current,o=t(a=>a.messages),l=t(a=>a.isStreaming),u=t(a=>a.error),e=useRef(null),i=useCallback(async(a,c)=>{if(l)throw new Error("Already streaming a response");try{let n={id:M("msg"),role:"user",content:a,timestamp:Date.now()};t.getState().addMessage(n),t.getState().setStreaming(!0),t.getState().setError(null),e.current=new AbortController;let g=await fetch(s.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json",...s.headers},body:JSON.stringify({messages:[...o,n],stream:!0,...c}),signal:e.current.signal});if(!g.ok)throw new Error(`API error: ${g.statusText}`);await x(g.body,t.getState(),s);}catch(n){if(n.name==="AbortError")return;let g=n.message||"Unknown error occurred";t.getState().setError(g),s.onError&&s.onError(n);}finally{t.getState().setStreaming(false),e.current=null;}},[l,o,s,t]),S=useCallback(async()=>{if(o.length===0)return;let a=[...o].reverse().find(n=>n.role==="user");if(!a)return;let c=o.filter((n,g)=>!(n.role==="assistant"&&g===o.length-1));t.getState().reset(),c.forEach(n=>t.getState().addMessage(n)),await i(a.content);},[o,i,t]),C=useCallback(()=>{e.current&&e.current.abort();},[]),f=useCallback(()=>{t.getState().reset();},[t]),d=useCallback(a=>{t.getState().addMessage(a);},[t]),p=useCallback(a=>{t.getState().reset(),a.forEach(c=>t.getState().addMessage(c));},[t]);return useEffect(()=>()=>{e.current&&e.current.abort();},[]),{messages:o,isStreaming:l,error:u,sendMessage:i,regenerate:S,stop:C,clear:f,append:d,setMessages:p,store:t}}async function x(s,r,t){let o=s.getReader(),l=new TextDecoder,u="",e={id:M("msg"),role:"assistant",content:"",timestamp:Date.now()},i=-1;try{for(;;){let{done:S,value:C}=await o.read();if(S)break;u+=l.decode(C,{stream:!0});let f=u.split(`
2
- `);u=f.pop()||"";for(let d of f){if(!d.trim()||!d.startsWith("data: "))continue;let p=d.slice(6);if(p!=="[DONE]")try{let a=JSON.parse(p);switch(a.type){case "text-delta":e.content+=a.delta,r.updateCurrentStreamingMessage(e);break;case "tool-call-start":e.toolCalls||(e.toolCalls=[]),e.toolCalls.push(a.toolCall),r.updateCurrentStreamingMessage(e),t.onToolCall&&t.onToolCall(a.toolCall);break;case "tool-call-end":r.updateCurrentStreamingMessage(e);break;case "tool-result":e.toolResults||(e.toolResults=[]),e.toolResults.push(a.result),r.updateCurrentStreamingMessage(e);break;case "artifact-start":e.metadata||(e.metadata={}),e.metadata.artifacts||(e.metadata.artifacts=[]),e.metadata.artifacts.push({...a.artifact,content:""}),i=e.metadata.artifacts.length-1,r.updateCurrentStreamingMessage(e);break;case "artifact-delta":if(e.metadata?.artifacts&&i>=0){let n=e.metadata.artifacts;n[i].content+=a.delta,r.updateCurrentStreamingMessage(e);}break;case "artifact-end":if(e.metadata?.artifacts&&i>=0){let n=e.metadata.artifacts;n[i]={...n[i],...a.artifact},r.updateCurrentStreamingMessage(e),t.onArtifact&&t.onArtifact(a.artifact);}i=-1;break;case "metadata":e.metadata||(e.metadata={}),e.metadata={...e.metadata,...a.metadata},r.updateCurrentStreamingMessage(e);break;case "usage":e.metadata||(e.metadata={}),e.metadata.usage=a.usage,r.updateCurrentStreamingMessage(e);break;case "error":r.setError(a.error),t.onError&&t.onError(new Error(a.error));break;case "done":let c={...e,...a.finalMessage};r.addMessage(c),r.clearCurrentStreamingMessage(),t.onComplete&&t.onComplete(c);break}}catch(a){console.error("Failed to parse SSE event:",a);}}}}finally{o.releaseLock();}}function O(s){return ()=>P(s)}export{h as createChatStore,O as createUsePaprFlare,P as usePaprFlare};//# sourceMappingURL=index.mjs.map
1
+ import {useRef,useCallback,useEffect}from'react';import {nanoid}from'nanoid';import {create}from'zustand';import {subscribeWithSelector}from'zustand/middleware';function b(o){let c=nanoid();return `${o}_${c}`}var w=()=>create()(subscribeWithSelector(o=>({messages:[],isStreaming:false,error:null,addMessage:c=>o(e=>({messages:[...e.messages,c]})),updateMessage:(c,e)=>o(g=>({messages:g.messages.map(d=>d.id===c?{...d,...e}:d)})),setStreaming:c=>o({isStreaming:c}),setError:c=>o({error:c}),reset:()=>o({messages:[],isStreaming:false,error:null})})));function P(o){let e=useRef(w()).current,g=e(l=>l.messages),d=e(l=>l.isStreaming),p=e(l=>l.error),s=useRef(null),m=useRef(null),M=useCallback(async(l,r)=>{if(d)throw new Error("Already streaming a response");try{let t={id:b("msg"),role:"user",content:l,timestamp:Date.now()};e.getState().addMessage(t),e.getState().setStreaming(!0),e.getState().setError(null),s.current=new AbortController;let n=await fetch(o.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json",...o.headers},body:JSON.stringify({messages:[...g,t],stream:!0,...r}),signal:s.current.signal});if(!n.ok)throw new Error(`API error: ${n.statusText}`);if(!n.body)throw new Error("Response body is null");await R(n.body,e.getState,o);}catch(t){if(t.name==="AbortError")return;let n=t.message||"Unknown error occurred";e.getState().setError(n),o.onError&&o.onError(t);}finally{e.getState().setStreaming(false),m.current=null,s.current=null;}},[d,g,o,e]),S=useCallback(async()=>{if(g.length===0)return;let l=g.map((t,n)=>({msg:t,idx:n})).reverse().find(({msg:t})=>t.role==="user");if(!l)return;let r=g.slice(0,l.idx+1);e.getState().reset(),r.forEach(t=>e.getState().addMessage(t)),await M(l.msg.content);},[g,M,e]),f=useCallback(()=>{s.current&&s.current.abort();},[]),h=useCallback(()=>{e.getState().reset();},[e]),a=useCallback(l=>{e.getState().addMessage(l);},[e]),i=useCallback(l=>{e.getState().reset(),l.forEach(r=>e.getState().addMessage(r));},[e]);return useEffect(()=>()=>{s.current&&s.current.abort();},[]),{messages:g,isStreaming:d,error:p,sendMessage:M,regenerate:S,stop:f,clear:h,append:a,setMessages:i,store:e}}async function R(o,c,e){let g=o.getReader(),d=new TextDecoder,p="",s=null;try{for(;;){let{done:m,value:M}=await g.read();if(m)break;p+=d.decode(M,{stream:!0});let S=p.split(`
2
+ `);p=S.pop()||"";for(let f of S){if(!f.trim()||!f.startsWith("data: "))continue;let h=f.slice(6).trim();if(h!=="[DONE]")try{let a=JSON.parse(h);console.log("Received event:",a);let i=c();switch(a.type){case "message-start":let l={id:a.messageId||b("msg"),role:"assistant",content:"",timestamp:Date.now()};s=l.id,i.addMessage(l),console.log("Created message:",s);break;case "text-delta":if(s){let r=i.messages.find(t=>t.id===s);r&&(i.updateMessage(s,{content:r.content+a.delta}),console.log("Updated content:",r.content+a.delta));}break;case "text-complete":console.log("Text complete:",a.fullText);break;case "message-complete":if(s&&a.message&&(i.updateMessage(s,{...a.message,isComplete:!0}),e.onComplete)){let r=i.messages.find(t=>t.id===s);r&&e.onComplete(r);}break;case "tool-call-start":if(s){let r=i.messages.find(t=>t.id===s);i.updateMessage(s,{toolCalls:[...r?.toolCalls||[],a.toolCall]}),e.onToolCall&&e.onToolCall(a.toolCall);}break;case "tool-result":if(s){let r=i.messages.find(t=>t.id===s);i.updateMessage(s,{toolResults:[...r?.toolResults||[],a.result]});}break;case "artifact-start":if(s){let r=i.messages.find(n=>n.id===s),t=r?.metadata?.artifacts||[];i.updateMessage(s,{metadata:{...r?.metadata||{},artifacts:[...t,{...a.artifact,content:""}]}});}break;case "artifact-delta":if(s){let r=i.messages.find(C=>C.id===s),t=[...r?.metadata?.artifacts||[]],n=t.length-1;n>=0&&(t[n]={...t[n],content:t[n].content+a.delta},i.updateMessage(s,{metadata:{...r?.metadata||{},artifacts:t}}));}break;case "artifact-end":if(s){let r=i.messages.find(C=>C.id===s),t=[...r?.metadata?.artifacts||[]],n=t.length-1;n>=0&&(t[n]={...t[n],...a.artifact},i.updateMessage(s,{metadata:{...r?.metadata||{},artifacts:t}}),e.onArtifact&&e.onArtifact(a.artifact));}break;case "error":i.setError(a.error),e.onError&&e.onError(new Error(a.error));break;default:console.log("Unknown event type:",a.type);}}catch(a){console.error("Failed to parse SSE event:",a,"Line:",f);}}}}catch(m){throw console.error("Stream processing error:",m),m}finally{g.releaseLock();}}function N(o){return ()=>P(o)}export{w as createChatStore,N as createUsePaprFlare,P as usePaprFlare};//# sourceMappingURL=index.mjs.map
3
3
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/utils/index.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","usePaprFlare","config","store","useRef","messages","abortControllerRef","sendMessage","useCallback","content","options","userMessage","response","processStream","errorMessage","regenerate","lastUserMessage","filteredMessages","idx","stop","clear","append","setMessages","newMessages","useEffect","body","reader","decoder","buffer","currentMessage","currentArtifactIndex","done","value","lines","line","data","event","artifacts","finalMessage","createUsePaprFlare"],"mappings":"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","file":"index.mjs","sourcesContent":["import { nanoid } from \"nanoid\";\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}","import { create } from 'zustand';\r\nimport { subscribeWithSelector } from 'zustand/middleware';\r\nimport type { ChatState } from '../../types';\r\n\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 isStreaming: false,\r\n error: null,\r\n currentStreamingMessage: null,\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 updateCurrentStreamingMessage: (message) =>\r\n set({ currentStreamingMessage: message }),\r\n\r\n clearCurrentStreamingMessage: () =>\r\n set({ currentStreamingMessage: null }),\r\n\r\n setStreaming: (isStreaming) => set({ isStreaming }),\r\n\r\n setError: (error) => set({ error }),\r\n\r\n reset: () =>\r\n set({\r\n messages: [],\r\n isStreaming: false,\r\n error: null,\r\n currentStreamingMessage: null,\r\n }),\r\n }))\r\n );","import { useRef, useCallback, useEffect } from 'react';\r\nimport { generateId } from '../utils';\r\nimport type { Message, ChatConfig, UsePaprFlareConfig, StreamEvent } from '../../types';\r\nimport { createChatStore } from '../store/store';\r\n\r\n/**\r\n * Simplified PaprFlare React hook\r\n * Everything flows through messages - unified state management\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 // Core state - simplified to essentials\r\n const messages = store((state) => state.messages);\r\n const isStreaming = store((state) => state.isStreaming);\r\n const error = store((state) => state.error);\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 (content: string, options?: Partial<ChatConfig>): 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\r\n // Create abort controller\r\n abortControllerRef.current = new AbortController();\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.headers,\r\n },\r\n body: JSON.stringify({\r\n messages: [...messages, userMessage],\r\n stream: true,\r\n ...options,\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(), config);\r\n } catch (error: any) {\r\n if (error.name === 'AbortError') return;\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, store]\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 // Find last user message\r\n const lastUserMessage = [...messages]\r\n .reverse()\r\n .find((msg) => msg.role === 'user');\r\n\r\n if (!lastUserMessage) return;\r\n\r\n // Remove last assistant message if exists\r\n const filteredMessages = messages.filter(\r\n (msg, idx) =>\r\n !(msg.role === 'assistant' && idx === messages.length - 1)\r\n );\r\n\r\n // Update messages and resend\r\n store.getState().reset();\r\n filteredMessages.forEach((msg) => store.getState().addMessage(msg));\r\n\r\n await sendMessage(lastUserMessage.content);\r\n }, [messages, sendMessage, store]);\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 message\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 // 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 - simplified\r\n messages,\r\n isStreaming,\r\n error,\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\r\n // Store (for advanced use)\r\n store,\r\n };\r\n}\r\n\r\n/**\r\n * Process SSE stream - builds complete messages with all data unified\r\n */\r\nasync function processStream(\r\n body: ReadableStream<Uint8Array>,\r\n state: any,\r\n config: UsePaprFlareConfig\r\n): Promise<void> {\r\n const reader = body.getReader();\r\n const decoder = new TextDecoder();\r\n\r\n let buffer = '';\r\n\r\n // Build assistant message progressively\r\n let currentMessage: Message = {\r\n id: generateId('msg'),\r\n role: 'assistant',\r\n content: '',\r\n timestamp: Date.now(),\r\n };\r\n\r\n // Track current artifact being built\r\n let currentArtifactIndex = -1;\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 // Append text to message content\r\n currentMessage.content += event.delta;\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'tool-call-start':\r\n // Add tool call to message\r\n if (!currentMessage.toolCalls) {\r\n currentMessage.toolCalls = [];\r\n }\r\n currentMessage.toolCalls.push(event.toolCall);\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n\r\n // Call callback if provided\r\n if (config.onToolCall) {\r\n config.onToolCall(event.toolCall);\r\n }\r\n break;\r\n\r\n case 'tool-call-end':\r\n // Tool call complete - already in message\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'tool-result':\r\n // Add tool result to message\r\n if (!currentMessage.toolResults) {\r\n currentMessage.toolResults = [];\r\n }\r\n currentMessage.toolResults.push(event.result);\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'artifact-start':\r\n // Initialize artifact in message metadata\r\n if (!currentMessage.metadata) {\r\n currentMessage.metadata = {};\r\n }\r\n if (!currentMessage.metadata.artifacts) {\r\n currentMessage.metadata.artifacts = [];\r\n }\r\n\r\n // Add new artifact\r\n (currentMessage.metadata.artifacts as any[]).push({\r\n ...event.artifact,\r\n content: '',\r\n });\r\n\r\n currentArtifactIndex = (currentMessage.metadata.artifacts as any[]).length - 1;\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'artifact-delta':\r\n // Update current artifact content\r\n if (\r\n currentMessage.metadata?.artifacts &&\r\n currentArtifactIndex >= 0\r\n ) {\r\n const artifacts = currentMessage.metadata.artifacts as any[];\r\n artifacts[currentArtifactIndex].content += event.delta;\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n }\r\n break;\r\n\r\n case 'artifact-end':\r\n // Finalize artifact\r\n if (\r\n currentMessage.metadata?.artifacts &&\r\n currentArtifactIndex >= 0\r\n ) {\r\n const artifacts = currentMessage.metadata.artifacts as any[];\r\n artifacts[currentArtifactIndex] = {\r\n ...artifacts[currentArtifactIndex],\r\n ...event.artifact,\r\n };\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n\r\n // Call callback if provided\r\n if (config.onArtifact) {\r\n config.onArtifact(event.artifact);\r\n }\r\n }\r\n currentArtifactIndex = -1;\r\n break;\r\n\r\n case 'metadata':\r\n // Merge custom metadata\r\n if (!currentMessage.metadata) {\r\n currentMessage.metadata = {};\r\n }\r\n currentMessage.metadata = {\r\n ...currentMessage.metadata,\r\n ...event.metadata,\r\n };\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'usage':\r\n // Add usage to metadata\r\n if (!currentMessage.metadata) {\r\n currentMessage.metadata = {};\r\n }\r\n currentMessage.metadata.usage = event.usage;\r\n state.updateCurrentStreamingMessage(currentMessage);\r\n break;\r\n\r\n case 'error':\r\n state.setError(event.error);\r\n if (config.onError) {\r\n config.onError(new Error(event.error));\r\n }\r\n break;\r\n\r\n case 'done':\r\n // Finalize and add complete message\r\n const finalMessage: Message = {\r\n ...currentMessage,\r\n ...event.finalMessage,\r\n };\r\n\r\n state.addMessage(finalMessage);\r\n state.clearCurrentStreamingMessage();\r\n\r\n if (config.onComplete) {\r\n config.onComplete(finalMessage);\r\n }\r\n break;\r\n }\r\n } catch (error) {\r\n console.error('Failed to parse SSE event:', error);\r\n }\r\n }\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create configured hook\r\n */\r\nexport function createUsePaprFlare(config: UsePaprFlareConfig) {\r\n return () => usePaprFlare(config);\r\n}"]}
1
+ {"version":3,"sources":["../../src/react/utils/index.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","usePaprFlare","config","store","useRef","messages","abortControllerRef","streamingMessageIdRef","sendMessage","useCallback","content","options","userMessage","response","processStream","errorMessage","regenerate","lastUserMessageIndex","idx","newMessages","stop","clear","append","setMessages","useEffect","body","getState","reader","decoder","buffer","messageId","done","value","lines","line","data","event","assistantMessage","currentMsg","m","finalMsg","msgWithToolCall","msgForArtifact","existingArtifacts","msgWithArtifact","artifacts","lastIndex","msgWithArtifactEnd","artifactsEnd","createUsePaprFlare"],"mappings":"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","file":"index.mjs","sourcesContent":["import { nanoid } from \"nanoid\";\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}","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 isStreaming: false,\r\n error: null,\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 setStreaming: (isStreaming) => set({ isStreaming }),\r\n\r\n setError: (error) => set({ error }),\r\n\r\n reset: () =>\r\n set({\r\n messages: [],\r\n isStreaming: false,\r\n error: null,\r\n }),\r\n }))\r\n );","import { useRef, useCallback, useEffect } from 'react';\r\nimport { generateId } from '../utils';\r\nimport type { Message, ChatConfig, UsePaprFlareConfig } from '../../types';\r\nimport { createChatStore } from '../store/store';\r\n\r\n/**\r\n * Simplified PaprFlare React hook\r\n * Everything flows through messages - unified state management\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 // Core state - simplified to essentials\r\n const messages = store((state) => state.messages);\r\n const isStreaming = store((state) => state.isStreaming);\r\n const error = store((state) => state.error);\r\n\r\n // Abort controller ref\r\n const abortControllerRef = useRef<AbortController | null>(null);\r\n\r\n // Track current streaming message ID\r\n const streamingMessageIdRef = useRef<string | 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 (content: string, options?: Partial<ChatConfig>): 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\r\n // Create abort controller\r\n abortControllerRef.current = new AbortController();\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.headers,\r\n },\r\n body: JSON.stringify({\r\n messages: [...messages, userMessage],\r\n stream: true,\r\n ...options,\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 if (!response.body) {\r\n throw new Error('Response body is null');\r\n }\r\n\r\n // Process stream\r\n await processStream(\r\n response.body,\r\n store.getState,\r\n config\r\n );\r\n } catch (error: any) {\r\n if (error.name === 'AbortError') {\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 streamingMessageIdRef.current = null;\r\n abortControllerRef.current = null;\r\n }\r\n },\r\n [isStreaming, messages, config, store]\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 // Find last user message\r\n const lastUserMessageIndex = messages\r\n .map((msg, idx) => ({ msg, idx }))\r\n .reverse()\r\n .find(({ msg }) => msg.role === 'user');\r\n\r\n if (!lastUserMessageIndex) return;\r\n\r\n // Remove all messages after the last user message\r\n const newMessages = messages.slice(0, lastUserMessageIndex.idx + 1);\r\n\r\n store.getState().reset();\r\n newMessages.forEach((msg) => store.getState().addMessage(msg));\r\n\r\n await sendMessage(lastUserMessageIndex.msg.content);\r\n }, [messages, sendMessage, store]);\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 message\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 // 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 - simplified\r\n messages,\r\n isStreaming,\r\n error,\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\r\n // Store (for advanced use)\r\n store,\r\n };\r\n}\r\n\r\n/**\r\n * Process SSE stream - updates message in place\r\n * Handles your server's event format: message-start, text-delta, text-complete, message-complete\r\n */\r\nasync function processStream(\r\n body: ReadableStream<Uint8Array>,\r\n getState: () => any,\r\n config: UsePaprFlareConfig\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 messageId: string | null = null;\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).trim();\r\n if (data === '[DONE]') continue;\r\n\r\n try {\r\n const event = JSON.parse(data);\r\n console.log('Received event:', event); // Debug log\r\n\r\n const state = getState();\r\n\r\n switch (event.type) {\r\n case 'message-start':\r\n // Create empty assistant message\r\n const assistantMessage: Message = {\r\n id: event.messageId || generateId('msg'),\r\n role: 'assistant',\r\n content: '',\r\n timestamp: Date.now(),\r\n };\r\n\r\n messageId = assistantMessage.id;\r\n state.addMessage(assistantMessage);\r\n console.log('Created message:', messageId); // Debug log\r\n break;\r\n\r\n case 'text-delta':\r\n // Append text to message content\r\n if (messageId) {\r\n const currentMsg = state.messages.find((m: Message) => m.id === messageId);\r\n if (currentMsg) {\r\n state.updateMessage(messageId, {\r\n content: currentMsg.content + event.delta,\r\n });\r\n console.log('Updated content:', currentMsg.content + event.delta); // Debug log\r\n }\r\n }\r\n break;\r\n\r\n case 'text-complete':\r\n // Optional: can be used to verify final text\r\n console.log('Text complete:', event.fullText);\r\n break;\r\n\r\n case 'message-complete':\r\n // Finalize message\r\n if (messageId && event.message) {\r\n state.updateMessage(messageId, {\r\n ...event.message,\r\n isComplete: true,\r\n });\r\n\r\n if (config.onComplete) {\r\n const finalMsg = state.messages.find((m: Message) => m.id === messageId);\r\n if (finalMsg) {\r\n config.onComplete(finalMsg);\r\n }\r\n }\r\n }\r\n break;\r\n\r\n case 'tool-call-start':\r\n if (messageId) {\r\n const currentMsg = state.messages.find((m: Message) => m.id === messageId);\r\n state.updateMessage(messageId, {\r\n toolCalls: [...(currentMsg?.toolCalls || []), event.toolCall],\r\n });\r\n\r\n if (config.onToolCall) {\r\n config.onToolCall(event.toolCall);\r\n }\r\n }\r\n break;\r\n\r\n case 'tool-result':\r\n if (messageId) {\r\n const msgWithToolCall = state.messages.find((m: Message) => m.id === messageId);\r\n state.updateMessage(messageId, {\r\n toolResults: [...(msgWithToolCall?.toolResults || []), event.result],\r\n });\r\n }\r\n break;\r\n\r\n case 'artifact-start':\r\n if (messageId) {\r\n const msgForArtifact = state.messages.find((m: Message) => m.id === messageId);\r\n const existingArtifacts = msgForArtifact?.metadata?.artifacts || [];\r\n\r\n state.updateMessage(messageId, {\r\n metadata: {\r\n ...(msgForArtifact?.metadata || {}),\r\n artifacts: [\r\n ...existingArtifacts,\r\n { ...event.artifact, content: '' },\r\n ],\r\n },\r\n });\r\n }\r\n break;\r\n\r\n case 'artifact-delta':\r\n if (messageId) {\r\n const msgWithArtifact = state.messages.find((m: Message) => m.id === messageId);\r\n const artifacts = [...(msgWithArtifact?.metadata?.artifacts || [])];\r\n const lastIndex = artifacts.length - 1;\r\n\r\n if (lastIndex >= 0) {\r\n artifacts[lastIndex] = {\r\n ...artifacts[lastIndex],\r\n content: artifacts[lastIndex].content + event.delta,\r\n };\r\n\r\n state.updateMessage(messageId, {\r\n metadata: {\r\n ...(msgWithArtifact?.metadata || {}),\r\n artifacts,\r\n },\r\n });\r\n }\r\n }\r\n break;\r\n\r\n case 'artifact-end':\r\n if (messageId) {\r\n const msgWithArtifactEnd = state.messages.find((m: Message) => m.id === messageId);\r\n const artifactsEnd = [...(msgWithArtifactEnd?.metadata?.artifacts || [])];\r\n const lastIndex = artifactsEnd.length - 1;\r\n\r\n if (lastIndex >= 0) {\r\n artifactsEnd[lastIndex] = {\r\n ...artifactsEnd[lastIndex],\r\n ...event.artifact,\r\n };\r\n\r\n state.updateMessage(messageId, {\r\n metadata: {\r\n ...(msgWithArtifactEnd?.metadata || {}),\r\n artifacts: artifactsEnd,\r\n },\r\n });\r\n\r\n if (config.onArtifact) {\r\n config.onArtifact(event.artifact);\r\n }\r\n }\r\n }\r\n break;\r\n\r\n case 'error':\r\n state.setError(event.error);\r\n if (config.onError) {\r\n config.onError(new Error(event.error));\r\n }\r\n break;\r\n\r\n default:\r\n console.log('Unknown event type:', event.type);\r\n }\r\n } catch (error) {\r\n console.error('Failed to parse SSE event:', error, 'Line:', line);\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n console.error('Stream processing error:', error);\r\n throw error;\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create configured hook\r\n */\r\nexport function createUsePaprFlare(config: UsePaprFlareConfig) {\r\n return () => usePaprFlare(config);\r\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paprflare-sdk",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "description": "Production-ready AI streaming SDK",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",