@holaboss/client 0.2.0-beta.2 → 0.2.0-beta.20
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.cjs +5 -5
- package/dist/index.d.cts +525 -20
- package/dist/index.d.ts +525 -20
- package/dist/index.js +5 -5
- package/package.json +6 -4
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
var
|
|
3
|
-
`))
|
|
4
|
-
`)}:null},
|
|
2
|
+
var Y=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},_=e=>{let t=Y(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},O=e=>{let t=Y(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},U=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="tool_execution_start"&&t.toolCallId?{phase:"start",id:t.toolCallId,name:t.toolName}:t.type==="tool_execution_end"&&t.toolCallId?{phase:"end",id:t.toolCallId,isError:t.isError}:null};var Ee=/^ /,w=e=>{if(e&&typeof e=="object"){let t=e,o=typeof t.error=="string"?t.error:"request_failed";return typeof t.retryable=="boolean"?{error:o,retryable:t.retryable}:{error:o}}return{error:"request_failed"}},$e=e=>{let t="message",o=[];for(let r of e.split(`
|
|
3
|
+
`))r.startsWith(":")||(r.startsWith("event:")?t=r.slice(6).trim():r.startsWith("data:")&&o.push(r.slice(5).replace(Ee,"")));return o.length>0?{event:t,data:o.join(`
|
|
4
|
+
`)}:null},_e=(e,t,o)=>{let r;try{r=JSON.parse(e.data)}catch{return}if(e.event==="session"){let l=r.sessionId;l&&(o(l),t.onSession?.(l));return}if(e.event==="turn_event"){t.onEvent?.(r);let l=_(r);l&&t.onText?.(l);let i=O(r);i&&t.onThinking?.(i);let n=U(r);n&&t.onTool?.(n);return}if(e.event==="chat_completed"){let l=r;o(l.sessionId),t.onComplete?.(l);return}e.event==="chat_error"&&t.onError?.(w(r))},v=async(e,t)=>{let o=await fetch(e,{headers:t});if(!o.ok)throw new Error(`hola: request failed (${o.status})`);return await o.json()},Z=async e=>{let t=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body});if(!t.ok)throw new Error(`hola: message failed (${t.status})`);return await t.json()},ee=async(e,t,o,r)=>{let l=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:r});if(!(l.ok&&l.body)){t.onError?.({error:`stream_failed_${l.status}`});return}let i=l.body.getReader(),n=new TextDecoder,s="",a=()=>{let d=s.indexOf(`
|
|
5
5
|
|
|
6
|
-
`);for(;
|
|
6
|
+
`);for(;d!==-1;){let c=s.slice(0,d);s=s.slice(d+2);let g=$e(c);g&&_e(g,t,o),d=s.indexOf(`
|
|
7
7
|
|
|
8
|
-
`)}},n=async()=>{let c=await d.read();if(!c.done)return o+=r.decode(c.value,{stream:!0}),l(),n()};await n()};var B=/\/+$/,C="/api/v1/end-user",G=e=>{let t=e.baseUrl.replace(B,""),a=()=>typeof e.token=="function"?e.token():e.token,s=async()=>({"content-type":"application/json",authorization:`Bearer ${await a()}`}),i=async d=>{let r=await fetch(`${t}${C}/chat`,{method:"POST",headers:await s(),body:JSON.stringify({message:d})});if(!r.ok)throw new Error(`hola: message failed (${r.status})`);return{reply:(await r.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>b(`${t}${C}/chat/info`,await s()),sendMessage:i,streamMessage:async(d,r)=>{try{let o=await i(d);r.onText?.(o.reply),r.onComplete?.(o)}catch(o){r.onError?.(x(o))}},subscribe:(d,r)=>{let o=r?.since??"0",l=!1,n,c=r?.intervalMs??3e3,f=async()=>{try{let p=await b(`${t}${C}/chat/thread?since=${encodeURIComponent(o)}`,await s());for(let y of p.messages)d.onMessage(y);o=p.cursor}catch(p){d.onError?.(x(p))}l||(n=setTimeout(f,c))},u=()=>{l=!0,n&&clearTimeout(n)};return r?.signal?.addEventListener("abort",u),n=setTimeout(f,0),u},requestHuman:async()=>{await fetch(`${t}${C}/chat/request-human`,{method:"POST",headers:await s(),body:"{}"})}}};import{useEffect as K,useState as V}from"react";var k=(e,t)=>{let[a,s]=V("");return K(()=>{if(!e){s("");return}let i=Uint8Array.from(atob(e),r=>r.charCodeAt(0)),d=URL.createObjectURL(new Blob([i],{type:t}));return s(d),()=>URL.revokeObjectURL(d)},[e,t]),a};import{useEffect as re,useRef as oe}from"react";import{createContext as Y,useContext as Q}from"react";import{jsx as Z}from"react/jsx-runtime";var L=Y(null),X=({client:e,children:t})=>Z(L.Provider,{value:e,children:t}),M=()=>{let e=Q(L);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};import{useCallback as W,useEffect as ee,useRef as te,useState as P}from"react";var A=e=>{let[t,a]=P([]),[s,i]=P(""),[d,r]=P(!1),[o,l]=P(null),n=te(0),c=W(()=>{let u=n.current;return n.current+=1,u},[]);ee(()=>{let u=!0;return e.getInfo().then(p=>{u&&p.greeting&&a([{id:c(),role:"assistant",text:p.greeting}])}).catch(()=>{}),()=>{u=!1}},[e,c]);let f=W(()=>{let u=s.trim();if(!u||d)return;i(""),l(null),r(!0);let p=c(),y=c();a(g=>[...g,{id:p,role:"user",text:u},{id:y,role:"assistant",text:"",streaming:!0}]);let m=g=>{a(h=>h.map(R=>R.id===y?g(R):R))};e.streamMessage(u,{onText:g=>m(h=>({...h,text:h.text+g})),onComplete:g=>{m(h=>({...h,text:g.reply||h.text,artifacts:g.artifacts,streaming:!1})),r(!1)},onError:g=>{m(h=>({...h,streaming:!1})),l(g.error),r(!1)}}).catch(g=>{m(h=>({...h,streaming:!1})),l(g instanceof Error?g.message:"stream_failed"),r(!1)})},[s,d,e,c]);return{messages:t,input:s,setInput:i,send:f,sending:d,error:o}};import{jsx as H,jsxs as U}from"react/jsx-runtime";var w={root:{display:"flex",flexDirection:"column",height:"100%",fontFamily:"system-ui, -apple-system, sans-serif",fontSize:14,color:"#111827"},log:{flex:1,overflowY:"auto",padding:12,display:"flex",flexDirection:"column",gap:8},user:{alignSelf:"flex-end",background:"#111827",color:"#ffffff",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},assistant:{alignSelf:"flex-start",background:"#f1f1f4",color:"#111827",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},artifacts:{display:"flex",flexDirection:"column",gap:6,marginTop:6},image:{maxHeight:220,borderRadius:8,border:"1px solid #e5e7eb"},link:{color:"#2563eb",textDecoration:"underline",wordBreak:"break-all"},error:{color:"#b91c1c",padding:"4px 12px",fontSize:13},form:{display:"flex",gap:8,borderTop:"1px solid #e5e7eb",padding:8},input:{flex:1,border:"1px solid #d1d5db",borderRadius:8,padding:"8px 10px",fontSize:14,outline:"none"},button:{border:"none",background:"#111827",color:"#ffffff",borderRadius:8,padding:"8px 14px",fontSize:14,cursor:"pointer"}},se=({artifact:e})=>{let t=k(e.dataBase64??"",e.mimeType),a=e.url??t;return a?e.mimeType.startsWith("image/")?H("a",{href:a,rel:"noopener noreferrer",target:"_blank",children:H("img",{alt:e.filename,src:a,style:w.image})}):H("a",{download:e.filename,href:a,style:w.link,children:e.filename}):null},ne=()=>{let e=M(),{messages:t,input:a,setInput:s,send:i,sending:d,error:r}=A(e),o=oe(null);re(()=>{let n=o.current;n&&(n.scrollTop=n.scrollHeight)},[t]);let l=n=>{n.preventDefault(),i()};return U("div",{style:w.root,children:[H("div",{ref:o,style:w.log,children:t.map(n=>U("div",{style:n.role==="user"?w.user:w.assistant,children:[n.text||(n.streaming?"\u2026":""),n.artifacts&&n.artifacts.length>0?H("div",{style:w.artifacts,children:n.artifacts.map(c=>H(se,{artifact:c},c.filename))}):null]},n.id))}),r?H("div",{style:w.error,children:r}):null,U("form",{onSubmit:l,style:w.form,children:[H("input",{"aria-label":"Message",onChange:n=>s(n.target.value),placeholder:"Type a message\u2026",style:w.input,value:a}),H("button",{disabled:d||a.trim().length===0,style:w.button,type:"submit",children:"Send"})]})]})};var ae=/\/+$/,D=e=>{let t=e.sessionId,a=e.baseUrl.replace(ae,""),s=r=>`${a}/endpoint/${encodeURIComponent(e.token)}${r}`,i={"content-type":"application/json"},d=(r,o)=>({url:s(r),headers:i,body:JSON.stringify({message:o,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>b(s("/config"),{}),sendMessage:async r=>{let o=await _(d("/message",r));return t=o.sessionId,o},streamMessage:(r,o,l)=>F(d("/message/stream",r),o,n=>{t=n},l),subscribe:(r,o)=>{let l=o?.since??"0",n=!1,c,f=o?.intervalMs??3e3,u=async()=>{let y=t;if(y)try{let m=await b(s(`/messages?session=${encodeURIComponent(y)}&since=${encodeURIComponent(l)}`),{});for(let g of m.messages)r.onMessage(g);l=m.cursor}catch(m){r.onError?.(x(m))}n||(c=setTimeout(u,f))},p=()=>{n=!0,c&&clearTimeout(c)};return o?.signal?.addEventListener("abort",p),c=setTimeout(u,0),p},requestHuman:async()=>{t&&await fetch(s("/request-human"),{method:"POST",headers:i,body:JSON.stringify({sessionId:t})})}}};var ie=e=>"transport"in e?e.transport:D(e);var le=/\/+$/,T="/api/v1/end-user",v=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function ce(e){let t="";for(let s=0;s<e.length;s+=32768)t+=String.fromCharCode(...e.subarray(s,s+32768));return btoa(t)}var de=e=>{let t=e.baseUrl.replace(le,""),a=()=>typeof e.token=="function"?e.token():e.token,s=async()=>({"content-type":"application/json",authorization:`Bearer ${await a()}`}),i=async(r,o)=>{try{let l=await fetch(`${t}${T}${r}`,{method:o.method,headers:await s(),...o.body===void 0?{}:{body:JSON.stringify(o.body)}});if(l.status===409){let n=await l.json().catch(()=>({}));throw new v(n.message??"Someone else saved this first.")}if(!l.ok){let n=await l.text().catch(()=>""),c=`${o.method} ${r} \u2192 ${String(l.status)}`;try{let f=JSON.parse(n);f.message&&(c=f.message)}catch{c=n?`${c}: ${n}`:c}throw x(new Error(c))}return await l.json()}catch(l){throw x(l)}},d=r=>`/tables/${encodeURIComponent(r)}`;return{listTables:async()=>(await b(`${t}${T}/tables`,await s())).tables,listRows:async(r,o)=>await b(`${t}${T}${d(r)}/rows?limit=${String(o??100)}`,await s()),insertRow:async(r,o)=>{let{rowIds:l}=await i(`${d(r)}/rows`,{method:"POST",body:{rows:[o]}}),n=l[0];if(!n)throw x(new Error("The row was not created."));return n},patchRow:async(r,o,l)=>(await i(`${d(r)}/rows/${encodeURIComponent(o)}`,{method:"PATCH",body:l})).updated,deleteRow:async(r,o)=>(await i(`/${encodeURIComponent(r)}/${encodeURIComponent(o)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await b(`${t}${T}/tables/files/rows?limit=200`,await s())).rows.map(o=>({id:o.rowId,filename:String(o.data.filename??""),source:String(o.data.source??"client"),campaign:String(o.data.campaign??""),size:typeof o.data.size=="number"?o.data.size:0,createdAt:o.createdAt})),uploadFile:async(r,o)=>{let l=new Uint8Array(await r.arrayBuffer());return await i("/files",{method:"POST",body:{filename:r.name,mime:r.type||"application/octet-stream",data:ce(l),...o===void 0?{}:{message:o}}})},fileLink:async r=>await b(`${t}${T}/files/${encodeURIComponent(r)}/url`,await s()),deleteFile:async r=>(await i(`/files/${encodeURIComponent(r)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await b(`${t}${T}/documents`,await s())).documents,readDocument:async r=>(await b(`${t}${T}/documents/${encodeURIComponent(r)}`,await s())).document,saveDocument:async(r,o)=>await i(`/documents/${encodeURIComponent(r)}`,{method:"PATCH",body:o})}};import{useCallback as pe,useEffect as N,useRef as ue,useState as I}from"react";function j(e,t){return e.some(s=>s.id===t.id)?e:[...t.author==="client"?e.filter(s=>!(s.pending&&s.author==="client"&&s.text===t.text)):e,t]}var me=(e,t)=>{let[a,s]=I([]),[i,d]=I(""),[r,o]=I(!1),[l,n]=I(null),c=ue(0),f=t?.pollMs??2e3;N(()=>{let p=!0;return e.getInfo().then(y=>{p&&y.greeting&&s(m=>m.length===0?[{id:"greeting",cursor:"",author:"agent",text:y.greeting}]:m)}).catch(()=>{}),()=>{p=!1}},[e]),N(()=>e.subscribe?.({onMessage:p=>s(y=>j(y,p)),onError:p=>n(p.error)},{intervalMs:f}),[e,f]);let u=pe(()=>{let p=i.trim();if(!p||r)return;d(""),n(null),o(!0),c.current+=1;let y={id:`pending-${c.current}`,cursor:"",author:"client",text:p,pending:!0};s(m=>[...m,y]),e.sendMessage(p).then(()=>o(!1)).catch(m=>{n(m instanceof Error?m.message:"send_failed"),o(!1)})},[i,r,e]);return{messages:a,input:i,setInput:d,send:u,sending:r,error:l}};export{ne as Chat,X as HolaProvider,v as PortalConflict,G as createApiTransport,ie as createHolaClient,de as createPortalData,D as createWidgetTransport,j as mergeMessage,E as textDeltaOf,S as thinkingDeltaOf,$ as toolEventOf,k as useArtifactUrl,A as useChat,M as useHolaClient,me as useThread};
|
|
8
|
+
`)}},u=async()=>{let d=await i.read();if(!d.done)return s+=n.decode(d.value,{stream:!0}),a(),u()};await u()};var Oe=/\/+$/,L="/api/v1/end-user",Ue=e=>{let t=e.baseUrl.replace(Oe,""),o=()=>typeof e.token=="function"?e.token():e.token,r=n=>e.project?`${n}project=${encodeURIComponent(e.project)}`:"",l=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),i=async n=>{let s=await fetch(`${t}${L}/chat${r("?")}`,{method:"POST",headers:await l(),body:JSON.stringify({message:n})});if(!s.ok)throw new Error(`hola: message failed (${s.status})`);return{reply:(await s.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>v(`${t}${L}/chat/info${r("?")}`,await l()),sendMessage:i,streamMessage:async(n,s)=>{try{let a=await i(n);s.onText?.(a.reply),s.onComplete?.(a)}catch(a){s.onError?.(w(a))}},subscribe:(n,s)=>{let a=s?.since??"0",u=!1,d,c=s?.intervalMs??3e3,g=typeof document<"u",p=()=>g&&document.visibilityState==="hidden",y=!1,x=()=>{if(!u){if(p()){y=!0;return}d=setTimeout(f,c)}},f=async()=>{try{let h=await v(`${t}${L}/chat/thread?since=${encodeURIComponent(a)}${r("&")}`,await l());for(let k of h.messages)n.onMessage(k);a=h.cursor,n.onHealthy?.()}catch(h){n.onError?.(w(h))}x()},R=()=>{u||!y||p()||(y=!1,d&&clearTimeout(d),d=setTimeout(f,0))};g&&document.addEventListener("visibilitychange",R);let m=()=>{u=!0,d&&clearTimeout(d),g&&document.removeEventListener("visibilitychange",R)};return s?.signal?.addEventListener("abort",m),d=setTimeout(f,0),m}}};import{useEffect as Le,useState as Fe}from"react";var F=(e,t)=>{let[o,r]=Fe("");return Le(()=>{if(!e){r("");return}let l=Uint8Array.from(atob(e),n=>n.charCodeAt(0)),i=URL.createObjectURL(new Blob([l],{type:t}));return r(i),()=>URL.revokeObjectURL(i)},[e,t]),o};import{useEffect as Be,useRef as ze}from"react";import{createContext as Ne,useContext as Ve}from"react";import{jsx as Ge}from"react/jsx-runtime";var te=Ne(null),je=({client:e,children:t})=>Ge(te.Provider,{value:e,children:t}),N=()=>{let e=Ve(te);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};import{useCallback as ne,useEffect as re,useRef as oe,useState as M}from"react";var V=e=>{let[t,o]=M([]),[r,l]=M(""),[i,n]=M(!1),[s,a]=M(null),u=oe(0),d=oe(null);re(()=>()=>d.current?.abort(),[]);let c=ne(()=>{let p=u.current;return u.current+=1,p},[]);re(()=>{let p=!0;return e.getInfo().then(y=>{p&&y.greeting&&o([{id:c(),role:"assistant",text:y.greeting}])}).catch(()=>{}),()=>{p=!1}},[e,c]);let g=ne(()=>{let p=r.trim();if(!p||i)return;l(""),a(null),n(!0);let y=c(),x=c();o(m=>[...m,{id:y,role:"user",text:p},{id:x,role:"assistant",text:"",streaming:!0}]);let f=m=>{o(h=>h.map(k=>k.id===x?m(k):k))},R=new AbortController;d.current=R,e.streamMessage(p,{onText:m=>f(h=>({...h,text:h.text+m})),onComplete:m=>{f(h=>({...h,text:m.reply||h.text,artifacts:m.artifacts,streaming:!1})),n(!1)},onError:m=>{f(h=>({...h,streaming:!1})),a(m.error),n(!1)}},R.signal).catch(m=>{f(h=>({...h,streaming:!1})),a(m instanceof Error?m.message:"stream_failed"),n(!1)}).finally(()=>{n(!1),f(m=>m.streaming?{...m,streaming:!1}:m)})},[r,i,e,c]);return{messages:t,input:r,setInput:l,send:g,sending:i,error:s}};import{jsx as P,jsxs as j}from"react/jsx-runtime";var S={root:{display:"flex",flexDirection:"column",height:"100%",fontFamily:"system-ui, -apple-system, sans-serif",fontSize:14,color:"#111827"},log:{flex:1,overflowY:"auto",padding:12,display:"flex",flexDirection:"column",gap:8},user:{alignSelf:"flex-end",background:"#111827",color:"#ffffff",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},assistant:{alignSelf:"flex-start",background:"#f1f1f4",color:"#111827",borderRadius:12,padding:"8px 12px",maxWidth:"80%",whiteSpace:"pre-wrap"},artifacts:{display:"flex",flexDirection:"column",gap:6,marginTop:6},image:{maxHeight:220,borderRadius:8,border:"1px solid #e5e7eb"},link:{color:"#2563eb",textDecoration:"underline",wordBreak:"break-all"},error:{color:"#b91c1c",padding:"4px 12px",fontSize:13},form:{display:"flex",gap:8,borderTop:"1px solid #e5e7eb",padding:8},input:{flex:1,border:"1px solid #d1d5db",borderRadius:8,padding:"8px 10px",fontSize:14,outline:"none"},button:{border:"none",background:"#111827",color:"#ffffff",borderRadius:8,padding:"8px 14px",fontSize:14,cursor:"pointer"}},Je=({artifact:e})=>{let t=F(e.dataBase64??"",e.mimeType),o=e.url??t;return o?e.mimeType.startsWith("image/")?P("a",{href:o,rel:"noopener noreferrer",target:"_blank",children:P("img",{alt:e.filename,src:o,style:S.image})}):P("a",{download:e.filename,href:o,style:S.link,children:e.filename}):null},Ke=()=>{let e=N(),{messages:t,input:o,setInput:r,send:l,sending:i,error:n}=V(e),s=ze(null);Be(()=>{let u=s.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let a=u=>{u.preventDefault(),l()};return j("div",{style:S.root,children:[P("div",{ref:s,style:S.log,children:t.map(u=>j("div",{style:u.role==="user"?S.user:S.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?P("div",{style:S.artifacts,children:u.artifacts.map(d=>P(Je,{artifact:d},d.filename))}):null]},u.id))}),n?P("div",{style:S.error,children:n}):null,j("form",{onSubmit:a,style:S.form,children:[P("input",{"aria-label":"Message",onChange:u=>r(u.target.value),placeholder:"Type a message\u2026",style:S.input,value:o}),P("button",{disabled:i||o.trim().length===0,style:S.button,type:"submit",children:"Send"})]})]})};var Xe=/\/+$/,G=e=>{let t=e.sessionId,o=e.baseUrl.replace(Xe,""),r=n=>`${o}/endpoint/${encodeURIComponent(e.token)}${n}`,l={"content-type":"application/json"},i=(n,s)=>({url:r(n),headers:l,body:JSON.stringify({message:s,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>v(r("/config"),{}),sendMessage:async n=>{let s=await Z(i("/message",n));return t=s.sessionId,s},streamMessage:(n,s,a)=>ee(i("/message/stream",n),s,u=>{t=u},a),subscribe:(n,s)=>{let a=s?.since??"0",u=!1,d,c=s?.intervalMs??3e3,g=async()=>{let y=t;if(y)try{let x=await v(r(`/messages?session=${encodeURIComponent(y)}&since=${encodeURIComponent(a)}`),{});for(let f of x.messages)n.onMessage(f);a=x.cursor,n.onHealthy?.()}catch(x){n.onError?.(w(x))}u||(d=setTimeout(g,c))},p=()=>{u=!0,d&&clearTimeout(d)};return s?.signal?.addEventListener("abort",p),d=setTimeout(g,0),p}}};var qe=e=>"transport"in e?e.transport:G(e);var Qe=/^https?:\/\//i,Ye=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Ze=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function et(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(Qe.test(e))return"url";if(Ye.test(e))return"date"}return"text"}function se(e){let t=[],o=new Map;for(let r of e)for(let[l,i]of Object.entries(r.data??{})){if(i==null)continue;let n=o.get(l);n||(n=new Map,o.set(l,n),t.push(l));let s=et(i);n.set(s,(n.get(s)??0)+1)}return t.map(r=>{let l=o.get(r)??new Map,i="text",n=-1;for(let[s,a]of l)a>n&&(n=a,i=s);return{key:r,label:Ze(r),type:i}})}var tt=e=>typeof e=="number"?e:Number(e)||0,ie=e=>/rate|position|rank|score|percent|avg/i.test(e),nt=/posted|published|sent|completed|shipped|launched|_at/i,rt=new Set(["service","order","end_user_id"]);function ae(e,t){let o=e.filter(a=>!rt.has(a.key)),r=o.filter(a=>a.type==="number").slice(0,3),l=o.find(a=>a.key==="status")??o.find(a=>a.type==="select"),i=o.find(a=>a.type==="date"&&nt.test(a.key))??o.find(a=>a.type==="date"),n=o.filter(a=>a.type==="number"&&!ie(a.key)).map(a=>({field:a,total:t.reduce((u,d)=>u+tt(d.data[a.key]),0)})).sort((a,u)=>u.total-a.total).find(a=>a.total>0)?.field??null,s=[{type:"stat",label:"Items",agg:"count"}];for(let a of r){let u=ie(a.key);s.push({type:"stat",metric:a.key,agg:u?"avg":"sum",label:u?`Avg ${a.label.toLowerCase()}`:a.label})}return i&&s.push({type:"line",x:i.key,y:n?.key,agg:"sum",title:n?`${n.label} by day`:"Items by day"}),l&&s.push({type:"donut",groupBy:l.key,title:l.label}),s.push({type:"table",columns:o.map(a=>a.key)}),{version:1,widgets:s}}var le=6,ue=6,de=4,pe={stat:{w:1,h:1},chart:{w:2,h:2},block:{w:6,h:2}},ot=e=>Math.max(1,Math.min(6,Math.round(e))),st=e=>Math.max(1,Math.min(4,Math.round(e)));function W(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function ce(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function ge(e){return pe[e]}function B(e,t,o){let r=pe[e];return{w:t===void 0?r.w:ot(t),h:o===void 0?r.h:st(o)}}function z(e){let t=[],o=[],r=(n,s,a,u)=>{if(n<0||n+a>6)return!1;for(let d=0;d<u;d+=1){let c=o[s+d];if(c){for(let g=0;g<a;g+=1)if(c[n+g])return!1}}return!0},l=(n,s,a,u)=>{for(let d=0;d<u;d+=1){let c=o[s+d]??[];for(let g=0;g<a;g+=1)c[n+g]=!0;o[s+d]=c}},i=(n,s)=>{for(let a=0;;a+=1)for(let u=0;u+n<=6;u+=1)if(r(u,a,n,s))return{gx:u,gy:a}};for(let n of e){let s=B(W(n.kind),n.w,n.h),u=n.gx!==void 0&&n.gy!==void 0&&r(n.gx,n.gy,s.w,s.h)&&n.gx!==void 0&&n.gy!==void 0?{gx:n.gx,gy:n.gy}:i(s.w,s.h);l(u.gx,u.gy,s.w,s.h),t.push({widget:n,gx:u.gx,gy:u.gy,w:s.w,h:s.h})}return t}function me(e){let t=[],o=[];for(let r of e)W(r.kind)==="block"?o.push(r):t.push(r);return{tiles:z(t),blocks:o}}var fe=new Set(["service","order","end_user_id"]),J=e=>typeof e=="number"?e:Number(e)||0,ye=e=>e==null?"":String(e);function K(e,t){if(e==="count")return t.length;if(t.length===0)return 0;if(e==="last")return t[t.length-1]??0;if(e==="min")return Math.min(...t);if(e==="max")return Math.max(...t);let o=t.reduce((r,l)=>r+l,0);return e==="avg"?Math.round(o/t.length*100)/100:o}function it(e,t,o,r){let l=new Map;for(let i of e){let n=new Date(ye(i.data[t]));if(Number.isNaN(n.getTime()))continue;let s=n.toISOString().slice(0,10),a=l.get(s)??[];a.push(o?J(i.data[o]):1),l.set(s,a)}return[...l.entries()].sort((i,n)=>i[0]<n[0]?-1:1).map(([i,n])=>({label:new Date(`${i}T00:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"}),value:o?K(r,n):n.length}))}function at(e,t,o,r="sum"){let l=new Map;for(let i of e){let n=ye(i.data[t]).trim();if(!n)continue;let s=l.get(n)??[];s.push(o?J(i.data[o]):1),l.set(n,s)}return[...l.entries()].map(([i,n])=>({label:i,value:o?K(r,n):n.length})).sort((i,n)=>n.value-i.value)}function lt(e,t,o,r){switch(e.type){case"stat":{let l=e.metric?t.get(e.metric):void 0;if(e.metric&&!l)return null;if(!l)return{kind:"stat",label:e.label??"Items",value:r.length};let i=r.map(n=>J(n.data[l.key]));return{kind:"stat",label:e.label??l.label,value:K(e.agg??"sum",i)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let l=it(r,e.x,e.y,e.agg??"sum");return l.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:l}}case"donut":{if(!t.has(e.groupBy))return null;let l=at(r,e.groupBy,e.metric,e.agg??"sum");return l.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:l}}case"table":{let l=e.columns?e.columns.map(i=>t.get(i)).filter(i=>i!==void 0&&!fe.has(i.key)):o;return l.length===0?null:{kind:"table",title:e.title,columns:l,rows:r}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function be(e,t,o,r={}){let l=new Map,i=a=>({byKey:new Map(a.fields.map(u=>[u.key,u])),cols:a.fields.filter(u=>!fe.has(u.key)),rows:a.rows}),n=i({fields:t,rows:o});for(let[a,u]of Object.entries(r))l.set(a,i(u));let s=[];for(let a of e.widgets){let u=a.type==="text"?void 0:a.source,d=u?l.get(u):n;if(!d)continue;let c=lt(a,d.byKey,d.cols,d.rows);c&&s.push({...c,w:a.w,h:a.h,gx:a.gx,gy:a.gy})}return s}var ut=new Set(["sum","avg","count","min","max","last"]),he=e=>typeof e=="string"&&ut.has(e)?e:void 0,b=e=>typeof e=="string"&&e!==""?e:void 0,C=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,I=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0,T=e=>typeof e=="number"&&e>=0?Math.round(e):void 0;function dt(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",source:b(t.source),label:b(t.label),metric:b(t.metric)??b(t.column),agg:he(t.agg),w:C(t.w),h:I(t.h),gx:T(t.gx),gy:T(t.gy)};case"line":case"bar":{let o=b(t.x);return o?{type:t.type,source:b(t.source),title:b(t.title),x:o,y:b(t.y)??b(t.column),agg:he(t.agg),w:C(t.w),h:I(t.h),gx:T(t.gx),gy:T(t.gy)}:null}case"donut":{let o=b(t.groupBy)??b(t.column);return o?{type:"donut",source:b(t.source),title:b(t.title),groupBy:o,w:C(t.w),h:I(t.h),gx:T(t.gx),gy:T(t.gy)}:null}case"table":{let o=Array.isArray(t.columns)?t.columns.filter(r=>typeof r=="string"):void 0;return{type:"table",source:b(t.source),title:b(t.title),columns:o,w:C(t.w),h:I(t.h),gx:T(t.gx),gy:T(t.gy)}}case"text":{let o=b(t.body);return o?{type:"text",title:b(t.title),body:o,w:C(t.w),h:I(t.h),gx:T(t.gx),gy:T(t.gy)}:null}default:return null}}function we(e){let t=e;if(typeof e=="string"){if(e.trim()==="")return null;try{t=JSON.parse(e)}catch{return null}}if(typeof t!="object"||t===null)return null;let o=t.widgets;if(!Array.isArray(o))return null;let r=o.map(dt).filter(i=>i!==null);if(r.length===0)return null;let l=t.version;return{version:typeof l=="number"?l:1,title:b(t.title),widgets:r}}function X(e){if(typeof e=="string")return e?{kind:"file",value:e}:null;if(e&&typeof e=="object"){let t=e,o=typeof t.value=="string"?t.value:"",r=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",l=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return o?{kind:r,value:o,...l?{v:l}:{}}:null}return null}function q(e){let t=new Map;for(let o of e){let r=o.v??1,l=t.get(r)??[];l.push(o),t.set(r,l)}return[...t.entries()].sort(([o],[r])=>o-r).map(([o,r])=>({v:o,items:r}))}function xe(e){let t=e.files;if(typeof t=="string"&&t.trim()!=="")try{let r=JSON.parse(t);if(Array.isArray(r))return r.map(X).filter(l=>l!==null)}catch{}let o=String(e.file??"");return o?[{kind:"file",value:o}]:[]}function ve(e,t,o,r=""){let i=q(e).find(s=>s.v===t)?.items??[],n=i.filter(s=>s.kind==="file").map(s=>o.get(s.value)??"");return i.some(s=>s.kind==="table")&&n.push(r),n.length===0||n.some(s=>s==="")?"awaiting":n.some(s=>s==="revise")?"revise":"accepted"}function Se(e){return Number(e.published_version)||0}function Q(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function Re(e){try{let t=JSON.parse(e);if(Array.isArray(t.columns)&&Array.isArray(t.rows)&&t.columns.length){let o=t.columns.map((i,n)=>({key:typeof i.key=="string"&&i.key?i.key:typeof i.id=="string"&&i.id?i.id:`column_${n+1}`,label:typeof i.label=="string"?i.label:"",type:Q(i.type),...i.clientEditable===!0?{clientEditable:!0}:{}})),r=t.rows.map((i,n)=>({id:typeof i.id=="string"&&i.id?i.id:`row_${n}`,cells:i.cells&&typeof i.cells=="object"?i.cells:{}})),l=typeof t.name=="string"?t.name:void 0;return{columns:o,rows:r,...l?{name:l}:{}}}}catch{}return null}function Te(e){return e==null?"":String(e)}function ke(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function E(){return{cells:{},verdict:"",comment:""}}function Pe(e){if(typeof e!="string"||e.trim()==="")return E();try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t)){let o=t;return{cells:o.cells&&typeof o.cells=="object"?o.cells:o,verdict:o.verdict==="accepted"||o.verdict==="revise"?o.verdict:"",comment:typeof o.comment=="string"?o.comment:""}}}catch{}return E()}function De(e,t,o){if(e.clientEditable){let r=o.cells[t.id];if(r&&e.key in r)return r[e.key]}return t.cells[e.key]}function Ce(e,t,o,r){return{...e,cells:{...e.cells,[t]:{...e.cells[t]??{},[o]:r}}}}function Ie(e,t,o){return{...e,verdict:t,comment:o}}function He(e){let t=new Date(`${e}T00:00:00`);return Number.isNaN(t.getTime())?e:t.toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})}var pt=/\/+$/,D="/api/v1/end-user",H=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function ct(e){let t="";for(let r=0;r<e.length;r+=32768)t+=String.fromCharCode(...e.subarray(r,r+32768));return btoa(t)}var gt=e=>{let t=e.baseUrl.replace(pt,""),o=()=>typeof e.token=="function"?e.token():e.token,r=async()=>({"content-type":"application/json",authorization:`Bearer ${await o()}`}),l=async(n,s)=>{try{let a=await fetch(`${t}${D}${n}`,{method:s.method,headers:await r(),...s.body===void 0?{}:{body:JSON.stringify(s.body)}});if(a.status===409){let u=await a.json().catch(()=>({}));throw new H(u.message??"Someone else saved this first.")}if(!a.ok){let u=await a.text().catch(()=>""),d=`${s.method} ${n} \u2192 ${String(a.status)}`;try{let c=JSON.parse(u);c.message&&(d=c.message)}catch{d=u?`${d}: ${u}`:d}throw w({error:d})}return await a.json()}catch(a){throw a instanceof H?a:w(a)}},i=n=>`/tables/${encodeURIComponent(n)}`;return{listTables:async()=>(await v(`${t}${D}/tables`,await r())).tables,listRows:async(n,s)=>await v(`${t}${D}${i(n)}/rows?limit=${String(s??100)}`,await r()),insertRow:async(n,s)=>{let{rowIds:a}=await l(`${i(n)}/rows`,{method:"POST",body:{rows:[s]}}),u=a[0];if(!u)throw w(new Error("The row was not created."));return u},patchRow:async(n,s,a)=>(await l(`${i(n)}/rows/${encodeURIComponent(s)}`,{method:"PATCH",body:a})).updated,deleteRow:async(n,s)=>(await l(`/${encodeURIComponent(n)}/${encodeURIComponent(s)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await v(`${t}${D}/tables/files/rows?limit=200`,await r())).rows.map(s=>({id:s.rowId,filename:String(s.data.filename??""),source:String(s.data.source??"client"),campaign:String(s.data.campaign??""),size:typeof s.data.size=="number"?s.data.size:0,createdAt:s.createdAt})),uploadFile:async(n,s)=>{let a=new Uint8Array(await n.arrayBuffer());return await l("/files",{method:"POST",body:{filename:n.name,mime:n.type||"application/octet-stream",data:ct(a),...s===void 0?{}:{message:s}}})},fileLink:async n=>await v(`${t}${D}/files/${encodeURIComponent(n)}/url`,await r()),deleteFile:async n=>(await l(`/files/${encodeURIComponent(n)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await v(`${t}${D}/documents`,await r())).documents,readDocument:async n=>(await v(`${t}${D}/documents/${encodeURIComponent(n)}`,await r())).document,saveDocument:async(n,s)=>await l(`/documents/${encodeURIComponent(n)}`,{method:"PATCH",body:s})}};var mt=/\/+$/,ft="/api/v1/end-user",yt=e=>{let t=e.baseUrl.replace(mt,""),o=async(r,l)=>{let i;try{i=await fetch(`${t}${ft}${r}`,l===void 0?{}:{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(l)})}catch(n){throw w(n)}if(i.status===429)throw w({error:"rate_limited",retryable:!0});if(!i.ok)throw w({error:`shop_request_failed_${String(i.status)}`});try{return await i.json()}catch(n){throw w(n)}};return{listProducts:async()=>{let r=await o(`/shop/products?publishable_key=${encodeURIComponent(e.publishableKey)}`);return{products:r.products.map(l=>({...l,currency:typeof l.currency=="string"?l.currency:""})),truncated:r.truncated===!0}},apply:async r=>await o("/shop/apply",{publishable_key:e.publishableKey,name:r.name,email:r.email,...r.phone?{phone:r.phone}:{},...r.message?{message:r.message}:{},...r.productId?{productId:r.productId}:{}})}};import{useCallback as bt,useEffect as ht,useState as A}from"react";var wt=e=>e&&typeof e=="object"&&typeof e.error=="string"?e.error:e instanceof Error?e.message:"shop_unavailable",xt=e=>{let[t,o]=A([]),[r,l]=A(!1),[i,n]=A(!0),[s,a]=A(null),[u,d]=A(0);ht(()=>{let g=!0;return n(!0),e.listProducts().then(p=>{g&&(o(p.products),l(p.truncated),a(null))}).catch(p=>{g&&a(wt(p))}).finally(()=>{g&&n(!1)}),()=>{g=!1}},[e,u]);let c=bt(()=>d(g=>g+1),[]);return{products:t,truncated:r,loading:i,error:s,reload:c}};import{useCallback as vt,useEffect as Ae,useRef as St,useState as $}from"react";var Me="greeting";function We(e,t){if(e.some(i=>i.id===t.id))return e;let o=e.filter(i=>i.id!==Me),r=i=>i.author==="client"==(t.author==="client");return[...o.filter(i=>!(i.pending&&r(i)&&i.text===t.text)),t]}var Rt=(e,t)=>{let[o,r]=$([]),[l,i]=$(""),[n,s]=$(!1),[a,u]=$(null),d=St(0),c=t?.pollMs??2e3;Ae(()=>{let p=!0;return e.getInfo().then(y=>{p&&y.greeting&&r(x=>x.length===0?[{id:Me,cursor:"",author:"agent",text:y.greeting}]:x)}).catch(()=>{}),()=>{p=!1}},[e]),Ae(()=>e.subscribe?.({onMessage:p=>r(y=>We(y,p)),onError:p=>u(p.error),onHealthy:()=>u(null)},{intervalMs:c}),[e,c]);let g=vt(()=>{let p=l.trim();if(!p||n)return;i(""),u(null),s(!0),d.current+=1;let y=`pending-${d.current}`,x={id:y,cursor:"",author:"client",text:p,pending:!0};r(f=>[...f,x]),e.sendMessage(p).then(f=>{s(!1),f.reply.trim()&&r(m=>m.some(k=>!k.pending&&k.author!=="client"&&k.text===f.reply)?m:(d.current+=1,[...m,{id:`pending-agent-${d.current}`,cursor:"",author:"agent",text:f.reply,pending:!0}]))}).catch(f=>{u(f instanceof Error?f.message:"send_failed"),s(!1),r(R=>R.filter(m=>m.id!==y)),i(R=>R||p)})},[l,n,e]);return{messages:o,input:l,setInput:i,send:g,sending:n,error:a}};export{Ke as Chat,le as GRID_COLS,ue as GRID_MAX_COLS,de as GRID_MAX_ROWS,je as HolaProvider,H as PortalConflict,W as bandOfKind,ce as bandOfType,De as cellValue,Ue as createApiTransport,qe as createHolaClient,gt as createPortalData,yt as createPortalShop,G as createWidgetTransport,Te as deliverableCellText,ve as deliverableStatus,se as deriveFields,E as emptyTableResponses,ge as footprintOf,B as footprintWith,He as formatDeliverableDate,q as groupDeliverableVersions,ae as inferSpec,ke as isDeliverableChecked,We as mergeMessage,Q as normalizeDeliverableColType,X as normalizeDeliverableItem,we as parseDashboardSpec,xe as parseDeliverableItems,Re as parseDeliverableTable,Pe as parseTableResponses,z as placeWidgets,Se as publishedVersionOf,be as renderModel,Ce as setResponse,Ie as setTableReview,me as splitLayout,_ as textDeltaOf,O as thinkingDeltaOf,U as toolEventOf,F as useArtifactUrl,V as useChat,N as useHolaClient,xt as useShop,Rt as useThread};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holaboss/client",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
4
|
-
"description": "Injectable client SDK for embedding a Holaboss AI employee (chat today;
|
|
3
|
+
"version": "0.2.0-beta.20",
|
|
4
|
+
"description": "Injectable client SDK for embedding a Holaboss AI employee (chat + configurable dashboards today; artifacts next) into your own web app.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"dev": "tsup --watch",
|
|
22
22
|
"build": "tsup",
|
|
23
23
|
"check-types": "tsc --noEmit",
|
|
24
|
-
"prepublishOnly": "bun run build"
|
|
24
|
+
"prepublishOnly": "bun run build",
|
|
25
|
+
"test": "vitest run"
|
|
25
26
|
},
|
|
26
27
|
"peerDependencies": {
|
|
27
28
|
"react": ">=18"
|
|
@@ -31,7 +32,8 @@
|
|
|
31
32
|
"@types/react-dom": "^19.1.9",
|
|
32
33
|
"tsconfig": "workspace:*",
|
|
33
34
|
"tsup": "^8.3.5",
|
|
34
|
-
"typescript": "catalog:"
|
|
35
|
+
"typescript": "catalog:",
|
|
36
|
+
"vitest": "^4.1.0"
|
|
35
37
|
},
|
|
36
38
|
"keywords": [
|
|
37
39
|
"ai",
|