@holaboss/client 0.2.0-beta.30 → 0.2.0-beta.31
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 +169 -13
- package/dist/index.d.ts +169 -13
- package/dist/index.js +5 -5
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
var
|
|
3
|
-
`))r.startsWith(":")||(r.startsWith("event:")?t=r.slice(6).trim():r.startsWith("data:")&&n.push(r.slice(5).replace(
|
|
4
|
-
`)}:null},
|
|
2
|
+
var se=Object.defineProperty;var ct=Object.getOwnPropertyDescriptor;var mt=Object.getOwnPropertyNames;var gt=Object.prototype.hasOwnProperty;var ft=(e,t)=>{for(var n in t)se(e,n,{get:t[n],enumerable:!0})},yt=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of mt(t))!gt.call(e,s)&&s!==n&&se(e,s,{get:()=>t[s],enumerable:!(r=ct(t,s))||r.enumerable});return e};var bt=e=>yt(se({},"__esModule",{value:!0}),e);var zt={};ft(zt,{Chat:()=>Le,CreditRefused:()=>H,GRID_COLS:()=>ue,GRID_MAX_COLS:()=>de,GRID_MAX_ROWS:()=>pe,HolaProvider:()=>Fe,InsufficientCredits:()=>_,PortalConflict:()=>M,QUOTE_BALANCE_LABEL:()=>oe,QUOTE_DEPOSIT_LABEL:()=>re,bandOfKind:()=>W,bandOfType:()=>ce,buyRequestText:()=>it,cellValue:()=>Ce,createApiTransport:()=>$e,createHolaClient:()=>Ue,createPortalCredits:()=>Je,createPortalData:()=>Ke,createPortalShop:()=>Xe,createWidgetTransport:()=>J,creditsOfMoney:()=>Qe,deliverableCellText:()=>ve,deliverableStatus:()=>we,deriveFields:()=>ae,emptyTableResponses:()=>F,facetValues:()=>st,footprintOf:()=>me,footprintWith:()=>K,formatDeliverableDate:()=>Ie,groupDeliverableVersions:()=>Z,includesFor:()=>ot,inferSpec:()=>le,isDeliverableChecked:()=>ke,mergeMessage:()=>He,modeOf:()=>Ye,money:()=>L,normalizeDeliverableColType:()=>ee,normalizeDeliverableItem:()=>Y,orderBilling:()=>ze,parseDashboardSpec:()=>he,parseDeliverableItems:()=>xe,parseDeliverableTable:()=>Se,parseTableResponses:()=>Te,paymentAsked:()=>ne,placeWidgets:()=>X,priceFor:()=>tt,priceLabel:()=>Ae,publishedVersionOf:()=>Pe,quantityRange:()=>rt,quoteSchedule:()=>Ge,renderModel:()=>be,setResponse:()=>Re,setTableReview:()=>De,shelfPriceLabel:()=>et,shelfProblem:()=>at,splitLayout:()=>ge,textDeltaOf:()=>U,thinkingDeltaOf:()=>N,toolEventOf:()=>q,totalFor:()=>nt,useArtifactUrl:()=>V,useChat:()=>Q,useCredits:()=>lt,useHolaClient:()=>G,useShop:()=>ut,useThread:()=>pt});module.exports=bt(zt);var Ee=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},U=e=>{let t=Ee(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},N=e=>{let t=Ee(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},q=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 ht=/^ /,w=e=>{if(e&&typeof e=="object"){let t=e,n=typeof t.error=="string"?t.error:"request_failed";return typeof t.retryable=="boolean"?{error:n,retryable:t.retryable}:{error:n}}return{error:"request_failed"}},xt=e=>{let t="message",n=[];for(let r of e.split(`
|
|
3
|
+
`))r.startsWith(":")||(r.startsWith("event:")?t=r.slice(6).trim():r.startsWith("data:")&&n.push(r.slice(5).replace(ht,"")));return n.length>0?{event:t,data:n.join(`
|
|
4
|
+
`)}:null},wt=(e,t,n)=>{let r;try{r=JSON.parse(e.data)}catch{return}if(e.event==="session"){let s=r.sessionId;s&&(n(s),t.onSession?.(s));return}if(e.event==="turn_event"){t.onEvent?.(r);let s=U(r);s&&t.onText?.(s);let a=N(r);a&&t.onThinking?.(a);let o=q(r);o&&t.onTool?.(o);return}if(e.event==="chat_completed"){let s=r;n(s.sessionId),t.onComplete?.(s);return}e.event==="chat_error"&&t.onError?.(w(r))},v=async(e,t)=>{let n=await fetch(e,{headers:t});if(!n.ok)throw new Error(`hola: request failed (${n.status})`);return await n.json()},Me=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()},We=async(e,t,n,r)=>{let s=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:r});if(!(s.ok&&s.body)){t.onError?.({error:`stream_failed_${s.status}`});return}let a=s.body.getReader(),o=new TextDecoder,i="",l=()=>{let d=i.indexOf(`
|
|
5
5
|
|
|
6
|
-
`);for(;d!==-1;){let
|
|
6
|
+
`);for(;d!==-1;){let m=i.slice(0,d);i=i.slice(d+2);let p=xt(m);p&&wt(p,t,n),d=i.indexOf(`
|
|
7
7
|
|
|
8
|
-
`)}},u=async()=>{let d=await i.read();if(!d.done)return a+=o.decode(d.value,{stream:!0}),l(),u()};await u()};var bt=/\/+$/,te="/api/v1/end-user",Ee=e=>{let t=e.baseUrl.replace(bt,""),n=()=>typeof e.token=="function"?e.token():e.token,r=o=>e.project?`${o}project=${encodeURIComponent(e.project)}`:"",s=async()=>({"content-type":"application/json",authorization:`Bearer ${await n()}`}),i=async o=>{let a=await fetch(`${t}${te}/chat${r("?")}`,{method:"POST",headers:await s(),body:JSON.stringify({message:o})});if(!a.ok)throw new Error(`hola: message failed (${a.status})`);return{reply:(await a.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>P(`${t}${te}/chat/info${r("?")}`,await s()),sendMessage:i,streamMessage:async(o,a)=>{try{let l=await i(o);a.onText?.(l.reply),a.onComplete?.(l)}catch(l){a.onError?.(w(l))}},subscribe:(o,a)=>{let l=a?.since??"0",u=!1,d,p=a?.intervalMs??3e3,f=typeof document<"u",c=()=>f&&document.visibilityState==="hidden",m=!1,y=()=>{if(!u){if(c()){m=!0;return}d=setTimeout(b,p)}},b=async()=>{try{let x=await P(`${t}${te}/chat/thread?since=${encodeURIComponent(l)}${r("&")}`,await s());for(let I of x.messages)o.onMessage(I);l=x.cursor,o.onHealthy?.()}catch(x){o.onError?.(w(x))}y()},R=()=>{u||!m||c()||(m=!1,d&&clearTimeout(d),d=setTimeout(b,0))};f&&document.addEventListener("visibilitychange",R);let g=()=>{u=!0,d&&clearTimeout(d),f&&document.removeEventListener("visibilitychange",R)};return a?.signal?.addEventListener("abort",g),d=setTimeout(b,0),g}}};var N=require("react"),B=(e,t)=>{let[n,r]=(0,N.useState)("");return(0,N.useEffect)(()=>{if(!e){r("");return}let s=Uint8Array.from(atob(e),o=>o.charCodeAt(0)),i=URL.createObjectURL(new Blob([s],{type:t}));return r(i),()=>URL.revokeObjectURL(i)},[e,t]),n};var Q=require("react");var V=require("react"),We=require("react/jsx-runtime"),Me=(0,V.createContext)(null),$e=({client:e,children:t})=>(0,We.jsx)(Me.Provider,{value:e,children:t}),j=()=>{let e=(0,V.useContext)(Me);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};var S=require("react"),G=e=>{let[t,n]=(0,S.useState)([]),[r,s]=(0,S.useState)(""),[i,o]=(0,S.useState)(!1),[a,l]=(0,S.useState)(null),u=(0,S.useRef)(0),d=(0,S.useRef)(null);(0,S.useEffect)(()=>()=>d.current?.abort(),[]);let p=(0,S.useCallback)(()=>{let c=u.current;return u.current+=1,c},[]);(0,S.useEffect)(()=>{let c=!0;return e.getInfo().then(m=>{c&&m.greeting&&n([{id:p(),role:"assistant",text:m.greeting}])}).catch(()=>{}),()=>{c=!1}},[e,p]);let f=(0,S.useCallback)(()=>{let c=r.trim();if(!c||i)return;s(""),l(null),o(!0);let m=p(),y=p();n(g=>[...g,{id:m,role:"user",text:c},{id:y,role:"assistant",text:"",streaming:!0}]);let b=g=>{n(x=>x.map(I=>I.id===y?g(I):I))},R=new AbortController;d.current=R,e.streamMessage(c,{onText:g=>b(x=>({...x,text:x.text+g})),onComplete:g=>{b(x=>({...x,text:g.reply||x.text,artifacts:g.artifacts,streaming:!1})),o(!1)},onError:g=>{b(x=>({...x,streaming:!1})),l(g.error),o(!1)}},R.signal).catch(g=>{b(x=>({...x,streaming:!1})),l(g instanceof Error?g.message:"stream_failed"),o(!1)}).finally(()=>{o(!1),b(g=>g.streaming?{...g,streaming:!1}:g)})},[r,i,e,p]);return{messages:t,input:r,setInput:s,send:f,sending:i,error:a}};var v=require("react/jsx-runtime"),k={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"}},ht=({artifact:e})=>{let t=B(e.dataBase64??"",e.mimeType),n=e.url??t;return n?e.mimeType.startsWith("image/")?(0,v.jsx)("a",{href:n,rel:"noopener noreferrer",target:"_blank",children:(0,v.jsx)("img",{alt:e.filename,src:n,style:k.image})}):(0,v.jsx)("a",{download:e.filename,href:n,style:k.link,children:e.filename}):null},Oe=()=>{let e=j(),{messages:t,input:n,setInput:r,send:s,sending:i,error:o}=G(e),a=(0,Q.useRef)(null);(0,Q.useEffect)(()=>{let u=a.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let l=u=>{u.preventDefault(),s()};return(0,v.jsxs)("div",{style:k.root,children:[(0,v.jsx)("div",{ref:a,style:k.log,children:t.map(u=>(0,v.jsxs)("div",{style:u.role==="user"?k.user:k.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?(0,v.jsx)("div",{style:k.artifacts,children:u.artifacts.map(d=>(0,v.jsx)(ht,{artifact:d},d.filename))}):null]},u.id))}),o?(0,v.jsx)("div",{style:k.error,children:o}):null,(0,v.jsxs)("form",{onSubmit:l,style:k.form,children:[(0,v.jsx)("input",{"aria-label":"Message",onChange:u=>r(u.target.value),placeholder:"Type a message\u2026",style:k.input,value:n}),(0,v.jsx)("button",{disabled:i||n.trim().length===0,style:k.button,type:"submit",children:"Send"})]})]})};var xt=/\/+$/,z=e=>{let t=e.sessionId,n=e.baseUrl.replace(xt,""),r=o=>`${n}/endpoint/${encodeURIComponent(e.token)}${o}`,s={"content-type":"application/json"},i=(o,a)=>({url:r(o),headers:s,body:JSON.stringify({message:a,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>P(r("/config"),{}),sendMessage:async o=>{let a=await Ae(i("/message",o));return t=a.sessionId,a},streamMessage:(o,a,l)=>He(i("/message/stream",o),a,u=>{t=u},l),subscribe:(o,a)=>{let l=a?.since??"0",u=!1,d,p=a?.intervalMs??3e3,f=async()=>{let m=t;if(m)try{let y=await P(r(`/messages?session=${encodeURIComponent(m)}&since=${encodeURIComponent(l)}`),{});for(let b of y.messages)o.onMessage(b);l=y.cursor,o.onHealthy?.()}catch(y){o.onError?.(w(y))}u||(d=setTimeout(f,p))},c=()=>{u=!0,d&&clearTimeout(d)};return a?.signal?.addEventListener("abort",c),d=setTimeout(f,0),c}}};var Fe=e=>"transport"in e?e.transport:z(e);var wt=/^https?:\/\//i,St=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,vt=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function Pt(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(wt.test(e))return"url";if(St.test(e))return"date"}return"text"}function ne(e){let t=[],n=new Map;for(let r of e)for(let[s,i]of Object.entries(r.data??{})){if(i==null)continue;let o=n.get(s);o||(o=new Map,n.set(s,o),t.push(s));let a=Pt(i);o.set(a,(o.get(a)??0)+1)}return t.map(r=>{let s=n.get(r)??new Map,i="text",o=-1;for(let[a,l]of s)l>o&&(o=l,i=a);return{key:r,label:vt(r),type:i}})}var Tt=e=>typeof e=="number"?e:Number(e)||0,_e=e=>/rate|position|rank|score|percent|avg/i.test(e),kt=/posted|published|sent|completed|shipped|launched|_at/i,Ct=new Set(["service","order","end_user_id"]);function re(e,t){let n=e.filter(l=>!Ct.has(l.key)),r=n.filter(l=>l.type==="number").slice(0,3),s=n.find(l=>l.key==="status")??n.find(l=>l.type==="select"),i=n.find(l=>l.type==="date"&&kt.test(l.key))??n.find(l=>l.type==="date"),o=n.filter(l=>l.type==="number"&&!_e(l.key)).map(l=>({field:l,total:t.reduce((u,d)=>u+Tt(d.data[l.key]),0)})).sort((l,u)=>u.total-l.total).find(l=>l.total>0)?.field??null,a=[{type:"stat",label:"Items",agg:"count"}];for(let l of r){let u=_e(l.key);a.push({type:"stat",metric:l.key,agg:u?"avg":"sum",label:u?`Avg ${l.label.toLowerCase()}`:l.label})}return i&&a.push({type:"line",x:i.key,y:o?.key,agg:"sum",title:o?`${o.label} by day`:"Items by day"}),s&&a.push({type:"donut",groupBy:s.key,title:s.label}),a.push({type:"table",columns:n.map(l=>l.key)}),{version:1,widgets:a}}var oe=6,se=6,ie=4,Le={stat:{w:1,h:1},chart:{w:2,h:2},block:{w:6,h:2}},Rt=e=>Math.max(1,Math.min(6,Math.round(e))),Dt=e=>Math.max(1,Math.min(4,Math.round(e)));function $(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function ae(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function le(e){return Le[e]}function J(e,t,n){let r=Le[e];return{w:t===void 0?r.w:Rt(t),h:n===void 0?r.h:Dt(n)}}function K(e){let t=[],n=[],r=(o,a,l,u)=>{if(o<0||o+l>6)return!1;for(let d=0;d<u;d+=1){let p=n[a+d];if(p){for(let f=0;f<l;f+=1)if(p[o+f])return!1}}return!0},s=(o,a,l,u)=>{for(let d=0;d<u;d+=1){let p=n[a+d]??[];for(let f=0;f<l;f+=1)p[o+f]=!0;n[a+d]=p}},i=(o,a)=>{for(let l=0;;l+=1)for(let u=0;u+o<=6;u+=1)if(r(u,l,o,a))return{gx:u,gy:l}};for(let o of e){let a=J($(o.kind),o.w,o.h),u=o.gx!==void 0&&o.gy!==void 0&&r(o.gx,o.gy,a.w,a.h)&&o.gx!==void 0&&o.gy!==void 0?{gx:o.gx,gy:o.gy}:i(a.w,a.h);s(u.gx,u.gy,a.w,a.h),t.push({widget:o,gx:u.gx,gy:u.gy,w:a.w,h:a.h})}return t}function ue(e){let t=[],n=[];for(let r of e)$(r.kind)==="block"?n.push(r):t.push(r);return{tiles:K(t),blocks:n}}var Ue=new Set(["service","order","end_user_id"]),de=e=>typeof e=="number"?e:Number(e)||0,qe=e=>e==null?"":String(e);function pe(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 n=t.reduce((r,s)=>r+s,0);return e==="avg"?Math.round(n/t.length*100)/100:n}function It(e,t,n,r){let s=new Map;for(let i of e){let o=new Date(qe(i.data[t]));if(Number.isNaN(o.getTime()))continue;let a=o.toISOString().slice(0,10),l=s.get(a)??[];l.push(n?de(i.data[n]):1),s.set(a,l)}return[...s.entries()].sort((i,o)=>i[0]<o[0]?-1:1).map(([i,o])=>({label:new Date(`${i}T00:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"}),value:n?pe(r,o):o.length}))}function At(e,t,n,r="sum"){let s=new Map;for(let i of e){let o=qe(i.data[t]).trim();if(!o)continue;let a=s.get(o)??[];a.push(n?de(i.data[n]):1),s.set(o,a)}return[...s.entries()].map(([i,o])=>({label:i,value:n?pe(r,o):o.length})).sort((i,o)=>o.value-i.value)}function Ht(e,t,n,r){switch(e.type){case"stat":{let s=e.metric?t.get(e.metric):void 0;if(e.metric&&!s)return null;if(!s)return{kind:"stat",label:e.label??"Items",value:r.length};let i=r.map(o=>de(o.data[s.key]));return{kind:"stat",label:e.label??s.label,value:pe(e.agg??"sum",i)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let s=It(r,e.x,e.y,e.agg??"sum");return s.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:s}}case"donut":{if(!t.has(e.groupBy))return null;let s=At(r,e.groupBy,e.metric,e.agg??"sum");return s.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:s}}case"table":{let s=e.columns?e.columns.map(i=>t.get(i)).filter(i=>i!==void 0&&!Ue.has(i.key)):n;return s.length===0?null:{kind:"table",title:e.title,columns:s,rows:r}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function ce(e,t,n,r={}){let s=new Map,i=l=>({byKey:new Map(l.fields.map(u=>[u.key,u])),cols:l.fields.filter(u=>!Ue.has(u.key)),rows:l.rows}),o=i({fields:t,rows:n});for(let[l,u]of Object.entries(r))s.set(l,i(u));let a=[];for(let l of e.widgets){let u=l.type==="text"?void 0:l.source,d=u?s.get(u):o;if(!d)continue;let p=Ht(l,d.byKey,d.cols,d.rows);p&&a.push({...p,w:l.w,h:l.h,gx:l.gx,gy:l.gy})}return a}var Et=new Set(["sum","avg","count","min","max","last"]),Ne=e=>typeof e=="string"&&Et.has(e)?e:void 0,h=e=>typeof e=="string"&&e!==""?e:void 0,W=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,O=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0,D=e=>typeof e=="number"&&e>=0?Math.round(e):void 0;function Mt(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",source:h(t.source),label:h(t.label),metric:h(t.metric)??h(t.column),agg:Ne(t.agg),w:W(t.w),h:O(t.h),gx:D(t.gx),gy:D(t.gy)};case"line":case"bar":{let n=h(t.x);return n?{type:t.type,source:h(t.source),title:h(t.title),x:n,y:h(t.y)??h(t.column),agg:Ne(t.agg),w:W(t.w),h:O(t.h),gx:D(t.gx),gy:D(t.gy)}:null}case"donut":{let n=h(t.groupBy)??h(t.column);return n?{type:"donut",source:h(t.source),title:h(t.title),groupBy:n,w:W(t.w),h:O(t.h),gx:D(t.gx),gy:D(t.gy)}:null}case"table":{let n=Array.isArray(t.columns)?t.columns.filter(r=>typeof r=="string"):void 0;return{type:"table",source:h(t.source),title:h(t.title),columns:n,w:W(t.w),h:O(t.h),gx:D(t.gx),gy:D(t.gy)}}case"text":{let n=h(t.body);return n?{type:"text",title:h(t.title),body:n,w:W(t.w),h:O(t.h),gx:D(t.gx),gy:D(t.gy)}:null}default:return null}}function me(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 n=t.widgets;if(!Array.isArray(n))return null;let r=n.map(Mt).filter(i=>i!==null);if(r.length===0)return null;let s=t.version;return{version:typeof s=="number"?s:1,title:h(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,n=typeof t.value=="string"?t.value:"",r=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",s=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return n?{kind:r,value:n,...s?{v:s}:{}}:null}return null}function Y(e){let t=new Map;for(let n of e){let r=n.v??1,s=t.get(r)??[];s.push(n),t.set(r,s)}return[...t.entries()].sort(([n],[r])=>n-r).map(([n,r])=>({v:n,items:r}))}function ge(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(s=>s!==null)}catch{}let n=String(e.file??"");return n?[{kind:"file",value:n}]:[]}function fe(e,t,n,r=""){let i=Y(e).find(a=>a.v===t)?.items??[],o=i.filter(a=>a.kind==="file").map(a=>n.get(a.value)??"");return i.some(a=>a.kind==="table")&&o.push(r),o.length===0||o.some(a=>a==="")?"awaiting":o.some(a=>a==="revise")?"revise":"accepted"}function ye(e){return Number(e.published_version)||0}function Z(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function be(e){try{let t=JSON.parse(e);if(Array.isArray(t.columns)&&Array.isArray(t.rows)&&t.columns.length){let n=t.columns.map((i,o)=>({key:typeof i.key=="string"&&i.key?i.key:typeof i.id=="string"&&i.id?i.id:`column_${o+1}`,label:typeof i.label=="string"?i.label:"",type:Z(i.type),...i.clientEditable===!0?{clientEditable:!0}:{}})),r=t.rows.map((i,o)=>({id:typeof i.id=="string"&&i.id?i.id:`row_${o}`,cells:i.cells&&typeof i.cells=="object"?i.cells:{}})),s=typeof t.name=="string"?t.name:void 0;return{columns:n,rows:r,...s?{name:s}:{}}}}catch{}return null}function he(e){return e==null?"":String(e)}function xe(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function F(){return{cells:{},verdict:"",comment:""}}function we(e){if(typeof e!="string"||e.trim()==="")return F();try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t)){let n=t;return{cells:n.cells&&typeof n.cells=="object"?n.cells:n,verdict:n.verdict==="accepted"||n.verdict==="revise"?n.verdict:"",comment:typeof n.comment=="string"?n.comment:""}}}catch{}return F()}function Se(e,t,n){if(e.clientEditable){let r=n.cells[t.id];if(r&&e.key in r)return r[e.key]}return t.cells[e.key]}function ve(e,t,n,r){return{...e,cells:{...e.cells,[t]:{...e.cells[t]??{},[n]:r}}}}function Pe(e,t,n){return{...e,verdict:t,comment:n}}function Te(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 E=class extends Error{code;status;constructor(t,n,r){super(n),this.name="CreditRefused",this.code=t,this.status=r}},$t=/\/+$/,Wt="/api/v1/end-user",ke="Pre-payment",Ce="After-payment";function Be(e,t){if(e<=0)return[];let n=t&&typeof t.upfront=="number"&&Number.isFinite(t.upfront)?Math.max(0,Math.min(t.upfront,e)):e,r=Math.round((e-n)*100)/100,s=[];return n>0&&s.push({label:ke,amount:n}),r>0&&s.push({label:Ce,amount:r}),s}var Ve=(e,t,n)=>{let r=t.filter(l=>l.order===n),s=r.reduce((l,u)=>l+u.amount,0),i=r.filter(l=>l.status==="paid").reduce((l,u)=>l+u.amount,0),o=e.value>0,a=s>0?s-i:e.value-i;return{value:e.value,priced:o,billed:s,paid:i,due:Math.max(0,a),lines:[...r].sort((l,u)=>l.status!==u.status?l.status==="due"?-1:1:(l.dueDate||l.paidAt).localeCompare(u.dueDate||u.paidAt)),awaitingPayment:o&&i<=0}},je=e=>{let t=e.baseUrl.replace($t,""),n=()=>typeof e.token=="function"?e.token():e.token,r=async(s,i={method:"GET"})=>{try{let o=await fetch(`${t}${Wt}${s}`,{method:i.method,headers:{"content-type":"application/json",authorization:`Bearer ${await n()}`},...i.body===void 0?{}:{body:JSON.stringify(i.body)}});if(!o.ok){let a=await o.json().catch(()=>({}));throw new E(a.error??"request_failed",a.message??`${i.method} ${s} \u2192 ${String(o.status)}`,o.status)}return await o.json()}catch(o){throw o instanceof E?o:w(o)}};return{wallet:()=>r("/credits"),history:()=>r("/credits/history"),topup:s=>r("/credits/checkout",{method:"POST",body:{packId:s}}),checkout:s=>r("/shop/checkout",{method:"POST",body:s}),payments:()=>r("/payments"),paymentMethods:()=>r("/payment-methods"),markPaymentSent:(s,i)=>r(`/payments/${encodeURIComponent(s)}/sent`,{method:"POST",body:{reference:i??""}}),inquiryQuote:s=>r(`/inquiries/${encodeURIComponent(s)}/quote`),acceptInquiry:(s,i)=>r(`/inquiries/${encodeURIComponent(s)}/accept`,{method:"POST",body:{version:i}}),enquire:(s,i,o)=>r("/shop/enquire",{method:"POST",body:{productId:s,answers:i,name:o??""}})}};var Ot=/\/+$/,H="/api/v1/end-user",M=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function Ft(e){let t="";for(let r=0;r<e.length;r+=32768)t+=String.fromCharCode(...e.subarray(r,r+32768));return btoa(t)}var Ge=e=>{let t=e.baseUrl.replace(Ot,""),n=()=>typeof e.token=="function"?e.token():e.token,r=async()=>({"content-type":"application/json",authorization:`Bearer ${await n()}`}),s=async(o,a)=>{try{let l=await fetch(`${t}${H}${o}`,{method:a.method,headers:await r(),...a.body===void 0?{}:{body:JSON.stringify(a.body)}});if(l.status===409){let u=await l.json().catch(()=>({}));throw new M(u.message??"Someone else saved this first.")}if(!l.ok){let u=await l.text().catch(()=>""),d=`${a.method} ${o} \u2192 ${String(l.status)}`;try{let p=JSON.parse(u);p.message&&(d=p.message)}catch{d=u?`${d}: ${u}`:d}throw w({error:d})}return await l.json()}catch(l){throw l instanceof M?l:w(l)}},i=o=>`/tables/${encodeURIComponent(o)}`;return{listTables:async()=>(await P(`${t}${H}/tables`,await r())).tables,listRows:async(o,a)=>await P(`${t}${H}${i(o)}/rows?limit=${String(a??100)}`,await r()),insertRow:async(o,a)=>{let{rowIds:l}=await s(`${i(o)}/rows`,{method:"POST",body:{rows:[a]}}),u=l[0];if(!u)throw w(new Error("The row was not created."));return u},patchRow:async(o,a,l)=>(await s(`${i(o)}/rows/${encodeURIComponent(a)}`,{method:"PATCH",body:l})).updated,deleteRow:async(o,a)=>(await s(`/${encodeURIComponent(o)}/${encodeURIComponent(a)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await P(`${t}${H}/tables/files/rows?limit=200`,await r())).rows.map(a=>({id:a.rowId,filename:String(a.data.filename??""),source:String(a.data.source??"client"),campaign:String(a.data.campaign??""),size:typeof a.data.size=="number"?a.data.size:0,createdAt:a.createdAt})),uploadFile:async(o,a)=>{let l=new Uint8Array(await o.arrayBuffer());return await s("/files",{method:"POST",body:{filename:o.name,mime:o.type||"application/octet-stream",data:Ft(l),...a===void 0?{}:{message:a}}})},fileLink:async o=>await P(`${t}${H}/files/${encodeURIComponent(o)}/url`,await r()),deleteFile:async o=>(await s(`/files/${encodeURIComponent(o)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await P(`${t}${H}/documents`,await r())).documents,readDocument:async o=>(await P(`${t}${H}/documents/${encodeURIComponent(o)}`,await r())).document,saveDocument:async(o,a)=>await s(`/documents/${encodeURIComponent(o)}`,{method:"PATCH",body:a})}};var _t=/\/+$/,Lt="/api/v1/end-user",Qe=e=>{let t=e.baseUrl.replace(_t,""),n=async(r,s)=>{let i;try{i=await fetch(`${t}${Lt}${r}`,s===void 0?{}:{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)})}catch(o){throw w(o)}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(o){throw w(o)}};return{listProducts:async()=>{let r=await n(`/shop/products?publishable_key=${encodeURIComponent(e.publishableKey)}`);return{products:r.products.map(s=>({...s,currency:typeof s.currency=="string"?s.currency:""})),truncated:r.truncated===!0,enquiryForm:Array.isArray(r.enquiryForm)?r.enquiryForm:[]}},apply:async r=>await n("/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}:{}})}};var Ut=new Set(["buy","ask"]);function ze(e){return Ut.has(e.mode)?e.mode:"ask"}var qt={kind:"quoted"};function _(e,t){if(!t)return e.toLocaleString();if(t.toLowerCase()==="credits")return`${e.toLocaleString()} ${e===1?"credit":"credits"}`;let n=Number.isInteger(e)?0:2;try{return new Intl.NumberFormat(void 0,{style:"currency",currency:t,minimumFractionDigits:n,maximumFractionDigits:n}).format(e)}catch{return`${t} ${e.toLocaleString()}`}}function Je(e,t){let n=/^[a-z]+$/i.test(t)&&!t.endsWith("s")?"s":"";return`${e.toLocaleString()} ${t}${n}`}function Re(e,t){return e.kind==="quoted"?"Priced on enquiry":e.kind==="flat"?_(e.price,t):`${_(e.unitPrice,t)} per ${e.unitStep===1?e.unit:Je(e.unitStep,e.unit)}`}function Ke(e){let t=e.currency,n=e.pricing;if(n.kind!=="variants")return Re(n,t);let r=n.variants.map(s=>s.price).filter(s=>typeof s=="number");return r.length>0?`From ${_(Math.min(...r),t)}`:"Priced on enquiry"}function Xe(e,t){if(e.kind!=="variants")return e;let n=e.variants.find(r=>r.name===t);return typeof n?.price=="number"?{kind:"flat",price:n.price}:qt}function Ye(e,t){return e.kind==="flat"?e.price:e.kind==="per_unit"?e.unitPrice*Math.ceil(t/Math.max(e.unitStep,1)):null}function Ze(e,t){let n=t.kind==="per_unit"?Math.max(t.unitStep,1):1;return{min:Math.max(e.minQty??n,n),max:e.maxQty??null,step:n}}function et(e,t){let n=e.variants?.find(r=>r.name===t);return n&&n.includes.length>0?n.includes:e.includes}function tt(e,t){let n=[];for(let r of e){let s=t(r).trim();s&&!n.includes(s)&&n.push(s)}return n}function nt(e,t,n,r){let s=t?`${e.name} \u2014 ${t}`:e.name,i=n.kind==="per_unit"?`, ${Je(r,n.unit)}`:"";return`I'd like to buy ${s}${i}. How do I go ahead?`}function rt(e){return e?(e&&typeof e=="object"&&"error"in e?String(e.error):"")==="rate_limited"?"That's a lot of looking at once \u2014 give it a moment, then reload.":"The shop isn't loading right now. Please try again shortly.":null}var A=require("react"),ot=e=>{let[t,n]=(0,A.useState)(null),[r,s]=(0,A.useState)(!0),[i,o]=(0,A.useState)(null),a=(0,A.useCallback)(async()=>{try{n(await e.wallet()),o(null)}catch{o("Couldn't read your balance just now.")}finally{s(!1)}},[e]),l=(0,A.useCallback)(()=>{a().catch(()=>{})},[a]);return(0,A.useEffect)(()=>(l(),window.addEventListener("focus",l),()=>{window.removeEventListener("focus",l)}),[l]),{wallet:t,loading:r,failure:i,refresh:l}};var C=require("react"),Nt=e=>e&&typeof e=="object"&&typeof e.error=="string"?e.error:e instanceof Error?e.message:"shop_unavailable",st=e=>{let[t,n]=(0,C.useState)([]),[r,s]=(0,C.useState)([]),[i,o]=(0,C.useState)(!1),[a,l]=(0,C.useState)(!0),[u,d]=(0,C.useState)(null),[p,f]=(0,C.useState)(0);(0,C.useEffect)(()=>{let m=!0;return l(!0),e.listProducts().then(y=>{m&&(n(y.products),s(y.enquiryForm),o(y.truncated),d(null))}).catch(y=>{m&&d(Nt(y))}).finally(()=>{m&&l(!1)}),()=>{m=!1}},[e,p]);let c=(0,C.useCallback)(()=>f(m=>m+1),[]);return{products:t,enquiryForm:r,truncated:i,loading:a,error:u,reload:c}};var T=require("react"),it="greeting";function De(e,t){if(e.some(i=>i.id===t.id))return e;let n=e.filter(i=>i.id!==it),r=i=>i.author==="client"==(t.author==="client");return[...n.filter(i=>!(i.pending&&r(i)&&i.text===t.text)),t]}var at=(e,t)=>{let[n,r]=(0,T.useState)([]),[s,i]=(0,T.useState)(""),[o,a]=(0,T.useState)(!1),[l,u]=(0,T.useState)(null),d=(0,T.useRef)(0),p=t?.pollMs??2e3;(0,T.useEffect)(()=>{let c=!0;return e.getInfo().then(m=>{c&&m.greeting&&r(y=>y.length===0?[{id:it,cursor:"",author:"agent",text:m.greeting}]:y)}).catch(()=>{}),()=>{c=!1}},[e]),(0,T.useEffect)(()=>e.subscribe?.({onMessage:c=>r(m=>De(m,c)),onError:c=>u(c.error),onHealthy:()=>u(null)},{intervalMs:p}),[e,p]);let f=(0,T.useCallback)(()=>{let c=s.trim();if(!c||o)return;i(""),u(null),a(!0),d.current+=1;let m=`pending-${d.current}`,y={id:m,cursor:"",author:"client",text:c,pending:!0};r(b=>[...b,y]),e.sendMessage(c).then(b=>{a(!1),b.reply.trim()&&r(g=>g.some(I=>!I.pending&&I.author!=="client"&&I.text===b.reply)?g:(d.current+=1,[...g,{id:`pending-agent-${d.current}`,cursor:"",author:"agent",text:b.reply,pending:!0}]))}).catch(b=>{u(b instanceof Error?b.message:"send_failed"),a(!1),r(R=>R.filter(g=>g.id!==m)),i(R=>R||c)})},[s,o,e]);return{messages:n,input:s,setInput:i,send:f,sending:o,error:l}};0&&(module.exports={Chat,CreditRefused,GRID_COLS,GRID_MAX_COLS,GRID_MAX_ROWS,HolaProvider,PortalConflict,QUOTE_BALANCE_LABEL,QUOTE_DEPOSIT_LABEL,bandOfKind,bandOfType,buyRequestText,cellValue,createApiTransport,createHolaClient,createPortalCredits,createPortalData,createPortalShop,createWidgetTransport,deliverableCellText,deliverableStatus,deriveFields,emptyTableResponses,facetValues,footprintOf,footprintWith,formatDeliverableDate,groupDeliverableVersions,includesFor,inferSpec,isDeliverableChecked,mergeMessage,modeOf,money,normalizeDeliverableColType,normalizeDeliverableItem,orderBilling,parseDashboardSpec,parseDeliverableItems,parseDeliverableTable,parseTableResponses,placeWidgets,priceFor,priceLabel,publishedVersionOf,quantityRange,quoteSchedule,renderModel,setResponse,setTableReview,shelfPriceLabel,shelfProblem,splitLayout,textDeltaOf,thinkingDeltaOf,toolEventOf,totalFor,useArtifactUrl,useChat,useCredits,useHolaClient,useShop,useThread});
|
|
8
|
+
`)}},u=async()=>{let d=await a.read();if(!d.done)return i+=o.decode(d.value,{stream:!0}),l(),u()};await u()};var Pt=/\/+$/,ie="/api/v1/end-user",$e=e=>{let t=e.baseUrl.replace(Pt,""),n=()=>typeof e.token=="function"?e.token():e.token,r=o=>e.project?`${o}project=${encodeURIComponent(e.project)}`:"",s=async()=>({"content-type":"application/json",authorization:`Bearer ${await n()}`}),a=async o=>{let i=await fetch(`${t}${ie}/chat${r("?")}`,{method:"POST",headers:await s(),body:JSON.stringify({message:o})});if(!i.ok)throw new Error(`hola: message failed (${i.status})`);return{reply:(await i.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>v(`${t}${ie}/chat/info${r("?")}`,await s()),sendMessage:a,streamMessage:async(o,i)=>{try{let l=await a(o);i.onText?.(l.reply),i.onComplete?.(l)}catch(l){i.onError?.(w(l))}},subscribe:(o,i)=>{let l=i?.since??"0",u=!1,d,m=i?.intervalMs??3e3,p=typeof document<"u",c=()=>p&&document.visibilityState==="hidden",g=!1,y=()=>{if(!u){if(c()){g=!0;return}d=setTimeout(b,m)}},b=async()=>{try{let x=await v(`${t}${ie}/chat/thread?since=${encodeURIComponent(l)}${r("&")}`,await s());for(let I of x.messages)o.onMessage(I);l=x.cursor,o.onHealthy?.()}catch(x){o.onError?.(w(x))}y()},R=()=>{u||!g||c()||(g=!1,d&&clearTimeout(d),d=setTimeout(b,0))};p&&document.addEventListener("visibilitychange",R);let f=()=>{u=!0,d&&clearTimeout(d),p&&document.removeEventListener("visibilitychange",R)};return i?.signal?.addEventListener("abort",f),d=setTimeout(b,0),f}}};var B=require("react"),V=(e,t)=>{let[n,r]=(0,B.useState)("");return(0,B.useEffect)(()=>{if(!e){r("");return}let s=Uint8Array.from(atob(e),o=>o.charCodeAt(0)),a=URL.createObjectURL(new Blob([s],{type:t}));return r(a),()=>URL.revokeObjectURL(a)},[e,t]),n};var z=require("react");var j=require("react"),_e=require("react/jsx-runtime"),Oe=(0,j.createContext)(null),Fe=({client:e,children:t})=>(0,_e.jsx)(Oe.Provider,{value:e,children:t}),G=()=>{let e=(0,j.useContext)(Oe);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};var P=require("react"),Q=e=>{let[t,n]=(0,P.useState)([]),[r,s]=(0,P.useState)(""),[a,o]=(0,P.useState)(!1),[i,l]=(0,P.useState)(null),u=(0,P.useRef)(0),d=(0,P.useRef)(null);(0,P.useEffect)(()=>()=>d.current?.abort(),[]);let m=(0,P.useCallback)(()=>{let c=u.current;return u.current+=1,c},[]);(0,P.useEffect)(()=>{let c=!0;return e.getInfo().then(g=>{c&&g.greeting&&n([{id:m(),role:"assistant",text:g.greeting}])}).catch(()=>{}),()=>{c=!1}},[e,m]);let p=(0,P.useCallback)(()=>{let c=r.trim();if(!c||a)return;s(""),l(null),o(!0);let g=m(),y=m();n(f=>[...f,{id:g,role:"user",text:c},{id:y,role:"assistant",text:"",streaming:!0}]);let b=f=>{n(x=>x.map(I=>I.id===y?f(I):I))},R=new AbortController;d.current=R,e.streamMessage(c,{onText:f=>b(x=>({...x,text:x.text+f})),onComplete:f=>{b(x=>({...x,text:f.reply||x.text,artifacts:f.artifacts,streaming:!1})),o(!1)},onError:f=>{b(x=>({...x,streaming:!1})),l(f.error),o(!1)}},R.signal).catch(f=>{b(x=>({...x,streaming:!1})),l(f instanceof Error?f.message:"stream_failed"),o(!1)}).finally(()=>{o(!1),b(f=>f.streaming?{...f,streaming:!1}:f)})},[r,a,e,m]);return{messages:t,input:r,setInput:s,send:p,sending:a,error:i}};var S=require("react/jsx-runtime"),T={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"}},St=({artifact:e})=>{let t=V(e.dataBase64??"",e.mimeType),n=e.url??t;return n?e.mimeType.startsWith("image/")?(0,S.jsx)("a",{href:n,rel:"noopener noreferrer",target:"_blank",children:(0,S.jsx)("img",{alt:e.filename,src:n,style:T.image})}):(0,S.jsx)("a",{download:e.filename,href:n,style:T.link,children:e.filename}):null},Le=()=>{let e=G(),{messages:t,input:n,setInput:r,send:s,sending:a,error:o}=Q(e),i=(0,z.useRef)(null);(0,z.useEffect)(()=>{let u=i.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let l=u=>{u.preventDefault(),s()};return(0,S.jsxs)("div",{style:T.root,children:[(0,S.jsx)("div",{ref:i,style:T.log,children:t.map(u=>(0,S.jsxs)("div",{style:u.role==="user"?T.user:T.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?(0,S.jsx)("div",{style:T.artifacts,children:u.artifacts.map(d=>(0,S.jsx)(St,{artifact:d},d.filename))}):null]},u.id))}),o?(0,S.jsx)("div",{style:T.error,children:o}):null,(0,S.jsxs)("form",{onSubmit:l,style:T.form,children:[(0,S.jsx)("input",{"aria-label":"Message",onChange:u=>r(u.target.value),placeholder:"Type a message\u2026",style:T.input,value:n}),(0,S.jsx)("button",{disabled:a||n.trim().length===0,style:T.button,type:"submit",children:"Send"})]})]})};var vt=/\/+$/,J=e=>{let t=e.sessionId,n=e.baseUrl.replace(vt,""),r=o=>`${n}/endpoint/${encodeURIComponent(e.token)}${o}`,s={"content-type":"application/json"},a=(o,i)=>({url:r(o),headers:s,body:JSON.stringify({message:i,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>v(r("/config"),{}),sendMessage:async o=>{let i=await Me(a("/message",o));return t=i.sessionId,i},streamMessage:(o,i,l)=>We(a("/message/stream",o),i,u=>{t=u},l),subscribe:(o,i)=>{let l=i?.since??"0",u=!1,d,m=i?.intervalMs??3e3,p=async()=>{let g=t;if(g)try{let y=await v(r(`/messages?session=${encodeURIComponent(g)}&since=${encodeURIComponent(l)}`),{});for(let b of y.messages)o.onMessage(b);l=y.cursor,o.onHealthy?.()}catch(y){o.onError?.(w(y))}u||(d=setTimeout(p,m))},c=()=>{u=!0,d&&clearTimeout(d)};return i?.signal?.addEventListener("abort",c),d=setTimeout(p,0),c}}};var Ue=e=>"transport"in e?e.transport:J(e);var kt=/^https?:\/\//i,Tt=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Ct=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function Rt(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(kt.test(e))return"url";if(Tt.test(e))return"date"}return"text"}function ae(e){let t=[],n=new Map;for(let r of e)for(let[s,a]of Object.entries(r.data??{})){if(a==null)continue;let o=n.get(s);o||(o=new Map,n.set(s,o),t.push(s));let i=Rt(a);o.set(i,(o.get(i)??0)+1)}return t.map(r=>{let s=n.get(r)??new Map,a="text",o=-1;for(let[i,l]of s)l>o&&(o=l,a=i);return{key:r,label:Ct(r),type:a}})}var Dt=e=>typeof e=="number"?e:Number(e)||0,Ne=e=>/rate|position|rank|score|percent|avg/i.test(e),It=/posted|published|sent|completed|shipped|launched|_at/i,At=new Set(["service","order","end_user_id"]);function le(e,t){let n=e.filter(l=>!At.has(l.key)),r=n.filter(l=>l.type==="number").slice(0,3),s=n.find(l=>l.key==="status")??n.find(l=>l.type==="select"),a=n.find(l=>l.type==="date"&&It.test(l.key))??n.find(l=>l.type==="date"),o=n.filter(l=>l.type==="number"&&!Ne(l.key)).map(l=>({field:l,total:t.reduce((u,d)=>u+Dt(d.data[l.key]),0)})).sort((l,u)=>u.total-l.total).find(l=>l.total>0)?.field??null,i=[{type:"stat",label:"Items",agg:"count"}];for(let l of r){let u=Ne(l.key);i.push({type:"stat",metric:l.key,agg:u?"avg":"sum",label:u?`Avg ${l.label.toLowerCase()}`:l.label})}return a&&i.push({type:"line",x:a.key,y:o?.key,agg:"sum",title:o?`${o.label} by day`:"Items by day"}),s&&i.push({type:"donut",groupBy:s.key,title:s.label}),i.push({type:"table",columns:n.map(l=>l.key)}),{version:1,widgets:i}}var ue=6,de=6,pe=4,qe={stat:{w:1,h:1},chart:{w:2,h:2},block:{w:6,h:2}},Ht=e=>Math.max(1,Math.min(6,Math.round(e))),Et=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 me(e){return qe[e]}function K(e,t,n){let r=qe[e];return{w:t===void 0?r.w:Ht(t),h:n===void 0?r.h:Et(n)}}function X(e){let t=[],n=[],r=(o,i,l,u)=>{if(o<0||o+l>6)return!1;for(let d=0;d<u;d+=1){let m=n[i+d];if(m){for(let p=0;p<l;p+=1)if(m[o+p])return!1}}return!0},s=(o,i,l,u)=>{for(let d=0;d<u;d+=1){let m=n[i+d]??[];for(let p=0;p<l;p+=1)m[o+p]=!0;n[i+d]=m}},a=(o,i)=>{for(let l=0;;l+=1)for(let u=0;u+o<=6;u+=1)if(r(u,l,o,i))return{gx:u,gy:l}};for(let o of e){let i=K(W(o.kind),o.w,o.h),u=o.gx!==void 0&&o.gy!==void 0&&r(o.gx,o.gy,i.w,i.h)&&o.gx!==void 0&&o.gy!==void 0?{gx:o.gx,gy:o.gy}:a(i.w,i.h);s(u.gx,u.gy,i.w,i.h),t.push({widget:o,gx:u.gx,gy:u.gy,w:i.w,h:i.h})}return t}function ge(e){let t=[],n=[];for(let r of e)W(r.kind)==="block"?n.push(r):t.push(r);return{tiles:X(t),blocks:n}}var Be=new Set(["service","order","end_user_id"]),fe=e=>typeof e=="number"?e:Number(e)||0,Ve=e=>e==null?"":String(e);function ye(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 n=t.reduce((r,s)=>r+s,0);return e==="avg"?Math.round(n/t.length*100)/100:n}function Mt(e,t,n,r){let s=new Map;for(let a of e){let o=new Date(Ve(a.data[t]));if(Number.isNaN(o.getTime()))continue;let i=o.toISOString().slice(0,10),l=s.get(i)??[];l.push(n?fe(a.data[n]):1),s.set(i,l)}return[...s.entries()].sort((a,o)=>a[0]<o[0]?-1:1).map(([a,o])=>({label:new Date(`${a}T00:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"}),value:n?ye(r,o):o.length}))}function Wt(e,t,n,r="sum"){let s=new Map;for(let a of e){let o=Ve(a.data[t]).trim();if(!o)continue;let i=s.get(o)??[];i.push(n?fe(a.data[n]):1),s.set(o,i)}return[...s.entries()].map(([a,o])=>({label:a,value:n?ye(r,o):o.length})).sort((a,o)=>o.value-a.value)}function $t(e,t,n,r){switch(e.type){case"stat":{let s=e.metric?t.get(e.metric):void 0;if(e.metric&&!s)return null;if(!s)return{kind:"stat",label:e.label??"Items",value:r.length};let a=r.map(o=>fe(o.data[s.key]));return{kind:"stat",label:e.label??s.label,value:ye(e.agg??"sum",a)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let s=Mt(r,e.x,e.y,e.agg??"sum");return s.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:s}}case"donut":{if(!t.has(e.groupBy))return null;let s=Wt(r,e.groupBy,e.metric,e.agg??"sum");return s.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:s}}case"table":{let s=e.columns?e.columns.map(a=>t.get(a)).filter(a=>a!==void 0&&!Be.has(a.key)):n;return s.length===0?null:{kind:"table",title:e.title,columns:s,rows:r}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function be(e,t,n,r={}){let s=new Map,a=l=>({byKey:new Map(l.fields.map(u=>[u.key,u])),cols:l.fields.filter(u=>!Be.has(u.key)),rows:l.rows}),o=a({fields:t,rows:n});for(let[l,u]of Object.entries(r))s.set(l,a(u));let i=[];for(let l of e.widgets){let u=l.type==="text"?void 0:l.source,d=u?s.get(u):o;if(!d)continue;let m=$t(l,d.byKey,d.cols,d.rows);m&&i.push({...m,w:l.w,h:l.h,gx:l.gx,gy:l.gy})}return i}var Ot=new Set(["sum","avg","count","min","max","last"]),je=e=>typeof e=="string"&&Ot.has(e)?e:void 0,h=e=>typeof e=="string"&&e!==""?e:void 0,$=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,O=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0,D=e=>typeof e=="number"&&e>=0?Math.round(e):void 0;function Ft(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",source:h(t.source),label:h(t.label),metric:h(t.metric)??h(t.column),agg:je(t.agg),w:$(t.w),h:O(t.h),gx:D(t.gx),gy:D(t.gy)};case"line":case"bar":{let n=h(t.x);return n?{type:t.type,source:h(t.source),title:h(t.title),x:n,y:h(t.y)??h(t.column),agg:je(t.agg),w:$(t.w),h:O(t.h),gx:D(t.gx),gy:D(t.gy)}:null}case"donut":{let n=h(t.groupBy)??h(t.column);return n?{type:"donut",source:h(t.source),title:h(t.title),groupBy:n,w:$(t.w),h:O(t.h),gx:D(t.gx),gy:D(t.gy)}:null}case"table":{let n=Array.isArray(t.columns)?t.columns.filter(r=>typeof r=="string"):void 0;return{type:"table",source:h(t.source),title:h(t.title),columns:n,w:$(t.w),h:O(t.h),gx:D(t.gx),gy:D(t.gy)}}case"text":{let n=h(t.body);return n?{type:"text",title:h(t.title),body:n,w:$(t.w),h:O(t.h),gx:D(t.gx),gy:D(t.gy)}:null}default:return null}}function he(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 n=t.widgets;if(!Array.isArray(n))return null;let r=n.map(Ft).filter(a=>a!==null);if(r.length===0)return null;let s=t.version;return{version:typeof s=="number"?s:1,title:h(t.title),widgets:r}}function Y(e){if(typeof e=="string")return e?{kind:"file",value:e}:null;if(e&&typeof e=="object"){let t=e,n=typeof t.value=="string"?t.value:"",r=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",s=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return n?{kind:r,value:n,...s?{v:s}:{}}:null}return null}function Z(e){let t=new Map;for(let n of e){let r=n.v??1,s=t.get(r)??[];s.push(n),t.set(r,s)}return[...t.entries()].sort(([n],[r])=>n-r).map(([n,r])=>({v:n,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(Y).filter(s=>s!==null)}catch{}let n=String(e.file??"");return n?[{kind:"file",value:n}]:[]}function we(e,t,n,r=""){let a=Z(e).find(i=>i.v===t)?.items??[],o=a.filter(i=>i.kind==="file").map(i=>n.get(i.value)??"");return a.some(i=>i.kind==="table")&&o.push(r),o.length===0||o.some(i=>i==="")?"awaiting":o.some(i=>i==="revise")?"revise":"accepted"}function Pe(e){return Number(e.published_version)||0}function ee(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function Se(e){try{let t=JSON.parse(e);if(Array.isArray(t.columns)&&Array.isArray(t.rows)&&t.columns.length){let n=t.columns.map((a,o)=>({key:typeof a.key=="string"&&a.key?a.key:typeof a.id=="string"&&a.id?a.id:`column_${o+1}`,label:typeof a.label=="string"?a.label:"",type:ee(a.type),...a.clientEditable===!0?{clientEditable:!0}:{}})),r=t.rows.map((a,o)=>({id:typeof a.id=="string"&&a.id?a.id:`row_${o}`,cells:a.cells&&typeof a.cells=="object"?a.cells:{}})),s=typeof t.name=="string"?t.name:void 0;return{columns:n,rows:r,...s?{name:s}:{}}}}catch{}return null}function ve(e){return e==null?"":String(e)}function ke(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function F(){return{cells:{},verdict:"",comment:""}}function Te(e){if(typeof e!="string"||e.trim()==="")return F();try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t)){let n=t;return{cells:n.cells&&typeof n.cells=="object"?n.cells:n,verdict:n.verdict==="accepted"||n.verdict==="revise"?n.verdict:"",comment:typeof n.comment=="string"?n.comment:""}}}catch{}return F()}function Ce(e,t,n){if(e.clientEditable){let r=n.cells[t.id];if(r&&e.key in r)return r[e.key]}return t.cells[e.key]}function Re(e,t,n,r){return{...e,cells:{...e.cells,[t]:{...e.cells[t]??{},[n]:r}}}}function De(e,t,n){return{...e,verdict:t,comment:n}}function Ie(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 H=class extends Error{code;status;constructor(t,n,r){super(n),this.name="CreditRefused",this.code=t,this.status=r}},_=class extends H{credits;balance;short;constructor(t,n){super("insufficient_credits",t,402),this.name="InsufficientCredits",this.credits=n.credits,this.balance=n.balance,this.short=n.short}},_t=/\/+$/,Lt="/api/v1/end-user",re="Pre-payment",oe="After-payment";function Ge(e,t){if(e<=0)return[];let n=t&&typeof t.upfront=="number"&&Number.isFinite(t.upfront)?Math.max(0,Math.min(t.upfront,e)):e,r=Math.round((e-n)*100)/100,s=[];return n>0&&s.push({label:re,amount:n}),r>0&&s.push({label:oe,amount:r}),s}var ne=e=>e.status!=="paid"&&e.asked!==!1,Qe=(e,t)=>{let n=typeof t=="number"&&Number.isFinite(t)&&t>0?t:1;return!Number.isFinite(e)||e<=0?0:Math.ceil(e*n)},te=e=>{let t=e.label.trim().toLowerCase();return t===re.toLowerCase()?0:t===oe.toLowerCase()?2:1},ze=(e,t,n)=>{let r=t.filter(p=>p.order===n),s=p=>p.reduce((c,g)=>c+g.amount,0),a=s(r),o=s(r.filter(p=>p.status==="paid")),i=e.value>0,l=[...r].sort((p,c)=>te(p)!==te(c)?te(p)-te(c):(p.dueDate||p.paidAt).localeCompare(c.dueDate||c.paidAt)),u=l.filter(ne),d=l.filter(p=>p.status!=="paid"&&!ne(p)),m=a>0?s(u):e.value-o;return{value:e.value,priced:i,billed:a,paid:o,due:Math.max(0,m),scheduled:s(d),lines:l,asked:u,upcoming:d,awaitingPayment:i&&o<=0}},Ut=e=>{let{credits:t,balance:n,short:r}=e;return typeof t!="number"||typeof n!="number"||typeof r!="number"||!(Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(r))?null:{credits:t,balance:n,short:r}},Je=e=>{let t=e.baseUrl.replace(_t,""),n=()=>typeof e.token=="function"?e.token():e.token,r=async(s,a={method:"GET"})=>{try{let o=await fetch(`${t}${Lt}${s}`,{method:a.method,headers:{"content-type":"application/json",authorization:`Bearer ${await n()}`},...a.body===void 0?{}:{body:JSON.stringify(a.body)}});if(!o.ok){let i=await o.json().catch(()=>({})),l=i.message??`${a.method} ${s} \u2192 ${String(o.status)}`,u=Ut(i);throw o.status===402&&i.error==="insufficient_credits"&&u?new _(l,u):new H(i.error??"request_failed",l,o.status)}return await o.json()}catch(o){throw o instanceof H?o:w(o)}};return{wallet:()=>r("/credits"),history:()=>r("/credits/history"),topup:s=>r("/credits/checkout",{method:"POST",body:{packId:s}}),checkout:s=>r("/shop/checkout",{method:"POST",body:s}),payments:()=>r("/payments"),paymentMethods:()=>r("/payment-methods"),markPaymentSent:(s,a)=>r(`/payments/${encodeURIComponent(s)}/sent`,{method:"POST",body:{reference:a??""}}),payWithCredits:s=>r(`/payments/${encodeURIComponent(s)}/pay-with-credits`,{method:"POST",body:{}}),inquiryQuote:s=>r(`/inquiries/${encodeURIComponent(s)}/quote`),acceptInquiry:(s,a)=>r(`/inquiries/${encodeURIComponent(s)}/accept`,{method:"POST",body:{version:a}}),enquire:(s,a,o)=>r("/shop/enquire",{method:"POST",body:{productId:s,answers:a,name:o??""}})}};var Nt=/\/+$/,E="/api/v1/end-user",M=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function qt(e){let t="";for(let r=0;r<e.length;r+=32768)t+=String.fromCharCode(...e.subarray(r,r+32768));return btoa(t)}var Ke=e=>{let t=e.baseUrl.replace(Nt,""),n=()=>typeof e.token=="function"?e.token():e.token,r=async()=>({"content-type":"application/json",authorization:`Bearer ${await n()}`}),s=async(o,i)=>{try{let l=await fetch(`${t}${E}${o}`,{method:i.method,headers:await r(),...i.body===void 0?{}:{body:JSON.stringify(i.body)}});if(l.status===409){let u=await l.json().catch(()=>({}));throw new M(u.message??"Someone else saved this first.")}if(!l.ok){let u=await l.text().catch(()=>""),d=`${i.method} ${o} \u2192 ${String(l.status)}`;try{let m=JSON.parse(u);m.message&&(d=m.message)}catch{d=u?`${d}: ${u}`:d}throw w({error:d})}return await l.json()}catch(l){throw l instanceof M?l:w(l)}},a=o=>`/tables/${encodeURIComponent(o)}`;return{listTables:async()=>(await v(`${t}${E}/tables`,await r())).tables,listRows:async(o,i)=>await v(`${t}${E}${a(o)}/rows?limit=${String(i??100)}`,await r()),insertRow:async(o,i)=>{let{rowIds:l}=await s(`${a(o)}/rows`,{method:"POST",body:{rows:[i]}}),u=l[0];if(!u)throw w(new Error("The row was not created."));return u},patchRow:async(o,i,l)=>(await s(`${a(o)}/rows/${encodeURIComponent(i)}`,{method:"PATCH",body:l})).updated,deleteRow:async(o,i)=>(await s(`/${encodeURIComponent(o)}/${encodeURIComponent(i)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await v(`${t}${E}/tables/files/rows?limit=200`,await r())).rows.map(i=>({id:i.rowId,filename:String(i.data.filename??""),source:String(i.data.source??"client"),campaign:String(i.data.campaign??""),size:typeof i.data.size=="number"?i.data.size:0,createdAt:i.createdAt})),uploadFile:async(o,i)=>{let l=new Uint8Array(await o.arrayBuffer());return await s("/files",{method:"POST",body:{filename:o.name,mime:o.type||"application/octet-stream",data:qt(l),...i===void 0?{}:{message:i}}})},fileLink:async o=>await v(`${t}${E}/files/${encodeURIComponent(o)}/url`,await r()),deleteFile:async o=>(await s(`/files/${encodeURIComponent(o)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await v(`${t}${E}/documents`,await r())).documents,readDocument:async o=>(await v(`${t}${E}/documents/${encodeURIComponent(o)}`,await r())).document,saveDocument:async(o,i)=>await s(`/documents/${encodeURIComponent(o)}`,{method:"PATCH",body:i})}};var Bt=/\/+$/,Vt="/api/v1/end-user",Xe=e=>{let t=e.baseUrl.replace(Bt,""),n=async(r,s)=>{let a;try{a=await fetch(`${t}${Vt}${r}`,s===void 0?{}:{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)})}catch(o){throw w(o)}if(a.status===429)throw w({error:"rate_limited",retryable:!0});if(!a.ok)throw w({error:`shop_request_failed_${String(a.status)}`});try{return await a.json()}catch(o){throw w(o)}};return{listProducts:async()=>{let r=await n(`/shop/products?publishable_key=${encodeURIComponent(e.publishableKey)}`);return{products:r.products.map(s=>({...s,currency:typeof s.currency=="string"?s.currency:""})),truncated:r.truncated===!0,enquiryForm:Array.isArray(r.enquiryForm)?r.enquiryForm:[]}},apply:async r=>await n("/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}:{}})}};var jt=new Set(["buy","ask"]);function Ye(e){return jt.has(e.mode)?e.mode:"ask"}var Gt={kind:"quoted"};function L(e,t){if(!t)return e.toLocaleString();if(t.toLowerCase()==="credits")return`${e.toLocaleString()} ${e===1?"credit":"credits"}`;let n=Number.isInteger(e)?0:2;try{return new Intl.NumberFormat(void 0,{style:"currency",currency:t,minimumFractionDigits:n,maximumFractionDigits:n}).format(e)}catch{return`${t} ${e.toLocaleString()}`}}function Ze(e,t){let n=/^[a-z]+$/i.test(t)&&!t.endsWith("s")?"s":"";return`${e.toLocaleString()} ${t}${n}`}function Ae(e,t){return e.kind==="quoted"?"Priced on enquiry":e.kind==="flat"?L(e.price,t):`${L(e.unitPrice,t)} per ${e.unitStep===1?e.unit:Ze(e.unitStep,e.unit)}`}function et(e){let t=e.currency,n=e.pricing;if(n.kind!=="variants")return Ae(n,t);let r=n.variants.map(s=>s.price).filter(s=>typeof s=="number");return r.length>0?`From ${L(Math.min(...r),t)}`:"Priced on enquiry"}function tt(e,t){if(e.kind!=="variants")return e;let n=e.variants.find(r=>r.name===t);return typeof n?.price=="number"?{kind:"flat",price:n.price}:Gt}function nt(e,t){return e.kind==="flat"?e.price:e.kind==="per_unit"?e.unitPrice*Math.ceil(t/Math.max(e.unitStep,1)):null}function rt(e,t){let n=t.kind==="per_unit"?Math.max(t.unitStep,1):1;return{min:Math.max(e.minQty??n,n),max:e.maxQty??null,step:n}}function ot(e,t){let n=e.variants?.find(r=>r.name===t);return n&&n.includes.length>0?n.includes:e.includes}function st(e,t){let n=[];for(let r of e){let s=t(r).trim();s&&!n.includes(s)&&n.push(s)}return n}function it(e,t,n,r){let s=t?`${e.name} \u2014 ${t}`:e.name,a=n.kind==="per_unit"?`, ${Ze(r,n.unit)}`:"";return`I'd like to buy ${s}${a}. How do I go ahead?`}function at(e){return e?(e&&typeof e=="object"&&"error"in e?String(e.error):"")==="rate_limited"?"That's a lot of looking at once \u2014 give it a moment, then reload.":"The shop isn't loading right now. Please try again shortly.":null}var A=require("react"),lt=e=>{let[t,n]=(0,A.useState)(null),[r,s]=(0,A.useState)(!0),[a,o]=(0,A.useState)(null),i=(0,A.useCallback)(async()=>{try{n(await e.wallet()),o(null)}catch{o("Couldn't read your balance just now.")}finally{s(!1)}},[e]),l=(0,A.useCallback)(()=>{i().catch(()=>{})},[i]);return(0,A.useEffect)(()=>(l(),window.addEventListener("focus",l),()=>{window.removeEventListener("focus",l)}),[l]),{wallet:t,loading:r,failure:a,refresh:l}};var C=require("react"),Qt=e=>e&&typeof e=="object"&&typeof e.error=="string"?e.error:e instanceof Error?e.message:"shop_unavailable",ut=e=>{let[t,n]=(0,C.useState)([]),[r,s]=(0,C.useState)([]),[a,o]=(0,C.useState)(!1),[i,l]=(0,C.useState)(!0),[u,d]=(0,C.useState)(null),[m,p]=(0,C.useState)(0);(0,C.useEffect)(()=>{let g=!0;return l(!0),e.listProducts().then(y=>{g&&(n(y.products),s(y.enquiryForm),o(y.truncated),d(null))}).catch(y=>{g&&d(Qt(y))}).finally(()=>{g&&l(!1)}),()=>{g=!1}},[e,m]);let c=(0,C.useCallback)(()=>p(g=>g+1),[]);return{products:t,enquiryForm:r,truncated:a,loading:i,error:u,reload:c}};var k=require("react"),dt="greeting";function He(e,t){if(e.some(a=>a.id===t.id))return e;let n=e.filter(a=>a.id!==dt),r=a=>a.author==="client"==(t.author==="client");return[...n.filter(a=>!(a.pending&&r(a)&&a.text===t.text)),t]}var pt=(e,t)=>{let[n,r]=(0,k.useState)([]),[s,a]=(0,k.useState)(""),[o,i]=(0,k.useState)(!1),[l,u]=(0,k.useState)(null),d=(0,k.useRef)(0),m=t?.pollMs??2e3;(0,k.useEffect)(()=>{let c=!0;return e.getInfo().then(g=>{c&&g.greeting&&r(y=>y.length===0?[{id:dt,cursor:"",author:"agent",text:g.greeting}]:y)}).catch(()=>{}),()=>{c=!1}},[e]),(0,k.useEffect)(()=>e.subscribe?.({onMessage:c=>r(g=>He(g,c)),onError:c=>u(c.error),onHealthy:()=>u(null)},{intervalMs:m}),[e,m]);let p=(0,k.useCallback)(()=>{let c=s.trim();if(!c||o)return;a(""),u(null),i(!0),d.current+=1;let g=`pending-${d.current}`,y={id:g,cursor:"",author:"client",text:c,pending:!0};r(b=>[...b,y]),e.sendMessage(c).then(b=>{i(!1),b.reply.trim()&&r(f=>f.some(I=>!I.pending&&I.author!=="client"&&I.text===b.reply)?f:(d.current+=1,[...f,{id:`pending-agent-${d.current}`,cursor:"",author:"agent",text:b.reply,pending:!0}]))}).catch(b=>{u(b instanceof Error?b.message:"send_failed"),i(!1),r(R=>R.filter(f=>f.id!==g)),a(R=>R||c)})},[s,o,e]);return{messages:n,input:s,setInput:a,send:p,sending:o,error:l}};0&&(module.exports={Chat,CreditRefused,GRID_COLS,GRID_MAX_COLS,GRID_MAX_ROWS,HolaProvider,InsufficientCredits,PortalConflict,QUOTE_BALANCE_LABEL,QUOTE_DEPOSIT_LABEL,bandOfKind,bandOfType,buyRequestText,cellValue,createApiTransport,createHolaClient,createPortalCredits,createPortalData,createPortalShop,createWidgetTransport,creditsOfMoney,deliverableCellText,deliverableStatus,deriveFields,emptyTableResponses,facetValues,footprintOf,footprintWith,formatDeliverableDate,groupDeliverableVersions,includesFor,inferSpec,isDeliverableChecked,mergeMessage,modeOf,money,normalizeDeliverableColType,normalizeDeliverableItem,orderBilling,parseDashboardSpec,parseDeliverableItems,parseDeliverableTable,parseTableResponses,paymentAsked,placeWidgets,priceFor,priceLabel,publishedVersionOf,quantityRange,quoteSchedule,renderModel,setResponse,setTableReview,shelfPriceLabel,shelfProblem,splitLayout,textDeltaOf,thinkingDeltaOf,toolEventOf,totalFor,useArtifactUrl,useChat,useCredits,useHolaClient,useShop,useThread});
|
package/dist/index.d.cts
CHANGED
|
@@ -627,6 +627,37 @@ declare class CreditRefused extends Error {
|
|
|
627
627
|
readonly status: number;
|
|
628
628
|
constructor(code: string, message: string, status: number);
|
|
629
629
|
}
|
|
630
|
+
/**
|
|
631
|
+
* "You cannot cover this" — carrying the three numbers that make it a QUOTE rather than a refusal.
|
|
632
|
+
*
|
|
633
|
+
* A SUBCLASS, not a second class, and that is load-bearing: every caller in every portal already
|
|
634
|
+
* branches on `instanceof CreditRefused` and reads `.code`, and a sibling class would fall out of
|
|
635
|
+
* all of them at once — the exact failure the comment above `CreditRefused` warns about, arriving
|
|
636
|
+
* from the other direction. Anything that handled the refusal before goes on handling it; the three
|
|
637
|
+
* numbers are additive.
|
|
638
|
+
*
|
|
639
|
+
* `short` is `credits - balance`, computed server-side, because the two figures it is derived from
|
|
640
|
+
* are read there under the same lock the debit takes. A portal recomputing it from a balance it
|
|
641
|
+
* fetched a minute ago would show a shortfall that has already been topped up.
|
|
642
|
+
*
|
|
643
|
+
* Minted ONLY when the server actually sent the numbers. Two surfaces answer 402
|
|
644
|
+
* `insufficient_credits` — settling a bill and buying from the shelf — and only the first sends
|
|
645
|
+
* them, so a shop refusal stays a plain `CreditRefused` rather than one carrying three zeros
|
|
646
|
+
* dressed as facts.
|
|
647
|
+
*/
|
|
648
|
+
declare class InsufficientCredits extends CreditRefused {
|
|
649
|
+
/** What the line costs, in credits. ROUNDED UP: see `creditsOfMoney`. */
|
|
650
|
+
readonly credits: number;
|
|
651
|
+
/** What they have right now. */
|
|
652
|
+
readonly balance: number;
|
|
653
|
+
/** The difference, and the size of the top-up that would fix it. */
|
|
654
|
+
readonly short: number;
|
|
655
|
+
constructor(message: string, figures: {
|
|
656
|
+
credits: number;
|
|
657
|
+
balance: number;
|
|
658
|
+
short: number;
|
|
659
|
+
});
|
|
660
|
+
}
|
|
630
661
|
/** One pack on sale: what it grants, and what it costs in real money.
|
|
631
662
|
*
|
|
632
663
|
* `credits` and `price` are different units and the pair is the point — 500 credits for $99 is a
|
|
@@ -985,6 +1016,35 @@ type PortalCredits = {
|
|
|
985
1016
|
claimed: boolean;
|
|
986
1017
|
status: string;
|
|
987
1018
|
}>;
|
|
1019
|
+
/**
|
|
1020
|
+
* Settle one payment line out of the customer's own prepaid balance.
|
|
1021
|
+
*
|
|
1022
|
+
* THE THIRD DOOR ONTO ONE TRANSITION, and the only self-service one that works. A transfer
|
|
1023
|
+
* settles in a bank this product cannot see and needs an operator to confirm it; `pay_url` has no
|
|
1024
|
+
* writer anywhere, so the card button never renders. This one closes itself — the balance moves,
|
|
1025
|
+
* the line flips to paid, the work starts — and it does NOT invent a second notion of paid:
|
|
1026
|
+
* `payments.status` stays the one definition, which is what keeps the console's badge, the
|
|
1027
|
+
* worklist and this page telling one story about the same order.
|
|
1028
|
+
*
|
|
1029
|
+
* `paymentId` names a LINE, not an order. That is what lets somebody pay the deposit today and
|
|
1030
|
+
* the balance on delivery, and it is what the server's idempotency key is cut from: a double tap
|
|
1031
|
+
* on a slow connection takes the credits once.
|
|
1032
|
+
*
|
|
1033
|
+
* Show the customer `creditsOfMoney(line.amount, wallet.bookRate)` before they press it. The
|
|
1034
|
+
* rounding is up, it is applied server-side, and a page that only ever showed the money figure
|
|
1035
|
+
* would take a credit more than the number on screen.
|
|
1036
|
+
*
|
|
1037
|
+
* REFUSALS, and each wants a different sentence:
|
|
1038
|
+
*
|
|
1039
|
+
* - `InsufficientCredits` (402) — they cannot cover it. Not a fault: it is a quote for a top-up,
|
|
1040
|
+
* carrying what the line costs, what they hold and the difference. The other ways to pay are
|
|
1041
|
+
* still on screen and must stay there.
|
|
1042
|
+
* - `CreditRefused` with `credits_not_sold` (409) — this company does not price in credits at
|
|
1043
|
+
* all. A portal should never have offered the option; treat it as the wallet being stale.
|
|
1044
|
+
* - `CreditRefused` with `rate_limited` (429) — too many in a row. Wait.
|
|
1045
|
+
* - Anything else is ours and the credits are safe; the sentence is the server's.
|
|
1046
|
+
*/
|
|
1047
|
+
payWithCredits(paymentId: string): Promise<PaidWithCredits>;
|
|
988
1048
|
};
|
|
989
1049
|
/** One line on a customer's bill. Mirrors the projection holaapp-backend's `customerPayment`
|
|
990
1050
|
* emits — an allowlist, not the stored row. */
|
|
@@ -1008,7 +1068,40 @@ type CustomerPayment = {
|
|
|
1008
1068
|
* money is what changes `status`. */
|
|
1009
1069
|
claimedAt: string;
|
|
1010
1070
|
reference: string;
|
|
1071
|
+
/**
|
|
1072
|
+
* Whether the customer is being ASKED for this line right now, as opposed to merely shown it as
|
|
1073
|
+
* part of the schedule they agreed to.
|
|
1074
|
+
*
|
|
1075
|
+
* RAISED IS NOT OWED. The whole schedule is written the moment the order is — that is what makes
|
|
1076
|
+
* the contract complete and the terms visible — but a balance falling due ON DELIVERY is not owed
|
|
1077
|
+
* while the work is still being done. With only `status` to go on, a portal drew a bank-transfer
|
|
1078
|
+
* form for the balance the instant the deposit landed: account numbers and an "I've sent the
|
|
1079
|
+
* transfer" button for money nobody was owed yet.
|
|
1080
|
+
*
|
|
1081
|
+
* DERIVED SERVER-SIDE, and the rule stays there. It is structural (which label, and whether the
|
|
1082
|
+
* operator has requested it) rather than a stamp, and a second copy of it here is a second copy
|
|
1083
|
+
* that can disagree with the operator's console about what a customer owes. Read it, never
|
|
1084
|
+
* recompute it — `paymentAsked` below is the whole of the reading.
|
|
1085
|
+
*
|
|
1086
|
+
* OPTIONAL because a portal is pinned to a published SDK and talks to whatever backend the
|
|
1087
|
+
* operator is on. Absent means the backend predates the field; see `paymentAsked` for why that
|
|
1088
|
+
* has to read as asked rather than as scheduled.
|
|
1089
|
+
*/
|
|
1090
|
+
asked?: boolean;
|
|
1011
1091
|
};
|
|
1092
|
+
/**
|
|
1093
|
+
* Whether this line has a pay surface — the transfer details, the credits button, the claim form.
|
|
1094
|
+
*
|
|
1095
|
+
* ABSENT READS AS ASKED, and the direction is not a coin toss. A backend older than the field sends
|
|
1096
|
+
* nothing, and reading that as "scheduled" would take the pay surface off every line in the portal
|
|
1097
|
+
* at once — a customer who owes a deposit with no way to pay it, which is worse than the bug
|
|
1098
|
+
* `asked` was added to fix. Reading it as asked reproduces exactly the behaviour that backend
|
|
1099
|
+
* already has.
|
|
1100
|
+
*
|
|
1101
|
+
* A settled line is never asked for, whatever the flag says: the server agrees, and stating it here
|
|
1102
|
+
* as well means a portal cannot draw a payment form over a receipt because one stale row disagreed.
|
|
1103
|
+
*/
|
|
1104
|
+
declare const paymentAsked: (p: CustomerPayment) => boolean;
|
|
1012
1105
|
/** How to pay this company by transfer. Null when the operator has published nothing you could
|
|
1013
1106
|
* actually send money to — no details is not an empty form, it is no transfer option. */
|
|
1014
1107
|
type TransferDetails = {
|
|
@@ -1019,6 +1112,56 @@ type TransferDetails = {
|
|
|
1019
1112
|
swift: string;
|
|
1020
1113
|
note: string;
|
|
1021
1114
|
};
|
|
1115
|
+
/**
|
|
1116
|
+
* What settling a bill from the balance came back as.
|
|
1117
|
+
*
|
|
1118
|
+
* BOTH ARMS SAY `paid: true`, and that is the whole shape of this type. The second one is the line
|
|
1119
|
+
* having already been settled — by an earlier tap of the same button on a slow connection, by the
|
|
1120
|
+
* operator marking a transfer while the customer was looking at the page, or by a retry whose first
|
|
1121
|
+
* attempt got further than the caller saw. From the customer's side the thing they wanted is TRUE,
|
|
1122
|
+
* so it is not an error and must not be drawn as one; a portal that showed "couldn't pay that" over
|
|
1123
|
+
* a bill that is paid would send somebody to pay it a second time.
|
|
1124
|
+
*
|
|
1125
|
+
* The zeros on that arm are LITERAL because they are not readings. Nothing was taken (`credits: 0`)
|
|
1126
|
+
* and nobody looked at the balance (`balance: 0`) — the row was already settled before a debit was
|
|
1127
|
+
* attempted. Re-read the wallet rather than printing that 0 at anybody.
|
|
1128
|
+
*/
|
|
1129
|
+
type PaidWithCredits =
|
|
1130
|
+
/** Settled just now. `balance` is what is LEFT, after this line. */
|
|
1131
|
+
{
|
|
1132
|
+
paid: true;
|
|
1133
|
+
alreadyPaid?: false;
|
|
1134
|
+
credits: number;
|
|
1135
|
+
balance: number;
|
|
1136
|
+
}
|
|
1137
|
+
/** It was already settled. Neither number is a reading — see above. */
|
|
1138
|
+
| {
|
|
1139
|
+
paid: true;
|
|
1140
|
+
alreadyPaid: true;
|
|
1141
|
+
credits: 0;
|
|
1142
|
+
balance: 0;
|
|
1143
|
+
};
|
|
1144
|
+
/**
|
|
1145
|
+
* What a MONEY figure costs in credits, at the company's book rate.
|
|
1146
|
+
*
|
|
1147
|
+
* A MIRROR of the server's `creditsOfMoney`, deliberately, and here for the same reason
|
|
1148
|
+
* `quoteSchedule` is: the customer has to be shown the credit figure BEFORE they press the button,
|
|
1149
|
+
* and the only figure worth showing is the one that will actually be taken.
|
|
1150
|
+
*
|
|
1151
|
+
* IT ROUNDS UP, and that is why showing it matters rather than being a nicety. The ledger moves in
|
|
1152
|
+
* whole credits, so a $10.50 line at rate 1 costs 11 — more than the exact conversion of the money
|
|
1153
|
+
* on the row. Up costs the customer at most one credit and never leaves the operator short, which
|
|
1154
|
+
* is the only direction that is safe to apply without asking; what makes it HONEST is that they
|
|
1155
|
+
* read the number first.
|
|
1156
|
+
*
|
|
1157
|
+
* Only good for a line that is still due. A settled one carries what was actually taken, stamped on
|
|
1158
|
+
* the row at the moment it was paid — the book rate is a setting an operator can change, and a
|
|
1159
|
+
* receipt re-derived through today's rate is a receipt that rewrites itself.
|
|
1160
|
+
*/
|
|
1161
|
+
declare const creditsOfMoney: (amount: number,
|
|
1162
|
+
/** Credits per one unit of currency — `CreditWallet.bookRate`. Absent or nonsense reads as 1,
|
|
1163
|
+
* which is what `normaliseBookRate` does server-side. */
|
|
1164
|
+
bookRate?: number) => number;
|
|
1022
1165
|
/** Where one order stands financially, and therefore whether it has started. */
|
|
1023
1166
|
type OrderBilling = {
|
|
1024
1167
|
/** The agreed contract value. 0 when nobody priced it — not the same as free, which is what
|
|
@@ -1029,12 +1172,33 @@ type OrderBilling = {
|
|
|
1029
1172
|
* record of what was billed, not a derivation of the contract. */
|
|
1030
1173
|
billed: number;
|
|
1031
1174
|
paid: number;
|
|
1032
|
-
/**
|
|
1033
|
-
*
|
|
1034
|
-
*
|
|
1175
|
+
/**
|
|
1176
|
+
* What the customer is being ASKED FOR right now. Never negative.
|
|
1177
|
+
*
|
|
1178
|
+
* NOT "everything raised and unsettled", which is the figure this used to be and is a bill the
|
|
1179
|
+
* customer does not owe: a deposit paid and a balance falling due on delivery came to "$4,000
|
|
1180
|
+
* due" over an order whose work was under way and whose next payment nobody had requested. Only
|
|
1181
|
+
* `asked` lines are counted — see `CustomerPayment.asked`.
|
|
1182
|
+
*
|
|
1183
|
+
* Falls back to the whole contract value when the order is priced and NOTHING has been raised
|
|
1184
|
+
* yet — the ordinary case the moment an order is written, where the customer is owed a figure
|
|
1185
|
+
* rather than a shrug. Deliberately not applied when lines exist but none is asked for: that is
|
|
1186
|
+
* a real state (all settled, or the rest merely scheduled) and answering it with the contract
|
|
1187
|
+
* value would re-bill a paid order.
|
|
1188
|
+
*/
|
|
1035
1189
|
due: number;
|
|
1036
|
-
/**
|
|
1190
|
+
/** Raised, unsettled, and NOT being asked for yet — the rest of the schedule. Listed so a
|
|
1191
|
+
* customer can see the terms they agreed to; never given a payment form. */
|
|
1192
|
+
scheduled: number;
|
|
1193
|
+
/** Every line, in SCHEDULE order: the deposit, then any milestones, then the balance — settled
|
|
1194
|
+
* or not. A bill's history reads forwards; what is owed *now* is `asked`, not a sort. */
|
|
1037
1195
|
lines: CustomerPayment[];
|
|
1196
|
+
/** The lines with a pay surface: unsettled and asked for, in the order above. What a portal draws
|
|
1197
|
+
* a transfer form, a credits button or a claim under — and nothing else. */
|
|
1198
|
+
asked: CustomerPayment[];
|
|
1199
|
+
/** Raised, unsettled, and merely COMING. Listed with their dates and no way to pay them: asking
|
|
1200
|
+
* for money against work nobody has handed over is the bug `asked` exists to prevent. */
|
|
1201
|
+
upcoming: CustomerPayment[];
|
|
1038
1202
|
/**
|
|
1039
1203
|
* Whether the work is waiting on money — and so has not started.
|
|
1040
1204
|
*
|
|
@@ -1046,14 +1210,6 @@ type OrderBilling = {
|
|
|
1046
1210
|
*/
|
|
1047
1211
|
awaitingPayment: boolean;
|
|
1048
1212
|
};
|
|
1049
|
-
/**
|
|
1050
|
-
* Fold an order's payment lines into where it stands.
|
|
1051
|
-
*
|
|
1052
|
-
* In the SDK rather than in each portal for the reason the whole of this file is: every portal that
|
|
1053
|
-
* shows a bill needs exactly this, and the second one to write it by hand would inherit nothing the
|
|
1054
|
-
* first one learned. Pure, so the arithmetic that decides whether somebody is told "this hasn't
|
|
1055
|
-
* started" is testable without a server.
|
|
1056
|
-
*/
|
|
1057
1213
|
declare const orderBilling: (order: {
|
|
1058
1214
|
value: number;
|
|
1059
1215
|
}, all: CustomerPayment[], orderId: string) => OrderBilling;
|
|
@@ -1405,4 +1561,4 @@ declare const useThread: (client: HolaClient, options?: {
|
|
|
1405
1561
|
pollMs?: number;
|
|
1406
1562
|
}) => UseThread;
|
|
1407
1563
|
|
|
1408
|
-
export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type ChosenPrice, type CreateHolaClientOptions, type CreditEntry, type CreditHistory, type CreditPack, CreditRefused, type CreditTotals, type CreditWallet, type CustomerPayment, type DashboardLayout, type DashboardSpec, type DataSource, type DeliverableColType, type DeliverableColumn, type DeliverableItem, type DeliverableItemKind, type DeliverableReviewState, type DeliverableRow, type DeliverableTable, type DeliverableVersion, type DonutWidget, GRID_COLS, GRID_MAX_COLS, GRID_MAX_ROWS, type HolaArtifact, type HolaAuthor, type HolaClient, type HolaCompletion, type HolaEmployeeInfo, type HolaError, type HolaIdentity, type HolaMessage, HolaProvider, type HolaStreamHandlers, type HolaSubscribeHandlers, type HolaSubscribeOptions, type HolaToolEvent, type HolaTransport, type InquiryQuote, type OrderBilling, type PendingTopup, type PlacedWidget, type Point, PortalConflict, type PortalCredits, type PortalData, type PortalDocument, type PortalDocumentSummary, type PortalField, type PortalFile, type PortalRow, type PortalRowAuthor, type PortalRowPage, type PortalShop, type PortalShopConfig, type PortalTable, type Purchased, QUOTE_BALANCE_LABEL, QUOTE_DEPOSIT_LABEL, type QuoteScheduleLine, type QuoteTerms, type QuotedLine, type ResolvedWidget, type SeriesWidget, type ShopApplication, type ShopApplyResult, type ShopFormField, type ShopInclusion, type ShopMode, type ShopPricing, type ShopProduct, type ShopShelf, type ShopVariant, type StatView, type StatWidget, type TableResponses, type TableReviewVerdict, type TableWidget, type TextWidget, type ThreadMessage, type TopupStarted, type TransferDetails, type UseChat, type UseCredits, type UseShop, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, buyRequestText, cellValue, createApiTransport, createHolaClient, createPortalCredits, createPortalData, createPortalShop, createWidgetTransport, deliverableCellText, deliverableStatus, deriveFields, emptyTableResponses, facetValues, footprintOf, footprintWith, formatDeliverableDate, groupDeliverableVersions, includesFor, inferSpec, isDeliverableChecked, mergeMessage, modeOf, money, normalizeDeliverableColType, normalizeDeliverableItem, orderBilling, parseDashboardSpec, parseDeliverableItems, parseDeliverableTable, parseTableResponses, placeWidgets, priceFor, priceLabel, publishedVersionOf, quantityRange, quoteSchedule, renderModel, setResponse, setTableReview, shelfPriceLabel, shelfProblem, splitLayout, textDeltaOf, thinkingDeltaOf, toolEventOf, totalFor, useArtifactUrl, useChat, useCredits, useHolaClient, useShop, useThread };
|
|
1564
|
+
export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type ChosenPrice, type CreateHolaClientOptions, type CreditEntry, type CreditHistory, type CreditPack, CreditRefused, type CreditTotals, type CreditWallet, type CustomerPayment, type DashboardLayout, type DashboardSpec, type DataSource, type DeliverableColType, type DeliverableColumn, type DeliverableItem, type DeliverableItemKind, type DeliverableReviewState, type DeliverableRow, type DeliverableTable, type DeliverableVersion, type DonutWidget, GRID_COLS, GRID_MAX_COLS, GRID_MAX_ROWS, type HolaArtifact, type HolaAuthor, type HolaClient, type HolaCompletion, type HolaEmployeeInfo, type HolaError, type HolaIdentity, type HolaMessage, HolaProvider, type HolaStreamHandlers, type HolaSubscribeHandlers, type HolaSubscribeOptions, type HolaToolEvent, type HolaTransport, type InquiryQuote, InsufficientCredits, type OrderBilling, type PaidWithCredits, type PendingTopup, type PlacedWidget, type Point, PortalConflict, type PortalCredits, type PortalData, type PortalDocument, type PortalDocumentSummary, type PortalField, type PortalFile, type PortalRow, type PortalRowAuthor, type PortalRowPage, type PortalShop, type PortalShopConfig, type PortalTable, type Purchased, QUOTE_BALANCE_LABEL, QUOTE_DEPOSIT_LABEL, type QuoteScheduleLine, type QuoteTerms, type QuotedLine, type ResolvedWidget, type SeriesWidget, type ShopApplication, type ShopApplyResult, type ShopFormField, type ShopInclusion, type ShopMode, type ShopPricing, type ShopProduct, type ShopShelf, type ShopVariant, type StatView, type StatWidget, type TableResponses, type TableReviewVerdict, type TableWidget, type TextWidget, type ThreadMessage, type TopupStarted, type TransferDetails, type UseChat, type UseCredits, type UseShop, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, buyRequestText, cellValue, createApiTransport, createHolaClient, createPortalCredits, createPortalData, createPortalShop, createWidgetTransport, creditsOfMoney, deliverableCellText, deliverableStatus, deriveFields, emptyTableResponses, facetValues, footprintOf, footprintWith, formatDeliverableDate, groupDeliverableVersions, includesFor, inferSpec, isDeliverableChecked, mergeMessage, modeOf, money, normalizeDeliverableColType, normalizeDeliverableItem, orderBilling, parseDashboardSpec, parseDeliverableItems, parseDeliverableTable, parseTableResponses, paymentAsked, placeWidgets, priceFor, priceLabel, publishedVersionOf, quantityRange, quoteSchedule, renderModel, setResponse, setTableReview, shelfPriceLabel, shelfProblem, splitLayout, textDeltaOf, thinkingDeltaOf, toolEventOf, totalFor, useArtifactUrl, useChat, useCredits, useHolaClient, useShop, useThread };
|
package/dist/index.d.ts
CHANGED
|
@@ -627,6 +627,37 @@ declare class CreditRefused extends Error {
|
|
|
627
627
|
readonly status: number;
|
|
628
628
|
constructor(code: string, message: string, status: number);
|
|
629
629
|
}
|
|
630
|
+
/**
|
|
631
|
+
* "You cannot cover this" — carrying the three numbers that make it a QUOTE rather than a refusal.
|
|
632
|
+
*
|
|
633
|
+
* A SUBCLASS, not a second class, and that is load-bearing: every caller in every portal already
|
|
634
|
+
* branches on `instanceof CreditRefused` and reads `.code`, and a sibling class would fall out of
|
|
635
|
+
* all of them at once — the exact failure the comment above `CreditRefused` warns about, arriving
|
|
636
|
+
* from the other direction. Anything that handled the refusal before goes on handling it; the three
|
|
637
|
+
* numbers are additive.
|
|
638
|
+
*
|
|
639
|
+
* `short` is `credits - balance`, computed server-side, because the two figures it is derived from
|
|
640
|
+
* are read there under the same lock the debit takes. A portal recomputing it from a balance it
|
|
641
|
+
* fetched a minute ago would show a shortfall that has already been topped up.
|
|
642
|
+
*
|
|
643
|
+
* Minted ONLY when the server actually sent the numbers. Two surfaces answer 402
|
|
644
|
+
* `insufficient_credits` — settling a bill and buying from the shelf — and only the first sends
|
|
645
|
+
* them, so a shop refusal stays a plain `CreditRefused` rather than one carrying three zeros
|
|
646
|
+
* dressed as facts.
|
|
647
|
+
*/
|
|
648
|
+
declare class InsufficientCredits extends CreditRefused {
|
|
649
|
+
/** What the line costs, in credits. ROUNDED UP: see `creditsOfMoney`. */
|
|
650
|
+
readonly credits: number;
|
|
651
|
+
/** What they have right now. */
|
|
652
|
+
readonly balance: number;
|
|
653
|
+
/** The difference, and the size of the top-up that would fix it. */
|
|
654
|
+
readonly short: number;
|
|
655
|
+
constructor(message: string, figures: {
|
|
656
|
+
credits: number;
|
|
657
|
+
balance: number;
|
|
658
|
+
short: number;
|
|
659
|
+
});
|
|
660
|
+
}
|
|
630
661
|
/** One pack on sale: what it grants, and what it costs in real money.
|
|
631
662
|
*
|
|
632
663
|
* `credits` and `price` are different units and the pair is the point — 500 credits for $99 is a
|
|
@@ -985,6 +1016,35 @@ type PortalCredits = {
|
|
|
985
1016
|
claimed: boolean;
|
|
986
1017
|
status: string;
|
|
987
1018
|
}>;
|
|
1019
|
+
/**
|
|
1020
|
+
* Settle one payment line out of the customer's own prepaid balance.
|
|
1021
|
+
*
|
|
1022
|
+
* THE THIRD DOOR ONTO ONE TRANSITION, and the only self-service one that works. A transfer
|
|
1023
|
+
* settles in a bank this product cannot see and needs an operator to confirm it; `pay_url` has no
|
|
1024
|
+
* writer anywhere, so the card button never renders. This one closes itself — the balance moves,
|
|
1025
|
+
* the line flips to paid, the work starts — and it does NOT invent a second notion of paid:
|
|
1026
|
+
* `payments.status` stays the one definition, which is what keeps the console's badge, the
|
|
1027
|
+
* worklist and this page telling one story about the same order.
|
|
1028
|
+
*
|
|
1029
|
+
* `paymentId` names a LINE, not an order. That is what lets somebody pay the deposit today and
|
|
1030
|
+
* the balance on delivery, and it is what the server's idempotency key is cut from: a double tap
|
|
1031
|
+
* on a slow connection takes the credits once.
|
|
1032
|
+
*
|
|
1033
|
+
* Show the customer `creditsOfMoney(line.amount, wallet.bookRate)` before they press it. The
|
|
1034
|
+
* rounding is up, it is applied server-side, and a page that only ever showed the money figure
|
|
1035
|
+
* would take a credit more than the number on screen.
|
|
1036
|
+
*
|
|
1037
|
+
* REFUSALS, and each wants a different sentence:
|
|
1038
|
+
*
|
|
1039
|
+
* - `InsufficientCredits` (402) — they cannot cover it. Not a fault: it is a quote for a top-up,
|
|
1040
|
+
* carrying what the line costs, what they hold and the difference. The other ways to pay are
|
|
1041
|
+
* still on screen and must stay there.
|
|
1042
|
+
* - `CreditRefused` with `credits_not_sold` (409) — this company does not price in credits at
|
|
1043
|
+
* all. A portal should never have offered the option; treat it as the wallet being stale.
|
|
1044
|
+
* - `CreditRefused` with `rate_limited` (429) — too many in a row. Wait.
|
|
1045
|
+
* - Anything else is ours and the credits are safe; the sentence is the server's.
|
|
1046
|
+
*/
|
|
1047
|
+
payWithCredits(paymentId: string): Promise<PaidWithCredits>;
|
|
988
1048
|
};
|
|
989
1049
|
/** One line on a customer's bill. Mirrors the projection holaapp-backend's `customerPayment`
|
|
990
1050
|
* emits — an allowlist, not the stored row. */
|
|
@@ -1008,7 +1068,40 @@ type CustomerPayment = {
|
|
|
1008
1068
|
* money is what changes `status`. */
|
|
1009
1069
|
claimedAt: string;
|
|
1010
1070
|
reference: string;
|
|
1071
|
+
/**
|
|
1072
|
+
* Whether the customer is being ASKED for this line right now, as opposed to merely shown it as
|
|
1073
|
+
* part of the schedule they agreed to.
|
|
1074
|
+
*
|
|
1075
|
+
* RAISED IS NOT OWED. The whole schedule is written the moment the order is — that is what makes
|
|
1076
|
+
* the contract complete and the terms visible — but a balance falling due ON DELIVERY is not owed
|
|
1077
|
+
* while the work is still being done. With only `status` to go on, a portal drew a bank-transfer
|
|
1078
|
+
* form for the balance the instant the deposit landed: account numbers and an "I've sent the
|
|
1079
|
+
* transfer" button for money nobody was owed yet.
|
|
1080
|
+
*
|
|
1081
|
+
* DERIVED SERVER-SIDE, and the rule stays there. It is structural (which label, and whether the
|
|
1082
|
+
* operator has requested it) rather than a stamp, and a second copy of it here is a second copy
|
|
1083
|
+
* that can disagree with the operator's console about what a customer owes. Read it, never
|
|
1084
|
+
* recompute it — `paymentAsked` below is the whole of the reading.
|
|
1085
|
+
*
|
|
1086
|
+
* OPTIONAL because a portal is pinned to a published SDK and talks to whatever backend the
|
|
1087
|
+
* operator is on. Absent means the backend predates the field; see `paymentAsked` for why that
|
|
1088
|
+
* has to read as asked rather than as scheduled.
|
|
1089
|
+
*/
|
|
1090
|
+
asked?: boolean;
|
|
1011
1091
|
};
|
|
1092
|
+
/**
|
|
1093
|
+
* Whether this line has a pay surface — the transfer details, the credits button, the claim form.
|
|
1094
|
+
*
|
|
1095
|
+
* ABSENT READS AS ASKED, and the direction is not a coin toss. A backend older than the field sends
|
|
1096
|
+
* nothing, and reading that as "scheduled" would take the pay surface off every line in the portal
|
|
1097
|
+
* at once — a customer who owes a deposit with no way to pay it, which is worse than the bug
|
|
1098
|
+
* `asked` was added to fix. Reading it as asked reproduces exactly the behaviour that backend
|
|
1099
|
+
* already has.
|
|
1100
|
+
*
|
|
1101
|
+
* A settled line is never asked for, whatever the flag says: the server agrees, and stating it here
|
|
1102
|
+
* as well means a portal cannot draw a payment form over a receipt because one stale row disagreed.
|
|
1103
|
+
*/
|
|
1104
|
+
declare const paymentAsked: (p: CustomerPayment) => boolean;
|
|
1012
1105
|
/** How to pay this company by transfer. Null when the operator has published nothing you could
|
|
1013
1106
|
* actually send money to — no details is not an empty form, it is no transfer option. */
|
|
1014
1107
|
type TransferDetails = {
|
|
@@ -1019,6 +1112,56 @@ type TransferDetails = {
|
|
|
1019
1112
|
swift: string;
|
|
1020
1113
|
note: string;
|
|
1021
1114
|
};
|
|
1115
|
+
/**
|
|
1116
|
+
* What settling a bill from the balance came back as.
|
|
1117
|
+
*
|
|
1118
|
+
* BOTH ARMS SAY `paid: true`, and that is the whole shape of this type. The second one is the line
|
|
1119
|
+
* having already been settled — by an earlier tap of the same button on a slow connection, by the
|
|
1120
|
+
* operator marking a transfer while the customer was looking at the page, or by a retry whose first
|
|
1121
|
+
* attempt got further than the caller saw. From the customer's side the thing they wanted is TRUE,
|
|
1122
|
+
* so it is not an error and must not be drawn as one; a portal that showed "couldn't pay that" over
|
|
1123
|
+
* a bill that is paid would send somebody to pay it a second time.
|
|
1124
|
+
*
|
|
1125
|
+
* The zeros on that arm are LITERAL because they are not readings. Nothing was taken (`credits: 0`)
|
|
1126
|
+
* and nobody looked at the balance (`balance: 0`) — the row was already settled before a debit was
|
|
1127
|
+
* attempted. Re-read the wallet rather than printing that 0 at anybody.
|
|
1128
|
+
*/
|
|
1129
|
+
type PaidWithCredits =
|
|
1130
|
+
/** Settled just now. `balance` is what is LEFT, after this line. */
|
|
1131
|
+
{
|
|
1132
|
+
paid: true;
|
|
1133
|
+
alreadyPaid?: false;
|
|
1134
|
+
credits: number;
|
|
1135
|
+
balance: number;
|
|
1136
|
+
}
|
|
1137
|
+
/** It was already settled. Neither number is a reading — see above. */
|
|
1138
|
+
| {
|
|
1139
|
+
paid: true;
|
|
1140
|
+
alreadyPaid: true;
|
|
1141
|
+
credits: 0;
|
|
1142
|
+
balance: 0;
|
|
1143
|
+
};
|
|
1144
|
+
/**
|
|
1145
|
+
* What a MONEY figure costs in credits, at the company's book rate.
|
|
1146
|
+
*
|
|
1147
|
+
* A MIRROR of the server's `creditsOfMoney`, deliberately, and here for the same reason
|
|
1148
|
+
* `quoteSchedule` is: the customer has to be shown the credit figure BEFORE they press the button,
|
|
1149
|
+
* and the only figure worth showing is the one that will actually be taken.
|
|
1150
|
+
*
|
|
1151
|
+
* IT ROUNDS UP, and that is why showing it matters rather than being a nicety. The ledger moves in
|
|
1152
|
+
* whole credits, so a $10.50 line at rate 1 costs 11 — more than the exact conversion of the money
|
|
1153
|
+
* on the row. Up costs the customer at most one credit and never leaves the operator short, which
|
|
1154
|
+
* is the only direction that is safe to apply without asking; what makes it HONEST is that they
|
|
1155
|
+
* read the number first.
|
|
1156
|
+
*
|
|
1157
|
+
* Only good for a line that is still due. A settled one carries what was actually taken, stamped on
|
|
1158
|
+
* the row at the moment it was paid — the book rate is a setting an operator can change, and a
|
|
1159
|
+
* receipt re-derived through today's rate is a receipt that rewrites itself.
|
|
1160
|
+
*/
|
|
1161
|
+
declare const creditsOfMoney: (amount: number,
|
|
1162
|
+
/** Credits per one unit of currency — `CreditWallet.bookRate`. Absent or nonsense reads as 1,
|
|
1163
|
+
* which is what `normaliseBookRate` does server-side. */
|
|
1164
|
+
bookRate?: number) => number;
|
|
1022
1165
|
/** Where one order stands financially, and therefore whether it has started. */
|
|
1023
1166
|
type OrderBilling = {
|
|
1024
1167
|
/** The agreed contract value. 0 when nobody priced it — not the same as free, which is what
|
|
@@ -1029,12 +1172,33 @@ type OrderBilling = {
|
|
|
1029
1172
|
* record of what was billed, not a derivation of the contract. */
|
|
1030
1173
|
billed: number;
|
|
1031
1174
|
paid: number;
|
|
1032
|
-
/**
|
|
1033
|
-
*
|
|
1034
|
-
*
|
|
1175
|
+
/**
|
|
1176
|
+
* What the customer is being ASKED FOR right now. Never negative.
|
|
1177
|
+
*
|
|
1178
|
+
* NOT "everything raised and unsettled", which is the figure this used to be and is a bill the
|
|
1179
|
+
* customer does not owe: a deposit paid and a balance falling due on delivery came to "$4,000
|
|
1180
|
+
* due" over an order whose work was under way and whose next payment nobody had requested. Only
|
|
1181
|
+
* `asked` lines are counted — see `CustomerPayment.asked`.
|
|
1182
|
+
*
|
|
1183
|
+
* Falls back to the whole contract value when the order is priced and NOTHING has been raised
|
|
1184
|
+
* yet — the ordinary case the moment an order is written, where the customer is owed a figure
|
|
1185
|
+
* rather than a shrug. Deliberately not applied when lines exist but none is asked for: that is
|
|
1186
|
+
* a real state (all settled, or the rest merely scheduled) and answering it with the contract
|
|
1187
|
+
* value would re-bill a paid order.
|
|
1188
|
+
*/
|
|
1035
1189
|
due: number;
|
|
1036
|
-
/**
|
|
1190
|
+
/** Raised, unsettled, and NOT being asked for yet — the rest of the schedule. Listed so a
|
|
1191
|
+
* customer can see the terms they agreed to; never given a payment form. */
|
|
1192
|
+
scheduled: number;
|
|
1193
|
+
/** Every line, in SCHEDULE order: the deposit, then any milestones, then the balance — settled
|
|
1194
|
+
* or not. A bill's history reads forwards; what is owed *now* is `asked`, not a sort. */
|
|
1037
1195
|
lines: CustomerPayment[];
|
|
1196
|
+
/** The lines with a pay surface: unsettled and asked for, in the order above. What a portal draws
|
|
1197
|
+
* a transfer form, a credits button or a claim under — and nothing else. */
|
|
1198
|
+
asked: CustomerPayment[];
|
|
1199
|
+
/** Raised, unsettled, and merely COMING. Listed with their dates and no way to pay them: asking
|
|
1200
|
+
* for money against work nobody has handed over is the bug `asked` exists to prevent. */
|
|
1201
|
+
upcoming: CustomerPayment[];
|
|
1038
1202
|
/**
|
|
1039
1203
|
* Whether the work is waiting on money — and so has not started.
|
|
1040
1204
|
*
|
|
@@ -1046,14 +1210,6 @@ type OrderBilling = {
|
|
|
1046
1210
|
*/
|
|
1047
1211
|
awaitingPayment: boolean;
|
|
1048
1212
|
};
|
|
1049
|
-
/**
|
|
1050
|
-
* Fold an order's payment lines into where it stands.
|
|
1051
|
-
*
|
|
1052
|
-
* In the SDK rather than in each portal for the reason the whole of this file is: every portal that
|
|
1053
|
-
* shows a bill needs exactly this, and the second one to write it by hand would inherit nothing the
|
|
1054
|
-
* first one learned. Pure, so the arithmetic that decides whether somebody is told "this hasn't
|
|
1055
|
-
* started" is testable without a server.
|
|
1056
|
-
*/
|
|
1057
1213
|
declare const orderBilling: (order: {
|
|
1058
1214
|
value: number;
|
|
1059
1215
|
}, all: CustomerPayment[], orderId: string) => OrderBilling;
|
|
@@ -1405,4 +1561,4 @@ declare const useThread: (client: HolaClient, options?: {
|
|
|
1405
1561
|
pollMs?: number;
|
|
1406
1562
|
}) => UseThread;
|
|
1407
1563
|
|
|
1408
|
-
export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type ChosenPrice, type CreateHolaClientOptions, type CreditEntry, type CreditHistory, type CreditPack, CreditRefused, type CreditTotals, type CreditWallet, type CustomerPayment, type DashboardLayout, type DashboardSpec, type DataSource, type DeliverableColType, type DeliverableColumn, type DeliverableItem, type DeliverableItemKind, type DeliverableReviewState, type DeliverableRow, type DeliverableTable, type DeliverableVersion, type DonutWidget, GRID_COLS, GRID_MAX_COLS, GRID_MAX_ROWS, type HolaArtifact, type HolaAuthor, type HolaClient, type HolaCompletion, type HolaEmployeeInfo, type HolaError, type HolaIdentity, type HolaMessage, HolaProvider, type HolaStreamHandlers, type HolaSubscribeHandlers, type HolaSubscribeOptions, type HolaToolEvent, type HolaTransport, type InquiryQuote, type OrderBilling, type PendingTopup, type PlacedWidget, type Point, PortalConflict, type PortalCredits, type PortalData, type PortalDocument, type PortalDocumentSummary, type PortalField, type PortalFile, type PortalRow, type PortalRowAuthor, type PortalRowPage, type PortalShop, type PortalShopConfig, type PortalTable, type Purchased, QUOTE_BALANCE_LABEL, QUOTE_DEPOSIT_LABEL, type QuoteScheduleLine, type QuoteTerms, type QuotedLine, type ResolvedWidget, type SeriesWidget, type ShopApplication, type ShopApplyResult, type ShopFormField, type ShopInclusion, type ShopMode, type ShopPricing, type ShopProduct, type ShopShelf, type ShopVariant, type StatView, type StatWidget, type TableResponses, type TableReviewVerdict, type TableWidget, type TextWidget, type ThreadMessage, type TopupStarted, type TransferDetails, type UseChat, type UseCredits, type UseShop, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, buyRequestText, cellValue, createApiTransport, createHolaClient, createPortalCredits, createPortalData, createPortalShop, createWidgetTransport, deliverableCellText, deliverableStatus, deriveFields, emptyTableResponses, facetValues, footprintOf, footprintWith, formatDeliverableDate, groupDeliverableVersions, includesFor, inferSpec, isDeliverableChecked, mergeMessage, modeOf, money, normalizeDeliverableColType, normalizeDeliverableItem, orderBilling, parseDashboardSpec, parseDeliverableItems, parseDeliverableTable, parseTableResponses, placeWidgets, priceFor, priceLabel, publishedVersionOf, quantityRange, quoteSchedule, renderModel, setResponse, setTableReview, shelfPriceLabel, shelfProblem, splitLayout, textDeltaOf, thinkingDeltaOf, toolEventOf, totalFor, useArtifactUrl, useChat, useCredits, useHolaClient, useShop, useThread };
|
|
1564
|
+
export { type Agg, type ApiTransportConfig, type Band, type ChartView, Chat, type ChatMessage, type ChosenPrice, type CreateHolaClientOptions, type CreditEntry, type CreditHistory, type CreditPack, CreditRefused, type CreditTotals, type CreditWallet, type CustomerPayment, type DashboardLayout, type DashboardSpec, type DataSource, type DeliverableColType, type DeliverableColumn, type DeliverableItem, type DeliverableItemKind, type DeliverableReviewState, type DeliverableRow, type DeliverableTable, type DeliverableVersion, type DonutWidget, GRID_COLS, GRID_MAX_COLS, GRID_MAX_ROWS, type HolaArtifact, type HolaAuthor, type HolaClient, type HolaCompletion, type HolaEmployeeInfo, type HolaError, type HolaIdentity, type HolaMessage, HolaProvider, type HolaStreamHandlers, type HolaSubscribeHandlers, type HolaSubscribeOptions, type HolaToolEvent, type HolaTransport, type InquiryQuote, InsufficientCredits, type OrderBilling, type PaidWithCredits, type PendingTopup, type PlacedWidget, type Point, PortalConflict, type PortalCredits, type PortalData, type PortalDocument, type PortalDocumentSummary, type PortalField, type PortalFile, type PortalRow, type PortalRowAuthor, type PortalRowPage, type PortalShop, type PortalShopConfig, type PortalTable, type Purchased, QUOTE_BALANCE_LABEL, QUOTE_DEPOSIT_LABEL, type QuoteScheduleLine, type QuoteTerms, type QuotedLine, type ResolvedWidget, type SeriesWidget, type ShopApplication, type ShopApplyResult, type ShopFormField, type ShopInclusion, type ShopMode, type ShopPricing, type ShopProduct, type ShopShelf, type ShopVariant, type StatView, type StatWidget, type TableResponses, type TableReviewVerdict, type TableWidget, type TextWidget, type ThreadMessage, type TopupStarted, type TransferDetails, type UseChat, type UseCredits, type UseShop, type UseThread, type Widget, type WidgetTransportConfig, type WidgetType, bandOfKind, bandOfType, buyRequestText, cellValue, createApiTransport, createHolaClient, createPortalCredits, createPortalData, createPortalShop, createWidgetTransport, creditsOfMoney, deliverableCellText, deliverableStatus, deriveFields, emptyTableResponses, facetValues, footprintOf, footprintWith, formatDeliverableDate, groupDeliverableVersions, includesFor, inferSpec, isDeliverableChecked, mergeMessage, modeOf, money, normalizeDeliverableColType, normalizeDeliverableItem, orderBilling, parseDashboardSpec, parseDeliverableItems, parseDeliverableTable, parseTableResponses, paymentAsked, placeWidgets, priceFor, priceLabel, publishedVersionOf, quantityRange, quoteSchedule, renderModel, setResponse, setTableReview, shelfPriceLabel, shelfProblem, splitLayout, textDeltaOf, thinkingDeltaOf, toolEventOf, totalFor, useArtifactUrl, useChat, useCredits, useHolaClient, useShop, useThread };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
var
|
|
3
|
-
`))r.startsWith(":")||(r.startsWith("event:")?t=r.slice(6).trim():r.startsWith("data:")&&n.push(r.slice(5).replace(
|
|
4
|
-
`)}:null},
|
|
2
|
+
var ie=e=>{if(!e||typeof e!="object")return null;let t=e;return t.type==="message_update"?t.assistantMessageEvent??null:null},U=e=>{let t=ie(e);return t?.type==="text_delta"&&typeof t.delta=="string"?t.delta:null},N=e=>{let t=ie(e);return t?.type==="thinking_delta"&&typeof t.delta=="string"?t.delta:null},q=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 je=/^ /,w=e=>{if(e&&typeof e=="object"){let t=e,n=typeof t.error=="string"?t.error:"request_failed";return typeof t.retryable=="boolean"?{error:n,retryable:t.retryable}:{error:n}}return{error:"request_failed"}},Ge=e=>{let t="message",n=[];for(let r of e.split(`
|
|
3
|
+
`))r.startsWith(":")||(r.startsWith("event:")?t=r.slice(6).trim():r.startsWith("data:")&&n.push(r.slice(5).replace(je,"")));return n.length>0?{event:t,data:n.join(`
|
|
4
|
+
`)}:null},Qe=(e,t,n)=>{let r;try{r=JSON.parse(e.data)}catch{return}if(e.event==="session"){let s=r.sessionId;s&&(n(s),t.onSession?.(s));return}if(e.event==="turn_event"){t.onEvent?.(r);let s=U(r);s&&t.onText?.(s);let a=N(r);a&&t.onThinking?.(a);let o=q(r);o&&t.onTool?.(o);return}if(e.event==="chat_completed"){let s=r;n(s.sessionId),t.onComplete?.(s);return}e.event==="chat_error"&&t.onError?.(w(r))},P=async(e,t)=>{let n=await fetch(e,{headers:t});if(!n.ok)throw new Error(`hola: request failed (${n.status})`);return await n.json()},ae=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()},le=async(e,t,n,r)=>{let s=await fetch(e.url,{method:"POST",headers:e.headers,body:e.body,signal:r});if(!(s.ok&&s.body)){t.onError?.({error:`stream_failed_${s.status}`});return}let a=s.body.getReader(),o=new TextDecoder,i="",l=()=>{let d=i.indexOf(`
|
|
5
5
|
|
|
6
|
-
`);for(;d!==-1;){let
|
|
6
|
+
`);for(;d!==-1;){let m=i.slice(0,d);i=i.slice(d+2);let p=Ge(m);p&&Qe(p,t,n),d=i.indexOf(`
|
|
7
7
|
|
|
8
|
-
`)}},u=async()=>{let d=await i.read();if(!d.done)return a+=o.decode(d.value,{stream:!0}),l(),u()};await u()};var je=/\/+$/,q="/api/v1/end-user",Ge=e=>{let t=e.baseUrl.replace(je,""),n=()=>typeof e.token=="function"?e.token():e.token,r=o=>e.project?`${o}project=${encodeURIComponent(e.project)}`:"",s=async()=>({"content-type":"application/json",authorization:`Bearer ${await n()}`}),i=async o=>{let a=await fetch(`${t}${q}/chat${r("?")}`,{method:"POST",headers:await s(),body:JSON.stringify({message:o})});if(!a.ok)throw new Error(`hola: message failed (${a.status})`);return{reply:(await a.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>S(`${t}${q}/chat/info${r("?")}`,await s()),sendMessage:i,streamMessage:async(o,a)=>{try{let l=await i(o);a.onText?.(l.reply),a.onComplete?.(l)}catch(l){a.onError?.(w(l))}},subscribe:(o,a)=>{let l=a?.since??"0",u=!1,d,p=a?.intervalMs??3e3,f=typeof document<"u",c=()=>f&&document.visibilityState==="hidden",m=!1,y=()=>{if(!u){if(c()){m=!0;return}d=setTimeout(b,p)}},b=async()=>{try{let x=await S(`${t}${q}/chat/thread?since=${encodeURIComponent(l)}${r("&")}`,await s());for(let k of x.messages)o.onMessage(k);l=x.cursor,o.onHealthy?.()}catch(x){o.onError?.(w(x))}y()},P=()=>{u||!m||c()||(m=!1,d&&clearTimeout(d),d=setTimeout(b,0))};f&&document.addEventListener("visibilitychange",P);let g=()=>{u=!0,d&&clearTimeout(d),f&&document.removeEventListener("visibilitychange",P)};return a?.signal?.addEventListener("abort",g),d=setTimeout(b,0),g}}};import{useEffect as Qe,useState as ze}from"react";var N=(e,t)=>{let[n,r]=ze("");return Qe(()=>{if(!e){r("");return}let s=Uint8Array.from(atob(e),o=>o.charCodeAt(0)),i=URL.createObjectURL(new Blob([s],{type:t}));return r(i),()=>URL.revokeObjectURL(i)},[e,t]),n};import{useEffect as Ze,useRef as et}from"react";import{createContext as Je,useContext as Ke}from"react";import{jsx as Ye}from"react/jsx-runtime";var oe=Je(null),Xe=({client:e,children:t})=>Ye(oe.Provider,{value:e,children:t}),B=()=>{let e=Ke(oe);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};import{useCallback as se,useEffect as ie,useRef as ae,useState as M}from"react";var V=e=>{let[t,n]=M([]),[r,s]=M(""),[i,o]=M(!1),[a,l]=M(null),u=ae(0),d=ae(null);ie(()=>()=>d.current?.abort(),[]);let p=se(()=>{let c=u.current;return u.current+=1,c},[]);ie(()=>{let c=!0;return e.getInfo().then(m=>{c&&m.greeting&&n([{id:p(),role:"assistant",text:m.greeting}])}).catch(()=>{}),()=>{c=!1}},[e,p]);let f=se(()=>{let c=r.trim();if(!c||i)return;s(""),l(null),o(!0);let m=p(),y=p();n(g=>[...g,{id:m,role:"user",text:c},{id:y,role:"assistant",text:"",streaming:!0}]);let b=g=>{n(x=>x.map(k=>k.id===y?g(k):k))},P=new AbortController;d.current=P,e.streamMessage(c,{onText:g=>b(x=>({...x,text:x.text+g})),onComplete:g=>{b(x=>({...x,text:g.reply||x.text,artifacts:g.artifacts,streaming:!1})),o(!1)},onError:g=>{b(x=>({...x,streaming:!1})),l(g.error),o(!1)}},P.signal).catch(g=>{b(x=>({...x,streaming:!1})),l(g instanceof Error?g.message:"stream_failed"),o(!1)}).finally(()=>{o(!1),b(g=>g.streaming?{...g,streaming:!1}:g)})},[r,i,e,p]);return{messages:t,input:r,setInput:s,send:f,sending:i,error:a}};import{jsx as C,jsxs as j}from"react/jsx-runtime";var v={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"}},tt=({artifact:e})=>{let t=N(e.dataBase64??"",e.mimeType),n=e.url??t;return n?e.mimeType.startsWith("image/")?C("a",{href:n,rel:"noopener noreferrer",target:"_blank",children:C("img",{alt:e.filename,src:n,style:v.image})}):C("a",{download:e.filename,href:n,style:v.link,children:e.filename}):null},nt=()=>{let e=B(),{messages:t,input:n,setInput:r,send:s,sending:i,error:o}=V(e),a=et(null);Ze(()=>{let u=a.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let l=u=>{u.preventDefault(),s()};return j("div",{style:v.root,children:[C("div",{ref:a,style:v.log,children:t.map(u=>j("div",{style:u.role==="user"?v.user:v.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?C("div",{style:v.artifacts,children:u.artifacts.map(d=>C(tt,{artifact:d},d.filename))}):null]},u.id))}),o?C("div",{style:v.error,children:o}):null,j("form",{onSubmit:l,style:v.form,children:[C("input",{"aria-label":"Message",onChange:u=>r(u.target.value),placeholder:"Type a message\u2026",style:v.input,value:n}),C("button",{disabled:i||n.trim().length===0,style:v.button,type:"submit",children:"Send"})]})]})};var rt=/\/+$/,G=e=>{let t=e.sessionId,n=e.baseUrl.replace(rt,""),r=o=>`${n}/endpoint/${encodeURIComponent(e.token)}${o}`,s={"content-type":"application/json"},i=(o,a)=>({url:r(o),headers:s,body:JSON.stringify({message:a,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>S(r("/config"),{}),sendMessage:async o=>{let a=await ne(i("/message",o));return t=a.sessionId,a},streamMessage:(o,a,l)=>re(i("/message/stream",o),a,u=>{t=u},l),subscribe:(o,a)=>{let l=a?.since??"0",u=!1,d,p=a?.intervalMs??3e3,f=async()=>{let m=t;if(m)try{let y=await S(r(`/messages?session=${encodeURIComponent(m)}&since=${encodeURIComponent(l)}`),{});for(let b of y.messages)o.onMessage(b);l=y.cursor,o.onHealthy?.()}catch(y){o.onError?.(w(y))}u||(d=setTimeout(f,p))},c=()=>{u=!0,d&&clearTimeout(d)};return a?.signal?.addEventListener("abort",c),d=setTimeout(f,0),c}}};var ot=e=>"transport"in e?e.transport:G(e);var st=/^https?:\/\//i,it=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,at=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function lt(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(st.test(e))return"url";if(it.test(e))return"date"}return"text"}function le(e){let t=[],n=new Map;for(let r of e)for(let[s,i]of Object.entries(r.data??{})){if(i==null)continue;let o=n.get(s);o||(o=new Map,n.set(s,o),t.push(s));let a=lt(i);o.set(a,(o.get(a)??0)+1)}return t.map(r=>{let s=n.get(r)??new Map,i="text",o=-1;for(let[a,l]of s)l>o&&(o=l,i=a);return{key:r,label:at(r),type:i}})}var ut=e=>typeof e=="number"?e:Number(e)||0,ue=e=>/rate|position|rank|score|percent|avg/i.test(e),dt=/posted|published|sent|completed|shipped|launched|_at/i,pt=new Set(["service","order","end_user_id"]);function de(e,t){let n=e.filter(l=>!pt.has(l.key)),r=n.filter(l=>l.type==="number").slice(0,3),s=n.find(l=>l.key==="status")??n.find(l=>l.type==="select"),i=n.find(l=>l.type==="date"&&dt.test(l.key))??n.find(l=>l.type==="date"),o=n.filter(l=>l.type==="number"&&!ue(l.key)).map(l=>({field:l,total:t.reduce((u,d)=>u+ut(d.data[l.key]),0)})).sort((l,u)=>u.total-l.total).find(l=>l.total>0)?.field??null,a=[{type:"stat",label:"Items",agg:"count"}];for(let l of r){let u=ue(l.key);a.push({type:"stat",metric:l.key,agg:u?"avg":"sum",label:u?`Avg ${l.label.toLowerCase()}`:l.label})}return i&&a.push({type:"line",x:i.key,y:o?.key,agg:"sum",title:o?`${o.label} by day`:"Items by day"}),s&&a.push({type:"donut",groupBy:s.key,title:s.label}),a.push({type:"table",columns:n.map(l=>l.key)}),{version:1,widgets:a}}var pe=6,ce=6,me=4,ge={stat:{w:1,h:1},chart:{w:2,h:2},block:{w:6,h:2}},ct=e=>Math.max(1,Math.min(6,Math.round(e))),mt=e=>Math.max(1,Math.min(4,Math.round(e)));function $(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function fe(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function ye(e){return ge[e]}function Q(e,t,n){let r=ge[e];return{w:t===void 0?r.w:ct(t),h:n===void 0?r.h:mt(n)}}function z(e){let t=[],n=[],r=(o,a,l,u)=>{if(o<0||o+l>6)return!1;for(let d=0;d<u;d+=1){let p=n[a+d];if(p){for(let f=0;f<l;f+=1)if(p[o+f])return!1}}return!0},s=(o,a,l,u)=>{for(let d=0;d<u;d+=1){let p=n[a+d]??[];for(let f=0;f<l;f+=1)p[o+f]=!0;n[a+d]=p}},i=(o,a)=>{for(let l=0;;l+=1)for(let u=0;u+o<=6;u+=1)if(r(u,l,o,a))return{gx:u,gy:l}};for(let o of e){let a=Q($(o.kind),o.w,o.h),u=o.gx!==void 0&&o.gy!==void 0&&r(o.gx,o.gy,a.w,a.h)&&o.gx!==void 0&&o.gy!==void 0?{gx:o.gx,gy:o.gy}:i(a.w,a.h);s(u.gx,u.gy,a.w,a.h),t.push({widget:o,gx:u.gx,gy:u.gy,w:a.w,h:a.h})}return t}function be(e){let t=[],n=[];for(let r of e)$(r.kind)==="block"?n.push(r):t.push(r);return{tiles:z(t),blocks:n}}var he=new Set(["service","order","end_user_id"]),J=e=>typeof e=="number"?e:Number(e)||0,xe=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 n=t.reduce((r,s)=>r+s,0);return e==="avg"?Math.round(n/t.length*100)/100:n}function gt(e,t,n,r){let s=new Map;for(let i of e){let o=new Date(xe(i.data[t]));if(Number.isNaN(o.getTime()))continue;let a=o.toISOString().slice(0,10),l=s.get(a)??[];l.push(n?J(i.data[n]):1),s.set(a,l)}return[...s.entries()].sort((i,o)=>i[0]<o[0]?-1:1).map(([i,o])=>({label:new Date(`${i}T00:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"}),value:n?K(r,o):o.length}))}function ft(e,t,n,r="sum"){let s=new Map;for(let i of e){let o=xe(i.data[t]).trim();if(!o)continue;let a=s.get(o)??[];a.push(n?J(i.data[n]):1),s.set(o,a)}return[...s.entries()].map(([i,o])=>({label:i,value:n?K(r,o):o.length})).sort((i,o)=>o.value-i.value)}function yt(e,t,n,r){switch(e.type){case"stat":{let s=e.metric?t.get(e.metric):void 0;if(e.metric&&!s)return null;if(!s)return{kind:"stat",label:e.label??"Items",value:r.length};let i=r.map(o=>J(o.data[s.key]));return{kind:"stat",label:e.label??s.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 s=gt(r,e.x,e.y,e.agg??"sum");return s.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:s}}case"donut":{if(!t.has(e.groupBy))return null;let s=ft(r,e.groupBy,e.metric,e.agg??"sum");return s.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:s}}case"table":{let s=e.columns?e.columns.map(i=>t.get(i)).filter(i=>i!==void 0&&!he.has(i.key)):n;return s.length===0?null:{kind:"table",title:e.title,columns:s,rows:r}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function we(e,t,n,r={}){let s=new Map,i=l=>({byKey:new Map(l.fields.map(u=>[u.key,u])),cols:l.fields.filter(u=>!he.has(u.key)),rows:l.rows}),o=i({fields:t,rows:n});for(let[l,u]of Object.entries(r))s.set(l,i(u));let a=[];for(let l of e.widgets){let u=l.type==="text"?void 0:l.source,d=u?s.get(u):o;if(!d)continue;let p=yt(l,d.byKey,d.cols,d.rows);p&&a.push({...p,w:l.w,h:l.h,gx:l.gx,gy:l.gy})}return a}var bt=new Set(["sum","avg","count","min","max","last"]),Se=e=>typeof e=="string"&&bt.has(e)?e:void 0,h=e=>typeof e=="string"&&e!==""?e:void 0,I=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,A=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 ht(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",source:h(t.source),label:h(t.label),metric:h(t.metric)??h(t.column),agg:Se(t.agg),w:I(t.w),h:A(t.h),gx:T(t.gx),gy:T(t.gy)};case"line":case"bar":{let n=h(t.x);return n?{type:t.type,source:h(t.source),title:h(t.title),x:n,y:h(t.y)??h(t.column),agg:Se(t.agg),w:I(t.w),h:A(t.h),gx:T(t.gx),gy:T(t.gy)}:null}case"donut":{let n=h(t.groupBy)??h(t.column);return n?{type:"donut",source:h(t.source),title:h(t.title),groupBy:n,w:I(t.w),h:A(t.h),gx:T(t.gx),gy:T(t.gy)}:null}case"table":{let n=Array.isArray(t.columns)?t.columns.filter(r=>typeof r=="string"):void 0;return{type:"table",source:h(t.source),title:h(t.title),columns:n,w:I(t.w),h:A(t.h),gx:T(t.gx),gy:T(t.gy)}}case"text":{let n=h(t.body);return n?{type:"text",title:h(t.title),body:n,w:I(t.w),h:A(t.h),gx:T(t.gx),gy:T(t.gy)}:null}default:return null}}function ve(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 n=t.widgets;if(!Array.isArray(n))return null;let r=n.map(ht).filter(i=>i!==null);if(r.length===0)return null;let s=t.version;return{version:typeof s=="number"?s:1,title:h(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,n=typeof t.value=="string"?t.value:"",r=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",s=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return n?{kind:r,value:n,...s?{v:s}:{}}:null}return null}function Y(e){let t=new Map;for(let n of e){let r=n.v??1,s=t.get(r)??[];s.push(n),t.set(r,s)}return[...t.entries()].sort(([n],[r])=>n-r).map(([n,r])=>({v:n,items:r}))}function Pe(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(s=>s!==null)}catch{}let n=String(e.file??"");return n?[{kind:"file",value:n}]:[]}function Te(e,t,n,r=""){let i=Y(e).find(a=>a.v===t)?.items??[],o=i.filter(a=>a.kind==="file").map(a=>n.get(a.value)??"");return i.some(a=>a.kind==="table")&&o.push(r),o.length===0||o.some(a=>a==="")?"awaiting":o.some(a=>a==="revise")?"revise":"accepted"}function ke(e){return Number(e.published_version)||0}function Z(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function Ce(e){try{let t=JSON.parse(e);if(Array.isArray(t.columns)&&Array.isArray(t.rows)&&t.columns.length){let n=t.columns.map((i,o)=>({key:typeof i.key=="string"&&i.key?i.key:typeof i.id=="string"&&i.id?i.id:`column_${o+1}`,label:typeof i.label=="string"?i.label:"",type:Z(i.type),...i.clientEditable===!0?{clientEditable:!0}:{}})),r=t.rows.map((i,o)=>({id:typeof i.id=="string"&&i.id?i.id:`row_${o}`,cells:i.cells&&typeof i.cells=="object"?i.cells:{}})),s=typeof t.name=="string"?t.name:void 0;return{columns:n,rows:r,...s?{name:s}:{}}}}catch{}return null}function Re(e){return e==null?"":String(e)}function De(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function W(){return{cells:{},verdict:"",comment:""}}function Ie(e){if(typeof e!="string"||e.trim()==="")return W();try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t)){let n=t;return{cells:n.cells&&typeof n.cells=="object"?n.cells:n,verdict:n.verdict==="accepted"||n.verdict==="revise"?n.verdict:"",comment:typeof n.comment=="string"?n.comment:""}}}catch{}return W()}function Ae(e,t,n){if(e.clientEditable){let r=n.cells[t.id];if(r&&e.key in r)return r[e.key]}return t.cells[e.key]}function He(e,t,n,r){return{...e,cells:{...e.cells,[t]:{...e.cells[t]??{},[n]:r}}}}function Ee(e,t,n){return{...e,verdict:t,comment:n}}function Me(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 H=class extends Error{code;status;constructor(t,n,r){super(n),this.name="CreditRefused",this.code=t,this.status=r}},xt=/\/+$/,wt="/api/v1/end-user",$e="Pre-payment",We="After-payment";function St(e,t){if(e<=0)return[];let n=t&&typeof t.upfront=="number"&&Number.isFinite(t.upfront)?Math.max(0,Math.min(t.upfront,e)):e,r=Math.round((e-n)*100)/100,s=[];return n>0&&s.push({label:$e,amount:n}),r>0&&s.push({label:We,amount:r}),s}var vt=(e,t,n)=>{let r=t.filter(l=>l.order===n),s=r.reduce((l,u)=>l+u.amount,0),i=r.filter(l=>l.status==="paid").reduce((l,u)=>l+u.amount,0),o=e.value>0,a=s>0?s-i:e.value-i;return{value:e.value,priced:o,billed:s,paid:i,due:Math.max(0,a),lines:[...r].sort((l,u)=>l.status!==u.status?l.status==="due"?-1:1:(l.dueDate||l.paidAt).localeCompare(u.dueDate||u.paidAt)),awaitingPayment:o&&i<=0}},Pt=e=>{let t=e.baseUrl.replace(xt,""),n=()=>typeof e.token=="function"?e.token():e.token,r=async(s,i={method:"GET"})=>{try{let o=await fetch(`${t}${wt}${s}`,{method:i.method,headers:{"content-type":"application/json",authorization:`Bearer ${await n()}`},...i.body===void 0?{}:{body:JSON.stringify(i.body)}});if(!o.ok){let a=await o.json().catch(()=>({}));throw new H(a.error??"request_failed",a.message??`${i.method} ${s} \u2192 ${String(o.status)}`,o.status)}return await o.json()}catch(o){throw o instanceof H?o:w(o)}};return{wallet:()=>r("/credits"),history:()=>r("/credits/history"),topup:s=>r("/credits/checkout",{method:"POST",body:{packId:s}}),checkout:s=>r("/shop/checkout",{method:"POST",body:s}),payments:()=>r("/payments"),paymentMethods:()=>r("/payment-methods"),markPaymentSent:(s,i)=>r(`/payments/${encodeURIComponent(s)}/sent`,{method:"POST",body:{reference:i??""}}),inquiryQuote:s=>r(`/inquiries/${encodeURIComponent(s)}/quote`),acceptInquiry:(s,i)=>r(`/inquiries/${encodeURIComponent(s)}/accept`,{method:"POST",body:{version:i}}),enquire:(s,i,o)=>r("/shop/enquire",{method:"POST",body:{productId:s,answers:i,name:o??""}})}};var Tt=/\/+$/,R="/api/v1/end-user",E=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function kt(e){let t="";for(let r=0;r<e.length;r+=32768)t+=String.fromCharCode(...e.subarray(r,r+32768));return btoa(t)}var Ct=e=>{let t=e.baseUrl.replace(Tt,""),n=()=>typeof e.token=="function"?e.token():e.token,r=async()=>({"content-type":"application/json",authorization:`Bearer ${await n()}`}),s=async(o,a)=>{try{let l=await fetch(`${t}${R}${o}`,{method:a.method,headers:await r(),...a.body===void 0?{}:{body:JSON.stringify(a.body)}});if(l.status===409){let u=await l.json().catch(()=>({}));throw new E(u.message??"Someone else saved this first.")}if(!l.ok){let u=await l.text().catch(()=>""),d=`${a.method} ${o} \u2192 ${String(l.status)}`;try{let p=JSON.parse(u);p.message&&(d=p.message)}catch{d=u?`${d}: ${u}`:d}throw w({error:d})}return await l.json()}catch(l){throw l instanceof E?l:w(l)}},i=o=>`/tables/${encodeURIComponent(o)}`;return{listTables:async()=>(await S(`${t}${R}/tables`,await r())).tables,listRows:async(o,a)=>await S(`${t}${R}${i(o)}/rows?limit=${String(a??100)}`,await r()),insertRow:async(o,a)=>{let{rowIds:l}=await s(`${i(o)}/rows`,{method:"POST",body:{rows:[a]}}),u=l[0];if(!u)throw w(new Error("The row was not created."));return u},patchRow:async(o,a,l)=>(await s(`${i(o)}/rows/${encodeURIComponent(a)}`,{method:"PATCH",body:l})).updated,deleteRow:async(o,a)=>(await s(`/${encodeURIComponent(o)}/${encodeURIComponent(a)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await S(`${t}${R}/tables/files/rows?limit=200`,await r())).rows.map(a=>({id:a.rowId,filename:String(a.data.filename??""),source:String(a.data.source??"client"),campaign:String(a.data.campaign??""),size:typeof a.data.size=="number"?a.data.size:0,createdAt:a.createdAt})),uploadFile:async(o,a)=>{let l=new Uint8Array(await o.arrayBuffer());return await s("/files",{method:"POST",body:{filename:o.name,mime:o.type||"application/octet-stream",data:kt(l),...a===void 0?{}:{message:a}}})},fileLink:async o=>await S(`${t}${R}/files/${encodeURIComponent(o)}/url`,await r()),deleteFile:async o=>(await s(`/files/${encodeURIComponent(o)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await S(`${t}${R}/documents`,await r())).documents,readDocument:async o=>(await S(`${t}${R}/documents/${encodeURIComponent(o)}`,await r())).document,saveDocument:async(o,a)=>await s(`/documents/${encodeURIComponent(o)}`,{method:"PATCH",body:a})}};var Rt=/\/+$/,Dt="/api/v1/end-user",It=e=>{let t=e.baseUrl.replace(Rt,""),n=async(r,s)=>{let i;try{i=await fetch(`${t}${Dt}${r}`,s===void 0?{}:{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)})}catch(o){throw w(o)}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(o){throw w(o)}};return{listProducts:async()=>{let r=await n(`/shop/products?publishable_key=${encodeURIComponent(e.publishableKey)}`);return{products:r.products.map(s=>({...s,currency:typeof s.currency=="string"?s.currency:""})),truncated:r.truncated===!0,enquiryForm:Array.isArray(r.enquiryForm)?r.enquiryForm:[]}},apply:async r=>await n("/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}:{}})}};var At=new Set(["buy","ask"]);function Ht(e){return At.has(e.mode)?e.mode:"ask"}var Et={kind:"quoted"};function O(e,t){if(!t)return e.toLocaleString();if(t.toLowerCase()==="credits")return`${e.toLocaleString()} ${e===1?"credit":"credits"}`;let n=Number.isInteger(e)?0:2;try{return new Intl.NumberFormat(void 0,{style:"currency",currency:t,minimumFractionDigits:n,maximumFractionDigits:n}).format(e)}catch{return`${t} ${e.toLocaleString()}`}}function Oe(e,t){let n=/^[a-z]+$/i.test(t)&&!t.endsWith("s")?"s":"";return`${e.toLocaleString()} ${t}${n}`}function Fe(e,t){return e.kind==="quoted"?"Priced on enquiry":e.kind==="flat"?O(e.price,t):`${O(e.unitPrice,t)} per ${e.unitStep===1?e.unit:Oe(e.unitStep,e.unit)}`}function Mt(e){let t=e.currency,n=e.pricing;if(n.kind!=="variants")return Fe(n,t);let r=n.variants.map(s=>s.price).filter(s=>typeof s=="number");return r.length>0?`From ${O(Math.min(...r),t)}`:"Priced on enquiry"}function $t(e,t){if(e.kind!=="variants")return e;let n=e.variants.find(r=>r.name===t);return typeof n?.price=="number"?{kind:"flat",price:n.price}:Et}function Wt(e,t){return e.kind==="flat"?e.price:e.kind==="per_unit"?e.unitPrice*Math.ceil(t/Math.max(e.unitStep,1)):null}function Ot(e,t){let n=t.kind==="per_unit"?Math.max(t.unitStep,1):1;return{min:Math.max(e.minQty??n,n),max:e.maxQty??null,step:n}}function Ft(e,t){let n=e.variants?.find(r=>r.name===t);return n&&n.includes.length>0?n.includes:e.includes}function _t(e,t){let n=[];for(let r of e){let s=t(r).trim();s&&!n.includes(s)&&n.push(s)}return n}function Lt(e,t,n,r){let s=t?`${e.name} \u2014 ${t}`:e.name,i=n.kind==="per_unit"?`, ${Oe(r,n.unit)}`:"";return`I'd like to buy ${s}${i}. How do I go ahead?`}function Ut(e){return e?(e&&typeof e=="object"&&"error"in e?String(e.error):"")==="rate_limited"?"That's a lot of looking at once \u2014 give it a moment, then reload.":"The shop isn't loading right now. Please try again shortly.":null}import{useCallback as _e,useEffect as qt,useState as ee}from"react";var Nt=e=>{let[t,n]=ee(null),[r,s]=ee(!0),[i,o]=ee(null),a=_e(async()=>{try{n(await e.wallet()),o(null)}catch{o("Couldn't read your balance just now.")}finally{s(!1)}},[e]),l=_e(()=>{a().catch(()=>{})},[a]);return qt(()=>(l(),window.addEventListener("focus",l),()=>{window.removeEventListener("focus",l)}),[l]),{wallet:t,loading:r,failure:i,refresh:l}};import{useCallback as Bt,useEffect as Vt,useState as D}from"react";var jt=e=>e&&typeof e=="object"&&typeof e.error=="string"?e.error:e instanceof Error?e.message:"shop_unavailable",Gt=e=>{let[t,n]=D([]),[r,s]=D([]),[i,o]=D(!1),[a,l]=D(!0),[u,d]=D(null),[p,f]=D(0);Vt(()=>{let m=!0;return l(!0),e.listProducts().then(y=>{m&&(n(y.products),s(y.enquiryForm),o(y.truncated),d(null))}).catch(y=>{m&&d(jt(y))}).finally(()=>{m&&l(!1)}),()=>{m=!1}},[e,p]);let c=Bt(()=>f(m=>m+1),[]);return{products:t,enquiryForm:r,truncated:i,loading:a,error:u,reload:c}};import{useCallback as Qt,useEffect as Le,useRef as zt,useState as F}from"react";var Ue="greeting";function qe(e,t){if(e.some(i=>i.id===t.id))return e;let n=e.filter(i=>i.id!==Ue),r=i=>i.author==="client"==(t.author==="client");return[...n.filter(i=>!(i.pending&&r(i)&&i.text===t.text)),t]}var Jt=(e,t)=>{let[n,r]=F([]),[s,i]=F(""),[o,a]=F(!1),[l,u]=F(null),d=zt(0),p=t?.pollMs??2e3;Le(()=>{let c=!0;return e.getInfo().then(m=>{c&&m.greeting&&r(y=>y.length===0?[{id:Ue,cursor:"",author:"agent",text:m.greeting}]:y)}).catch(()=>{}),()=>{c=!1}},[e]),Le(()=>e.subscribe?.({onMessage:c=>r(m=>qe(m,c)),onError:c=>u(c.error),onHealthy:()=>u(null)},{intervalMs:p}),[e,p]);let f=Qt(()=>{let c=s.trim();if(!c||o)return;i(""),u(null),a(!0),d.current+=1;let m=`pending-${d.current}`,y={id:m,cursor:"",author:"client",text:c,pending:!0};r(b=>[...b,y]),e.sendMessage(c).then(b=>{a(!1),b.reply.trim()&&r(g=>g.some(k=>!k.pending&&k.author!=="client"&&k.text===b.reply)?g:(d.current+=1,[...g,{id:`pending-agent-${d.current}`,cursor:"",author:"agent",text:b.reply,pending:!0}]))}).catch(b=>{u(b instanceof Error?b.message:"send_failed"),a(!1),r(P=>P.filter(g=>g.id!==m)),i(P=>P||c)})},[s,o,e]);return{messages:n,input:s,setInput:i,send:f,sending:o,error:l}};export{nt as Chat,H as CreditRefused,pe as GRID_COLS,ce as GRID_MAX_COLS,me as GRID_MAX_ROWS,Xe as HolaProvider,E as PortalConflict,We as QUOTE_BALANCE_LABEL,$e as QUOTE_DEPOSIT_LABEL,$ as bandOfKind,fe as bandOfType,Lt as buyRequestText,Ae as cellValue,Ge as createApiTransport,ot as createHolaClient,Pt as createPortalCredits,Ct as createPortalData,It as createPortalShop,G as createWidgetTransport,Re as deliverableCellText,Te as deliverableStatus,le as deriveFields,W as emptyTableResponses,_t as facetValues,ye as footprintOf,Q as footprintWith,Me as formatDeliverableDate,Y as groupDeliverableVersions,Ft as includesFor,de as inferSpec,De as isDeliverableChecked,qe as mergeMessage,Ht as modeOf,O as money,Z as normalizeDeliverableColType,X as normalizeDeliverableItem,vt as orderBilling,ve as parseDashboardSpec,Pe as parseDeliverableItems,Ce as parseDeliverableTable,Ie as parseTableResponses,z as placeWidgets,$t as priceFor,Fe as priceLabel,ke as publishedVersionOf,Ot as quantityRange,St as quoteSchedule,we as renderModel,He as setResponse,Ee as setTableReview,Mt as shelfPriceLabel,Ut as shelfProblem,be as splitLayout,_ as textDeltaOf,L as thinkingDeltaOf,U as toolEventOf,Wt as totalFor,N as useArtifactUrl,V as useChat,Nt as useCredits,B as useHolaClient,Gt as useShop,Jt as useThread};
|
|
8
|
+
`)}},u=async()=>{let d=await a.read();if(!d.done)return i+=o.decode(d.value,{stream:!0}),l(),u()};await u()};var ze=/\/+$/,B="/api/v1/end-user",Je=e=>{let t=e.baseUrl.replace(ze,""),n=()=>typeof e.token=="function"?e.token():e.token,r=o=>e.project?`${o}project=${encodeURIComponent(e.project)}`:"",s=async()=>({"content-type":"application/json",authorization:`Bearer ${await n()}`}),a=async o=>{let i=await fetch(`${t}${B}/chat${r("?")}`,{method:"POST",headers:await s(),body:JSON.stringify({message:o})});if(!i.ok)throw new Error(`hola: message failed (${i.status})`);return{reply:(await i.json()).reply??"",sessionId:"",artifacts:[]}};return{sessionId:()=>"",getInfo:async()=>P(`${t}${B}/chat/info${r("?")}`,await s()),sendMessage:a,streamMessage:async(o,i)=>{try{let l=await a(o);i.onText?.(l.reply),i.onComplete?.(l)}catch(l){i.onError?.(w(l))}},subscribe:(o,i)=>{let l=i?.since??"0",u=!1,d,m=i?.intervalMs??3e3,p=typeof document<"u",c=()=>p&&document.visibilityState==="hidden",g=!1,y=()=>{if(!u){if(c()){g=!0;return}d=setTimeout(b,m)}},b=async()=>{try{let x=await P(`${t}${B}/chat/thread?since=${encodeURIComponent(l)}${r("&")}`,await s());for(let T of x.messages)o.onMessage(T);l=x.cursor,o.onHealthy?.()}catch(x){o.onError?.(w(x))}y()},v=()=>{u||!g||c()||(g=!1,d&&clearTimeout(d),d=setTimeout(b,0))};p&&document.addEventListener("visibilitychange",v);let f=()=>{u=!0,d&&clearTimeout(d),p&&document.removeEventListener("visibilitychange",v)};return i?.signal?.addEventListener("abort",f),d=setTimeout(b,0),f}}};import{useEffect as Ke,useState as Xe}from"react";var V=(e,t)=>{let[n,r]=Xe("");return Ke(()=>{if(!e){r("");return}let s=Uint8Array.from(atob(e),o=>o.charCodeAt(0)),a=URL.createObjectURL(new Blob([s],{type:t}));return r(a),()=>URL.revokeObjectURL(a)},[e,t]),n};import{useEffect as nt,useRef as rt}from"react";import{createContext as Ye,useContext as Ze}from"react";import{jsx as tt}from"react/jsx-runtime";var ue=Ye(null),et=({client:e,children:t})=>tt(ue.Provider,{value:e,children:t}),j=()=>{let e=Ze(ue);if(!e)throw new Error("useHolaClient must be used within <HolaProvider>");return e};import{useCallback as de,useEffect as pe,useRef as ce,useState as M}from"react";var G=e=>{let[t,n]=M([]),[r,s]=M(""),[a,o]=M(!1),[i,l]=M(null),u=ce(0),d=ce(null);pe(()=>()=>d.current?.abort(),[]);let m=de(()=>{let c=u.current;return u.current+=1,c},[]);pe(()=>{let c=!0;return e.getInfo().then(g=>{c&&g.greeting&&n([{id:m(),role:"assistant",text:g.greeting}])}).catch(()=>{}),()=>{c=!1}},[e,m]);let p=de(()=>{let c=r.trim();if(!c||a)return;s(""),l(null),o(!0);let g=m(),y=m();n(f=>[...f,{id:g,role:"user",text:c},{id:y,role:"assistant",text:"",streaming:!0}]);let b=f=>{n(x=>x.map(T=>T.id===y?f(T):T))},v=new AbortController;d.current=v,e.streamMessage(c,{onText:f=>b(x=>({...x,text:x.text+f})),onComplete:f=>{b(x=>({...x,text:f.reply||x.text,artifacts:f.artifacts,streaming:!1})),o(!1)},onError:f=>{b(x=>({...x,streaming:!1})),l(f.error),o(!1)}},v.signal).catch(f=>{b(x=>({...x,streaming:!1})),l(f instanceof Error?f.message:"stream_failed"),o(!1)}).finally(()=>{o(!1),b(f=>f.streaming?{...f,streaming:!1}:f)})},[r,a,e,m]);return{messages:t,input:r,setInput:s,send:p,sending:a,error:i}};import{jsx as C,jsxs as Q}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"}},ot=({artifact:e})=>{let t=V(e.dataBase64??"",e.mimeType),n=e.url??t;return n?e.mimeType.startsWith("image/")?C("a",{href:n,rel:"noopener noreferrer",target:"_blank",children:C("img",{alt:e.filename,src:n,style:S.image})}):C("a",{download:e.filename,href:n,style:S.link,children:e.filename}):null},st=()=>{let e=j(),{messages:t,input:n,setInput:r,send:s,sending:a,error:o}=G(e),i=rt(null);nt(()=>{let u=i.current;u&&(u.scrollTop=u.scrollHeight)},[t]);let l=u=>{u.preventDefault(),s()};return Q("div",{style:S.root,children:[C("div",{ref:i,style:S.log,children:t.map(u=>Q("div",{style:u.role==="user"?S.user:S.assistant,children:[u.text||(u.streaming?"\u2026":""),u.artifacts&&u.artifacts.length>0?C("div",{style:S.artifacts,children:u.artifacts.map(d=>C(ot,{artifact:d},d.filename))}):null]},u.id))}),o?C("div",{style:S.error,children:o}):null,Q("form",{onSubmit:l,style:S.form,children:[C("input",{"aria-label":"Message",onChange:u=>r(u.target.value),placeholder:"Type a message\u2026",style:S.input,value:n}),C("button",{disabled:a||n.trim().length===0,style:S.button,type:"submit",children:"Send"})]})]})};var it=/\/+$/,z=e=>{let t=e.sessionId,n=e.baseUrl.replace(it,""),r=o=>`${n}/endpoint/${encodeURIComponent(e.token)}${o}`,s={"content-type":"application/json"},a=(o,i)=>({url:r(o),headers:s,body:JSON.stringify({message:i,...t?{sessionId:t}:{},...e.identity?{externalUserId:e.identity.externalUserId,userHmac:e.identity.userHmac}:{}})});return{sessionId:()=>t,getInfo:()=>P(r("/config"),{}),sendMessage:async o=>{let i=await ae(a("/message",o));return t=i.sessionId,i},streamMessage:(o,i,l)=>le(a("/message/stream",o),i,u=>{t=u},l),subscribe:(o,i)=>{let l=i?.since??"0",u=!1,d,m=i?.intervalMs??3e3,p=async()=>{let g=t;if(g)try{let y=await P(r(`/messages?session=${encodeURIComponent(g)}&since=${encodeURIComponent(l)}`),{});for(let b of y.messages)o.onMessage(b);l=y.cursor,o.onHealthy?.()}catch(y){o.onError?.(w(y))}u||(d=setTimeout(p,m))},c=()=>{u=!0,d&&clearTimeout(d)};return i?.signal?.addEventListener("abort",c),d=setTimeout(p,0),c}}};var at=e=>"transport"in e?e.transport:z(e);var lt=/^https?:\/\//i,ut=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,dt=e=>e.replace(/_/g," ").replace(/\b\w/g,t=>t.toUpperCase());function pt(e){if(typeof e=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="string"){if(lt.test(e))return"url";if(ut.test(e))return"date"}return"text"}function me(e){let t=[],n=new Map;for(let r of e)for(let[s,a]of Object.entries(r.data??{})){if(a==null)continue;let o=n.get(s);o||(o=new Map,n.set(s,o),t.push(s));let i=pt(a);o.set(i,(o.get(i)??0)+1)}return t.map(r=>{let s=n.get(r)??new Map,a="text",o=-1;for(let[i,l]of s)l>o&&(o=l,a=i);return{key:r,label:dt(r),type:a}})}var ct=e=>typeof e=="number"?e:Number(e)||0,ge=e=>/rate|position|rank|score|percent|avg/i.test(e),mt=/posted|published|sent|completed|shipped|launched|_at/i,gt=new Set(["service","order","end_user_id"]);function fe(e,t){let n=e.filter(l=>!gt.has(l.key)),r=n.filter(l=>l.type==="number").slice(0,3),s=n.find(l=>l.key==="status")??n.find(l=>l.type==="select"),a=n.find(l=>l.type==="date"&&mt.test(l.key))??n.find(l=>l.type==="date"),o=n.filter(l=>l.type==="number"&&!ge(l.key)).map(l=>({field:l,total:t.reduce((u,d)=>u+ct(d.data[l.key]),0)})).sort((l,u)=>u.total-l.total).find(l=>l.total>0)?.field??null,i=[{type:"stat",label:"Items",agg:"count"}];for(let l of r){let u=ge(l.key);i.push({type:"stat",metric:l.key,agg:u?"avg":"sum",label:u?`Avg ${l.label.toLowerCase()}`:l.label})}return a&&i.push({type:"line",x:a.key,y:o?.key,agg:"sum",title:o?`${o.label} by day`:"Items by day"}),s&&i.push({type:"donut",groupBy:s.key,title:s.label}),i.push({type:"table",columns:n.map(l=>l.key)}),{version:1,widgets:i}}var ye=6,be=6,he=4,xe={stat:{w:1,h:1},chart:{w:2,h:2},block:{w:6,h:2}},ft=e=>Math.max(1,Math.min(6,Math.round(e))),yt=e=>Math.max(1,Math.min(4,Math.round(e)));function W(e){return e==="stat"?"stat":e==="series"||e==="donut"?"chart":"block"}function we(e){return e==="stat"?"stat":e==="line"||e==="bar"||e==="donut"?"chart":"block"}function Pe(e){return xe[e]}function J(e,t,n){let r=xe[e];return{w:t===void 0?r.w:ft(t),h:n===void 0?r.h:yt(n)}}function K(e){let t=[],n=[],r=(o,i,l,u)=>{if(o<0||o+l>6)return!1;for(let d=0;d<u;d+=1){let m=n[i+d];if(m){for(let p=0;p<l;p+=1)if(m[o+p])return!1}}return!0},s=(o,i,l,u)=>{for(let d=0;d<u;d+=1){let m=n[i+d]??[];for(let p=0;p<l;p+=1)m[o+p]=!0;n[i+d]=m}},a=(o,i)=>{for(let l=0;;l+=1)for(let u=0;u+o<=6;u+=1)if(r(u,l,o,i))return{gx:u,gy:l}};for(let o of e){let i=J(W(o.kind),o.w,o.h),u=o.gx!==void 0&&o.gy!==void 0&&r(o.gx,o.gy,i.w,i.h)&&o.gx!==void 0&&o.gy!==void 0?{gx:o.gx,gy:o.gy}:a(i.w,i.h);s(u.gx,u.gy,i.w,i.h),t.push({widget:o,gx:u.gx,gy:u.gy,w:i.w,h:i.h})}return t}function Se(e){let t=[],n=[];for(let r of e)W(r.kind)==="block"?n.push(r):t.push(r);return{tiles:K(t),blocks:n}}var ve=new Set(["service","order","end_user_id"]),X=e=>typeof e=="number"?e:Number(e)||0,ke=e=>e==null?"":String(e);function Y(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 n=t.reduce((r,s)=>r+s,0);return e==="avg"?Math.round(n/t.length*100)/100:n}function bt(e,t,n,r){let s=new Map;for(let a of e){let o=new Date(ke(a.data[t]));if(Number.isNaN(o.getTime()))continue;let i=o.toISOString().slice(0,10),l=s.get(i)??[];l.push(n?X(a.data[n]):1),s.set(i,l)}return[...s.entries()].sort((a,o)=>a[0]<o[0]?-1:1).map(([a,o])=>({label:new Date(`${a}T00:00:00`).toLocaleDateString(void 0,{month:"short",day:"numeric"}),value:n?Y(r,o):o.length}))}function ht(e,t,n,r="sum"){let s=new Map;for(let a of e){let o=ke(a.data[t]).trim();if(!o)continue;let i=s.get(o)??[];i.push(n?X(a.data[n]):1),s.set(o,i)}return[...s.entries()].map(([a,o])=>({label:a,value:n?Y(r,o):o.length})).sort((a,o)=>o.value-a.value)}function xt(e,t,n,r){switch(e.type){case"stat":{let s=e.metric?t.get(e.metric):void 0;if(e.metric&&!s)return null;if(!s)return{kind:"stat",label:e.label??"Items",value:r.length};let a=r.map(o=>X(o.data[s.key]));return{kind:"stat",label:e.label??s.label,value:Y(e.agg??"sum",a)}}case"line":case"bar":{if(!t.has(e.x)||e.y&&!t.has(e.y))return null;let s=bt(r,e.x,e.y,e.agg??"sum");return s.length<2?null:{kind:"series",draw:e.type,title:e.title??"By day",points:s}}case"donut":{if(!t.has(e.groupBy))return null;let s=ht(r,e.groupBy,e.metric,e.agg??"sum");return s.length===0?null:{kind:"donut",title:e.title??t.get(e.groupBy)?.label??"Breakdown",points:s}}case"table":{let s=e.columns?e.columns.map(a=>t.get(a)).filter(a=>a!==void 0&&!ve.has(a.key)):n;return s.length===0?null:{kind:"table",title:e.title,columns:s,rows:r}}case"text":return{kind:"text",title:e.title,body:e.body};default:return null}}function Te(e,t,n,r={}){let s=new Map,a=l=>({byKey:new Map(l.fields.map(u=>[u.key,u])),cols:l.fields.filter(u=>!ve.has(u.key)),rows:l.rows}),o=a({fields:t,rows:n});for(let[l,u]of Object.entries(r))s.set(l,a(u));let i=[];for(let l of e.widgets){let u=l.type==="text"?void 0:l.source,d=u?s.get(u):o;if(!d)continue;let m=xt(l,d.byKey,d.cols,d.rows);m&&i.push({...m,w:l.w,h:l.h,gx:l.gx,gy:l.gy})}return i}var wt=new Set(["sum","avg","count","min","max","last"]),Ce=e=>typeof e=="string"&&wt.has(e)?e:void 0,h=e=>typeof e=="string"&&e!==""?e:void 0,A=e=>typeof e=="number"&&e>=1?Math.min(6,Math.round(e)):void 0,H=e=>typeof e=="number"&&e>=1?Math.min(4,Math.round(e)):void 0,k=e=>typeof e=="number"&&e>=0?Math.round(e):void 0;function Pt(e){if(typeof e!="object"||e===null)return null;let t=e;switch(t.type){case"stat":return{type:"stat",source:h(t.source),label:h(t.label),metric:h(t.metric)??h(t.column),agg:Ce(t.agg),w:A(t.w),h:H(t.h),gx:k(t.gx),gy:k(t.gy)};case"line":case"bar":{let n=h(t.x);return n?{type:t.type,source:h(t.source),title:h(t.title),x:n,y:h(t.y)??h(t.column),agg:Ce(t.agg),w:A(t.w),h:H(t.h),gx:k(t.gx),gy:k(t.gy)}:null}case"donut":{let n=h(t.groupBy)??h(t.column);return n?{type:"donut",source:h(t.source),title:h(t.title),groupBy:n,w:A(t.w),h:H(t.h),gx:k(t.gx),gy:k(t.gy)}:null}case"table":{let n=Array.isArray(t.columns)?t.columns.filter(r=>typeof r=="string"):void 0;return{type:"table",source:h(t.source),title:h(t.title),columns:n,w:A(t.w),h:H(t.h),gx:k(t.gx),gy:k(t.gy)}}case"text":{let n=h(t.body);return n?{type:"text",title:h(t.title),body:n,w:A(t.w),h:H(t.h),gx:k(t.gx),gy:k(t.gy)}:null}default:return null}}function Re(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 n=t.widgets;if(!Array.isArray(n))return null;let r=n.map(Pt).filter(a=>a!==null);if(r.length===0)return null;let s=t.version;return{version:typeof s=="number"?s:1,title:h(t.title),widgets:r}}function Z(e){if(typeof e=="string")return e?{kind:"file",value:e}:null;if(e&&typeof e=="object"){let t=e,n=typeof t.value=="string"?t.value:"",r=t.kind==="link"||t.kind==="text"||t.kind==="table"?t.kind:"file",s=typeof t.v=="number"&&t.v>=1?Math.floor(t.v):void 0;return n?{kind:r,value:n,...s?{v:s}:{}}:null}return null}function ee(e){let t=new Map;for(let n of e){let r=n.v??1,s=t.get(r)??[];s.push(n),t.set(r,s)}return[...t.entries()].sort(([n],[r])=>n-r).map(([n,r])=>({v:n,items:r}))}function De(e){let t=e.files;if(typeof t=="string"&&t.trim()!=="")try{let r=JSON.parse(t);if(Array.isArray(r))return r.map(Z).filter(s=>s!==null)}catch{}let n=String(e.file??"");return n?[{kind:"file",value:n}]:[]}function Ie(e,t,n,r=""){let a=ee(e).find(i=>i.v===t)?.items??[],o=a.filter(i=>i.kind==="file").map(i=>n.get(i.value)??"");return a.some(i=>i.kind==="table")&&o.push(r),o.length===0||o.some(i=>i==="")?"awaiting":o.some(i=>i==="revise")?"revise":"accepted"}function Ae(e){return Number(e.published_version)||0}function te(e){return e==="number"||e==="date"||e==="boolean"||e==="select"||e==="url"?e:e==="link"?"url":e==="checkbox"?"boolean":"text"}function He(e){try{let t=JSON.parse(e);if(Array.isArray(t.columns)&&Array.isArray(t.rows)&&t.columns.length){let n=t.columns.map((a,o)=>({key:typeof a.key=="string"&&a.key?a.key:typeof a.id=="string"&&a.id?a.id:`column_${o+1}`,label:typeof a.label=="string"?a.label:"",type:te(a.type),...a.clientEditable===!0?{clientEditable:!0}:{}})),r=t.rows.map((a,o)=>({id:typeof a.id=="string"&&a.id?a.id:`row_${o}`,cells:a.cells&&typeof a.cells=="object"?a.cells:{}})),s=typeof t.name=="string"?t.name:void 0;return{columns:n,rows:r,...s?{name:s}:{}}}}catch{}return null}function Ee(e){return e==null?"":String(e)}function Me(e){return e===!0||e==="true"||e==="1"||e==="yes"||e==="\u2713"}function $(){return{cells:{},verdict:"",comment:""}}function We(e){if(typeof e!="string"||e.trim()==="")return $();try{let t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t)){let n=t;return{cells:n.cells&&typeof n.cells=="object"?n.cells:n,verdict:n.verdict==="accepted"||n.verdict==="revise"?n.verdict:"",comment:typeof n.comment=="string"?n.comment:""}}}catch{}return $()}function $e(e,t,n){if(e.clientEditable){let r=n.cells[t.id];if(r&&e.key in r)return r[e.key]}return t.cells[e.key]}function Oe(e,t,n,r){return{...e,cells:{...e.cells,[t]:{...e.cells[t]??{},[n]:r}}}}function Fe(e,t,n){return{...e,verdict:t,comment:n}}function _e(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 D=class extends Error{code;status;constructor(t,n,r){super(n),this.name="CreditRefused",this.code=t,this.status=r}},F=class extends D{credits;balance;short;constructor(t,n){super("insufficient_credits",t,402),this.name="InsufficientCredits",this.credits=n.credits,this.balance=n.balance,this.short=n.short}},St=/\/+$/,vt="/api/v1/end-user",re="Pre-payment",oe="After-payment";function kt(e,t){if(e<=0)return[];let n=t&&typeof t.upfront=="number"&&Number.isFinite(t.upfront)?Math.max(0,Math.min(t.upfront,e)):e,r=Math.round((e-n)*100)/100,s=[];return n>0&&s.push({label:re,amount:n}),r>0&&s.push({label:oe,amount:r}),s}var ne=e=>e.status!=="paid"&&e.asked!==!1,Tt=(e,t)=>{let n=typeof t=="number"&&Number.isFinite(t)&&t>0?t:1;return!Number.isFinite(e)||e<=0?0:Math.ceil(e*n)},O=e=>{let t=e.label.trim().toLowerCase();return t===re.toLowerCase()?0:t===oe.toLowerCase()?2:1},Ct=(e,t,n)=>{let r=t.filter(p=>p.order===n),s=p=>p.reduce((c,g)=>c+g.amount,0),a=s(r),o=s(r.filter(p=>p.status==="paid")),i=e.value>0,l=[...r].sort((p,c)=>O(p)!==O(c)?O(p)-O(c):(p.dueDate||p.paidAt).localeCompare(c.dueDate||c.paidAt)),u=l.filter(ne),d=l.filter(p=>p.status!=="paid"&&!ne(p)),m=a>0?s(u):e.value-o;return{value:e.value,priced:i,billed:a,paid:o,due:Math.max(0,m),scheduled:s(d),lines:l,asked:u,upcoming:d,awaitingPayment:i&&o<=0}},Rt=e=>{let{credits:t,balance:n,short:r}=e;return typeof t!="number"||typeof n!="number"||typeof r!="number"||!(Number.isFinite(t)&&Number.isFinite(n)&&Number.isFinite(r))?null:{credits:t,balance:n,short:r}},Dt=e=>{let t=e.baseUrl.replace(St,""),n=()=>typeof e.token=="function"?e.token():e.token,r=async(s,a={method:"GET"})=>{try{let o=await fetch(`${t}${vt}${s}`,{method:a.method,headers:{"content-type":"application/json",authorization:`Bearer ${await n()}`},...a.body===void 0?{}:{body:JSON.stringify(a.body)}});if(!o.ok){let i=await o.json().catch(()=>({})),l=i.message??`${a.method} ${s} \u2192 ${String(o.status)}`,u=Rt(i);throw o.status===402&&i.error==="insufficient_credits"&&u?new F(l,u):new D(i.error??"request_failed",l,o.status)}return await o.json()}catch(o){throw o instanceof D?o:w(o)}};return{wallet:()=>r("/credits"),history:()=>r("/credits/history"),topup:s=>r("/credits/checkout",{method:"POST",body:{packId:s}}),checkout:s=>r("/shop/checkout",{method:"POST",body:s}),payments:()=>r("/payments"),paymentMethods:()=>r("/payment-methods"),markPaymentSent:(s,a)=>r(`/payments/${encodeURIComponent(s)}/sent`,{method:"POST",body:{reference:a??""}}),payWithCredits:s=>r(`/payments/${encodeURIComponent(s)}/pay-with-credits`,{method:"POST",body:{}}),inquiryQuote:s=>r(`/inquiries/${encodeURIComponent(s)}/quote`),acceptInquiry:(s,a)=>r(`/inquiries/${encodeURIComponent(s)}/accept`,{method:"POST",body:{version:a}}),enquire:(s,a,o)=>r("/shop/enquire",{method:"POST",body:{productId:s,answers:a,name:o??""}})}};var It=/\/+$/,R="/api/v1/end-user",E=class extends Error{constructor(t){super(t),this.name="PortalConflict"}};function At(e){let t="";for(let r=0;r<e.length;r+=32768)t+=String.fromCharCode(...e.subarray(r,r+32768));return btoa(t)}var Ht=e=>{let t=e.baseUrl.replace(It,""),n=()=>typeof e.token=="function"?e.token():e.token,r=async()=>({"content-type":"application/json",authorization:`Bearer ${await n()}`}),s=async(o,i)=>{try{let l=await fetch(`${t}${R}${o}`,{method:i.method,headers:await r(),...i.body===void 0?{}:{body:JSON.stringify(i.body)}});if(l.status===409){let u=await l.json().catch(()=>({}));throw new E(u.message??"Someone else saved this first.")}if(!l.ok){let u=await l.text().catch(()=>""),d=`${i.method} ${o} \u2192 ${String(l.status)}`;try{let m=JSON.parse(u);m.message&&(d=m.message)}catch{d=u?`${d}: ${u}`:d}throw w({error:d})}return await l.json()}catch(l){throw l instanceof E?l:w(l)}},a=o=>`/tables/${encodeURIComponent(o)}`;return{listTables:async()=>(await P(`${t}${R}/tables`,await r())).tables,listRows:async(o,i)=>await P(`${t}${R}${a(o)}/rows?limit=${String(i??100)}`,await r()),insertRow:async(o,i)=>{let{rowIds:l}=await s(`${a(o)}/rows`,{method:"POST",body:{rows:[i]}}),u=l[0];if(!u)throw w(new Error("The row was not created."));return u},patchRow:async(o,i,l)=>(await s(`${a(o)}/rows/${encodeURIComponent(i)}`,{method:"PATCH",body:l})).updated,deleteRow:async(o,i)=>(await s(`/${encodeURIComponent(o)}/${encodeURIComponent(i)}`,{method:"DELETE"})).deleted,listFiles:async()=>(await P(`${t}${R}/tables/files/rows?limit=200`,await r())).rows.map(i=>({id:i.rowId,filename:String(i.data.filename??""),source:String(i.data.source??"client"),campaign:String(i.data.campaign??""),size:typeof i.data.size=="number"?i.data.size:0,createdAt:i.createdAt})),uploadFile:async(o,i)=>{let l=new Uint8Array(await o.arrayBuffer());return await s("/files",{method:"POST",body:{filename:o.name,mime:o.type||"application/octet-stream",data:At(l),...i===void 0?{}:{message:i}}})},fileLink:async o=>await P(`${t}${R}/files/${encodeURIComponent(o)}/url`,await r()),deleteFile:async o=>(await s(`/files/${encodeURIComponent(o)}`,{method:"DELETE"})).deleted,listDocuments:async()=>(await P(`${t}${R}/documents`,await r())).documents,readDocument:async o=>(await P(`${t}${R}/documents/${encodeURIComponent(o)}`,await r())).document,saveDocument:async(o,i)=>await s(`/documents/${encodeURIComponent(o)}`,{method:"PATCH",body:i})}};var Et=/\/+$/,Mt="/api/v1/end-user",Wt=e=>{let t=e.baseUrl.replace(Et,""),n=async(r,s)=>{let a;try{a=await fetch(`${t}${Mt}${r}`,s===void 0?{}:{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)})}catch(o){throw w(o)}if(a.status===429)throw w({error:"rate_limited",retryable:!0});if(!a.ok)throw w({error:`shop_request_failed_${String(a.status)}`});try{return await a.json()}catch(o){throw w(o)}};return{listProducts:async()=>{let r=await n(`/shop/products?publishable_key=${encodeURIComponent(e.publishableKey)}`);return{products:r.products.map(s=>({...s,currency:typeof s.currency=="string"?s.currency:""})),truncated:r.truncated===!0,enquiryForm:Array.isArray(r.enquiryForm)?r.enquiryForm:[]}},apply:async r=>await n("/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}:{}})}};var $t=new Set(["buy","ask"]);function Ot(e){return $t.has(e.mode)?e.mode:"ask"}var Ft={kind:"quoted"};function _(e,t){if(!t)return e.toLocaleString();if(t.toLowerCase()==="credits")return`${e.toLocaleString()} ${e===1?"credit":"credits"}`;let n=Number.isInteger(e)?0:2;try{return new Intl.NumberFormat(void 0,{style:"currency",currency:t,minimumFractionDigits:n,maximumFractionDigits:n}).format(e)}catch{return`${t} ${e.toLocaleString()}`}}function Le(e,t){let n=/^[a-z]+$/i.test(t)&&!t.endsWith("s")?"s":"";return`${e.toLocaleString()} ${t}${n}`}function Ue(e,t){return e.kind==="quoted"?"Priced on enquiry":e.kind==="flat"?_(e.price,t):`${_(e.unitPrice,t)} per ${e.unitStep===1?e.unit:Le(e.unitStep,e.unit)}`}function _t(e){let t=e.currency,n=e.pricing;if(n.kind!=="variants")return Ue(n,t);let r=n.variants.map(s=>s.price).filter(s=>typeof s=="number");return r.length>0?`From ${_(Math.min(...r),t)}`:"Priced on enquiry"}function Lt(e,t){if(e.kind!=="variants")return e;let n=e.variants.find(r=>r.name===t);return typeof n?.price=="number"?{kind:"flat",price:n.price}:Ft}function Ut(e,t){return e.kind==="flat"?e.price:e.kind==="per_unit"?e.unitPrice*Math.ceil(t/Math.max(e.unitStep,1)):null}function Nt(e,t){let n=t.kind==="per_unit"?Math.max(t.unitStep,1):1;return{min:Math.max(e.minQty??n,n),max:e.maxQty??null,step:n}}function qt(e,t){let n=e.variants?.find(r=>r.name===t);return n&&n.includes.length>0?n.includes:e.includes}function Bt(e,t){let n=[];for(let r of e){let s=t(r).trim();s&&!n.includes(s)&&n.push(s)}return n}function Vt(e,t,n,r){let s=t?`${e.name} \u2014 ${t}`:e.name,a=n.kind==="per_unit"?`, ${Le(r,n.unit)}`:"";return`I'd like to buy ${s}${a}. How do I go ahead?`}function jt(e){return e?(e&&typeof e=="object"&&"error"in e?String(e.error):"")==="rate_limited"?"That's a lot of looking at once \u2014 give it a moment, then reload.":"The shop isn't loading right now. Please try again shortly.":null}import{useCallback as Ne,useEffect as Gt,useState as se}from"react";var Qt=e=>{let[t,n]=se(null),[r,s]=se(!0),[a,o]=se(null),i=Ne(async()=>{try{n(await e.wallet()),o(null)}catch{o("Couldn't read your balance just now.")}finally{s(!1)}},[e]),l=Ne(()=>{i().catch(()=>{})},[i]);return Gt(()=>(l(),window.addEventListener("focus",l),()=>{window.removeEventListener("focus",l)}),[l]),{wallet:t,loading:r,failure:a,refresh:l}};import{useCallback as zt,useEffect as Jt,useState as I}from"react";var Kt=e=>e&&typeof e=="object"&&typeof e.error=="string"?e.error:e instanceof Error?e.message:"shop_unavailable",Xt=e=>{let[t,n]=I([]),[r,s]=I([]),[a,o]=I(!1),[i,l]=I(!0),[u,d]=I(null),[m,p]=I(0);Jt(()=>{let g=!0;return l(!0),e.listProducts().then(y=>{g&&(n(y.products),s(y.enquiryForm),o(y.truncated),d(null))}).catch(y=>{g&&d(Kt(y))}).finally(()=>{g&&l(!1)}),()=>{g=!1}},[e,m]);let c=zt(()=>p(g=>g+1),[]);return{products:t,enquiryForm:r,truncated:a,loading:i,error:u,reload:c}};import{useCallback as Yt,useEffect as qe,useRef as Zt,useState as L}from"react";var Be="greeting";function Ve(e,t){if(e.some(a=>a.id===t.id))return e;let n=e.filter(a=>a.id!==Be),r=a=>a.author==="client"==(t.author==="client");return[...n.filter(a=>!(a.pending&&r(a)&&a.text===t.text)),t]}var en=(e,t)=>{let[n,r]=L([]),[s,a]=L(""),[o,i]=L(!1),[l,u]=L(null),d=Zt(0),m=t?.pollMs??2e3;qe(()=>{let c=!0;return e.getInfo().then(g=>{c&&g.greeting&&r(y=>y.length===0?[{id:Be,cursor:"",author:"agent",text:g.greeting}]:y)}).catch(()=>{}),()=>{c=!1}},[e]),qe(()=>e.subscribe?.({onMessage:c=>r(g=>Ve(g,c)),onError:c=>u(c.error),onHealthy:()=>u(null)},{intervalMs:m}),[e,m]);let p=Yt(()=>{let c=s.trim();if(!c||o)return;a(""),u(null),i(!0),d.current+=1;let g=`pending-${d.current}`,y={id:g,cursor:"",author:"client",text:c,pending:!0};r(b=>[...b,y]),e.sendMessage(c).then(b=>{i(!1),b.reply.trim()&&r(f=>f.some(T=>!T.pending&&T.author!=="client"&&T.text===b.reply)?f:(d.current+=1,[...f,{id:`pending-agent-${d.current}`,cursor:"",author:"agent",text:b.reply,pending:!0}]))}).catch(b=>{u(b instanceof Error?b.message:"send_failed"),i(!1),r(v=>v.filter(f=>f.id!==g)),a(v=>v||c)})},[s,o,e]);return{messages:n,input:s,setInput:a,send:p,sending:o,error:l}};export{st as Chat,D as CreditRefused,ye as GRID_COLS,be as GRID_MAX_COLS,he as GRID_MAX_ROWS,et as HolaProvider,F as InsufficientCredits,E as PortalConflict,oe as QUOTE_BALANCE_LABEL,re as QUOTE_DEPOSIT_LABEL,W as bandOfKind,we as bandOfType,Vt as buyRequestText,$e as cellValue,Je as createApiTransport,at as createHolaClient,Dt as createPortalCredits,Ht as createPortalData,Wt as createPortalShop,z as createWidgetTransport,Tt as creditsOfMoney,Ee as deliverableCellText,Ie as deliverableStatus,me as deriveFields,$ as emptyTableResponses,Bt as facetValues,Pe as footprintOf,J as footprintWith,_e as formatDeliverableDate,ee as groupDeliverableVersions,qt as includesFor,fe as inferSpec,Me as isDeliverableChecked,Ve as mergeMessage,Ot as modeOf,_ as money,te as normalizeDeliverableColType,Z as normalizeDeliverableItem,Ct as orderBilling,Re as parseDashboardSpec,De as parseDeliverableItems,He as parseDeliverableTable,We as parseTableResponses,ne as paymentAsked,K as placeWidgets,Lt as priceFor,Ue as priceLabel,Ae as publishedVersionOf,Nt as quantityRange,kt as quoteSchedule,Te as renderModel,Oe as setResponse,Fe as setTableReview,_t as shelfPriceLabel,jt as shelfProblem,Se as splitLayout,U as textDeltaOf,N as thinkingDeltaOf,q as toolEventOf,Ut as totalFor,V as useArtifactUrl,G as useChat,Qt as useCredits,j as useHolaClient,Xt as useShop,en as useThread};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holaboss/client",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.31",
|
|
4
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",
|