@miiflow/assistant-ui 0.1.1 → 0.2.2
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/README.md +18 -0
- package/dist/{WelcomeScreen-B434H05-.d.cts → WelcomeScreen-BiY3uGhp.d.cts} +59 -4
- package/dist/{WelcomeScreen-TrcbOYob.d.ts → WelcomeScreen-YsXZsAwZ.d.ts} +59 -4
- package/dist/{avatar-DftdWqSs.d.ts → avatar-BgjqLv1r.d.ts} +1 -1
- package/dist/{avatar-DvOcT8NS.d.cts → avatar-CL1hlGO5.d.cts} +1 -1
- package/dist/chunk-3SEVU272.cjs +2 -0
- package/dist/chunk-3SEVU272.cjs.map +1 -0
- package/dist/chunk-65VDOUZG.js +2 -0
- package/dist/chunk-65VDOUZG.js.map +1 -0
- package/dist/chunk-D2PFIJNZ.js +2 -0
- package/dist/chunk-D2PFIJNZ.js.map +1 -0
- package/dist/chunk-HVCCZKEO.cjs +2 -0
- package/dist/chunk-HVCCZKEO.cjs.map +1 -0
- package/dist/chunk-POKFMILU.js +22 -0
- package/dist/chunk-POKFMILU.js.map +1 -0
- package/dist/chunk-QGRXQAWZ.cjs +22 -0
- package/dist/chunk-QGRXQAWZ.cjs.map +1 -0
- package/dist/chunk-TOYU46SZ.cjs +2 -0
- package/dist/chunk-TOYU46SZ.cjs.map +1 -0
- package/dist/chunk-W3HWTAF6.js +2 -0
- package/dist/chunk-W3HWTAF6.js.map +1 -0
- package/dist/{chunk-3ERHTQXR.js → chunk-WG77GQR3.js} +2 -2
- package/dist/{chunk-3ERHTQXR.js.map → chunk-WG77GQR3.js.map} +1 -1
- package/dist/{chunk-YMIEUVHK.cjs → chunk-ZKMXEECD.cjs} +2 -2
- package/dist/{chunk-YMIEUVHK.cjs.map → chunk-ZKMXEECD.cjs.map} +1 -1
- package/dist/client/index.cjs +5 -5
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +5 -5
- package/dist/client/index.js.map +1 -1
- package/dist/context/index.d.cts +1 -1
- package/dist/context/index.d.ts +1 -1
- package/dist/hooks/index.cjs +1 -1
- package/dist/hooks/index.d.cts +46 -9
- package/dist/hooks/index.d.ts +46 -9
- package/dist/hooks/index.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/{message-B21_kqE2.d.ts → message-4-BaKes3.d.ts} +11 -1
- package/dist/{message-a6VUd777.d.cts → message-9z0crkf9.d.cts} +11 -1
- package/dist/primitives/index.cjs +1 -1
- package/dist/primitives/index.d.cts +9 -4
- package/dist/primitives/index.d.ts +9 -4
- package/dist/primitives/index.js +1 -1
- package/dist/styled/index.cjs +1 -1
- package/dist/styled/index.d.cts +4 -4
- package/dist/styled/index.d.ts +4 -4
- package/dist/styled/index.js +1 -1
- package/dist/styles-no-preflight.css +1 -1
- package/dist/styles.css +1 -1
- package/package.json +11 -11
- package/dist/chunk-3KB4JYSQ.js +0 -2
- package/dist/chunk-3KB4JYSQ.js.map +0 -1
- package/dist/chunk-BA3VCHRC.js +0 -22
- package/dist/chunk-BA3VCHRC.js.map +0 -1
- package/dist/chunk-G7TGUXDN.cjs +0 -2
- package/dist/chunk-G7TGUXDN.cjs.map +0 -1
- package/dist/chunk-LJQHWCUK.js +0 -2
- package/dist/chunk-LJQHWCUK.js.map +0 -1
- package/dist/chunk-LLMC5JID.cjs +0 -2
- package/dist/chunk-LLMC5JID.cjs.map +0 -1
- package/dist/chunk-VQVCOIS3.cjs +0 -22
- package/dist/chunk-VQVCOIS3.cjs.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var react=require('react');function L({enabled:s=true,smooth:h=true,scrollToBottomOnMount:T=true}={}){let o=react.useRef(null),[p,g]=react.useState(true),l=react.useRef(0),c=react.useRef(null),i=react.useCallback(t=>{let e=o.current;if(!e)return;let f=t??(h?"smooth":"instant");c.current=f,e.scrollTo({top:e.scrollHeight,behavior:f});},[h]),u=react.useCallback(t=>Math.abs(t.scrollHeight-t.scrollTop-t.clientHeight)<1||t.scrollHeight<=t.clientHeight,[]),m=react.useCallback(()=>{let t=o.current;if(!t)return;let e=u(t);!e&&l.current<t.scrollTop||(e&&(c.current=null),(e||c.current===null)&&g(e)),l.current=t.scrollTop;},[u]),r=react.useCallback(()=>{let t=c.current;if(t)i(t);else if(s){let e=o.current;e&&u(e)&&i("instant");}m();},[s,i,u,m]);return react.useEffect(()=>{let t=o.current;if(!t||!s)return;let e=new ResizeObserver(()=>{r();});return e.observe(t),()=>e.disconnect()},[s,r]),react.useEffect(()=>{let t=o.current;if(!t||!s)return;let e=new MutationObserver(f=>{f.some(v=>v.type!=="attributes"||v.attributeName!=="style")&&r();});return e.observe(t,{childList:true,subtree:true,attributes:true,characterData:true}),()=>e.disconnect()},[s,r]),react.useEffect(()=>{let t=o.current;if(t)return t.addEventListener("scroll",m,{passive:true}),()=>t.removeEventListener("scroll",m)},[m]),react.useEffect(()=>{s&&T&&(c.current="instant",requestAnimationFrame(()=>{i("instant");}));},[]),{containerRef:o,scrollToBottom:i,isAtBottom:p}}function z({onSubmit:s,disabled:h=false,maxFileSize:T=10*1024*1024,allowedFileTypes:o}){let[p,g]=react.useState(""),[l,c]=react.useState([]),[i,u]=react.useState(false),[m,r]=react.useState(null),t=react.useRef(null),e=react.useCallback(n=>{g(n),r(null);},[]),f=react.useCallback(n=>{let b=Array.from(n),y=[];for(let a of b){if(a.size>T){r(`File "${a.name}" exceeds maximum size`);continue}if(o&&!o.includes(a.type)){r(`File type "${a.type}" is not allowed`);continue}y.push(a);}c(a=>[...a,...y]);},[T,o]),E=react.useCallback(n=>{c(b=>b.filter((y,a)=>a!==n));},[]),v=react.useCallback(async()=>{let n=p.trim();if(!(!n&&l.length===0||h||i)){u(true),r(null);try{await s(n,l.length>0?l:void 0),g(""),c([]),t.current?.focus();}catch(b){r(b instanceof Error?b.message:"Failed to send message");}finally{u(false);}}},[p,l,h,i,s]),M=react.useCallback(n=>{n.key==="Enter"&&!n.shiftKey&&(n.preventDefault(),v());},[v]),x=react.useCallback(()=>{g(""),c([]),r(null);},[]),C=(p.trim()||l.length>0)&&!h&&!i;return {content:p,attachments:l,isSubmitting:i,error:m,canSubmit:C,inputRef:t,handleContentChange:e,handleAddAttachment:f,handleRemoveAttachment:E,handleSubmit:v,handleKeyDown:M,clear:x}}exports.a=L;exports.b=z;//# sourceMappingURL=chunk-TOYU46SZ.cjs.map
|
|
2
|
+
//# sourceMappingURL=chunk-TOYU46SZ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-auto-scroll.ts","../src/hooks/use-message-composer.ts"],"names":["useAutoScroll","enabled","smooth","scrollToBottomOnMount","containerRef","useRef","isAtBottom","setIsAtBottom","useState","lastScrollTopRef","scrollingToBottomBehaviorRef","scrollToBottom","useCallback","behavior","container","b","computeIsAtBottom","el","handleScroll","newIsAtBottom","handleContentResize","scrollBehavior","useEffect","resizeObserver","mutationObserver","mutations","m","useMessageComposer","onSubmit","disabled","maxFileSize","allowedFileTypes","content","setContent","attachments","setAttachments","isSubmitting","setIsSubmitting","error","setError","inputRef","handleContentChange","value","handleAddAttachment","files","fileArray","validFiles","file","prev","handleRemoveAttachment","index","_","i","handleSubmit","trimmedContent","err","handleKeyDown","e","clear","canSubmit"],"mappings":"wCA+BO,SAASA,EAAqC,CACnD,OAAA,CAAAC,CAAAA,CAAU,IAAA,CACV,OAAAC,CAAAA,CAAS,IAAA,CACT,qBAAA,CAAAC,CAAAA,CAAwB,IAC1B,CAAA,CAA0B,EAAC,CAA2B,CACpD,IAAMC,CAAAA,CAAeC,YAAAA,CAAU,IAAI,CAAA,CAC7B,CAACC,CAAAA,CAAYC,CAAa,CAAA,CAAIC,cAAAA,CAAS,IAAI,CAAA,CAC3CC,CAAAA,CAAmBJ,YAAAA,CAAO,CAAC,EAO3BK,CAAAA,CAA+BL,YAAAA,CAA8B,IAAI,CAAA,CAEjEM,EAAiBC,iBAAAA,CACpBC,CAAAA,EAA8B,CAC7B,IAAMC,EAAYV,CAAAA,CAAa,OAAA,CAC/B,GAAI,CAACU,EAAW,OAEhB,IAAMC,CAAAA,CAAIF,CAAAA,GAAaX,EAAS,QAAA,CAAW,SAAA,CAAA,CAC3CQ,CAAAA,CAA6B,OAAA,CAAUK,EACvCD,CAAAA,CAAU,QAAA,CAAS,CAAE,GAAA,CAAKA,EAAU,YAAA,CAAc,QAAA,CAAUC,CAAE,CAAC,EACjE,CAAA,CACA,CAACb,CAAM,CACT,EAGMc,CAAAA,CAAoBJ,iBAAAA,CAAaK,CAAAA,EAEnC,IAAA,CAAK,IAAIA,CAAAA,CAAG,YAAA,CAAeA,CAAAA,CAAG,SAAA,CAAYA,EAAG,YAAY,CAAA,CAAI,CAAA,EAC7DA,CAAAA,CAAG,cAAgBA,CAAAA,CAAG,YAAA,CAEvB,EAAE,EAGCC,CAAAA,CAAeN,iBAAAA,CAAY,IAAM,CACrC,IAAME,CAAAA,CAAYV,CAAAA,CAAa,OAAA,CAC/B,GAAI,CAACU,CAAAA,CAAW,OAEhB,IAAMK,CAAAA,CAAgBH,EAAkBF,CAAS,CAAA,CAI7C,CAACK,CAAAA,EAAiBV,EAAiB,OAAA,CAAUK,CAAAA,CAAU,SAAA,GAGrDK,CAAAA,GACFT,EAA6B,OAAA,CAAU,IAAA,CAAA,CAAA,CAMvCS,CAAAA,EAAiBT,CAAAA,CAA6B,UAAY,IAAA,GAG1DH,CAAAA,CAAcY,CAAa,CAAA,CAAA,CAI/BV,EAAiB,OAAA,CAAUK,CAAAA,CAAU,UACvC,CAAA,CAAG,CAACE,CAAiB,CAAC,CAAA,CAGhBI,CAAAA,CAAsBR,kBAAY,IAAM,CAC5C,IAAMS,CAAAA,CAAiBX,EAA6B,OAAA,CACpD,GAAIW,EAEFV,CAAAA,CAAeU,CAAc,UACpBpB,CAAAA,CAAS,CAElB,IAAMa,CAAAA,CAAYV,EAAa,OAAA,CAC3BU,CAAAA,EAAaE,CAAAA,CAAkBF,CAAS,GAC1CH,CAAAA,CAAe,SAAS,EAE5B,CAEAO,IACF,CAAA,CAAG,CAACjB,CAAAA,CAASU,EAAgBK,CAAAA,CAAmBE,CAAY,CAAC,CAAA,CAG7D,OAAAI,eAAAA,CAAU,IAAM,CACd,IAAMR,EAAYV,CAAAA,CAAa,OAAA,CAC/B,GAAI,CAACU,GAAa,CAACb,CAAAA,CAAS,OAE5B,IAAMsB,EAAiB,IAAI,cAAA,CAAe,IAAM,CAC9CH,IACF,CAAC,CAAA,CAED,OAAAG,EAAe,OAAA,CAAQT,CAAS,CAAA,CACzB,IAAMS,EAAe,UAAA,EAC9B,CAAA,CAAG,CAACtB,EAASmB,CAAmB,CAAC,CAAA,CAGjCE,eAAAA,CAAU,IAAM,CACd,IAAMR,CAAAA,CAAYV,CAAAA,CAAa,QAC/B,GAAI,CAACU,CAAAA,EAAa,CAACb,EAAS,OAE5B,IAAMuB,EAAmB,IAAI,gBAAA,CAAkBC,GAAc,CAG/BA,CAAAA,CAAU,IAAA,CACnCC,CAAAA,EAAMA,EAAE,IAAA,GAAS,YAAA,EAAgBA,CAAAA,CAAE,aAAA,GAAkB,OACxD,CAAA,EAEEN,CAAAA,GAEJ,CAAC,EAED,OAAAI,CAAAA,CAAiB,OAAA,CAAQV,CAAAA,CAAW,CAClC,SAAA,CAAW,IAAA,CACX,OAAA,CAAS,IAAA,CACT,WAAY,IAAA,CACZ,aAAA,CAAe,IACjB,CAAC,EAEM,IAAMU,CAAAA,CAAiB,UAAA,EAChC,EAAG,CAACvB,CAAAA,CAASmB,CAAmB,CAAC,EAGjCE,eAAAA,CAAU,IAAM,CACd,IAAMR,EAAYV,CAAAA,CAAa,OAAA,CAC/B,GAAKU,CAAAA,CAEL,OAAAA,CAAAA,CAAU,gBAAA,CAAiB,QAAA,CAAUI,CAAAA,CAAc,CAAE,OAAA,CAAS,IAAK,CAAC,CAAA,CAC7D,IAAMJ,CAAAA,CAAU,mBAAA,CAAoB,QAAA,CAAUI,CAAY,CACnE,CAAA,CAAG,CAACA,CAAY,CAAC,EAGjBI,eAAAA,CAAU,IAAM,CACVrB,CAAAA,EAAWE,IAEbO,CAAAA,CAA6B,OAAA,CAAU,UACvC,qBAAA,CAAsB,IAAM,CAC1BC,CAAAA,CAAe,SAAS,EAC1B,CAAC,GAIL,CAAA,CAAG,EAAE,CAAA,CAEE,CACL,YAAA,CAAAP,CAAAA,CACA,cAAA,CAAAO,CAAAA,CACA,WAAAL,CACF,CACF,CCnKO,SAASqB,CAAAA,CAAmB,CACjC,SAAAC,CAAAA,CACA,QAAA,CAAAC,CAAAA,CAAW,KAAA,CACX,YAAAC,CAAAA,CAAc,EAAA,CAAK,IAAA,CAAO,IAAA,CAC1B,iBAAAC,CACF,CAAA,CAA8B,CAC5B,GAAM,CAACC,CAAAA,CAASC,CAAU,CAAA,CAAIzB,cAAAA,CAAS,EAAE,CAAA,CACnC,CAAC0B,CAAAA,CAAaC,CAAc,EAAI3B,cAAAA,CAAiB,EAAE,CAAA,CACnD,CAAC4B,CAAAA,CAAcC,CAAe,CAAA,CAAI7B,cAAAA,CAAS,KAAK,CAAA,CAChD,CAAC8B,CAAAA,CAAOC,CAAQ,EAAI/B,cAAAA,CAAwB,IAAI,CAAA,CAEhDgC,CAAAA,CAAWnC,aAA4B,IAAI,CAAA,CAE3CoC,CAAAA,CAAsB7B,iBAAAA,CAAa8B,GAAkB,CACzDT,CAAAA,CAAWS,CAAK,CAAA,CAChBH,EAAS,IAAI,EACf,CAAA,CAAG,EAAE,CAAA,CAECI,CAAAA,CAAsB/B,iBAAAA,CACzBgC,CAAAA,EAA6B,CAC5B,IAAMC,CAAAA,CAAY,KAAA,CAAM,IAAA,CAAKD,CAAK,CAAA,CAC5BE,CAAAA,CAAqB,EAAC,CAE5B,QAAWC,CAAAA,IAAQF,CAAAA,CAAW,CAE5B,GAAIE,EAAK,IAAA,CAAOjB,CAAAA,CAAa,CAC3BS,CAAAA,CAAS,SAASQ,CAAAA,CAAK,IAAI,CAAA,sBAAA,CAAwB,CAAA,CACnD,QACF,CAGA,GAAIhB,CAAAA,EAAoB,CAACA,EAAiB,QAAA,CAASgB,CAAAA,CAAK,IAAI,CAAA,CAAG,CAC7DR,CAAAA,CAAS,CAAA,WAAA,EAAcQ,CAAAA,CAAK,IAAI,kBAAkB,CAAA,CAClD,QACF,CAEAD,CAAAA,CAAW,KAAKC,CAAI,EACtB,CAEAZ,CAAAA,CAAgBa,GAAS,CAAC,GAAGA,CAAAA,CAAM,GAAGF,CAAU,CAAC,EACnD,CAAA,CACA,CAAChB,EAAaC,CAAgB,CAChC,EAEMkB,CAAAA,CAAyBrC,iBAAAA,CAAasC,GAAkB,CAC5Df,CAAAA,CAAgBa,CAAAA,EAASA,CAAAA,CAAK,OAAO,CAACG,CAAAA,CAAGC,CAAAA,GAAMA,CAAAA,GAAMF,CAAK,CAAC,EAC7D,CAAA,CAAG,EAAE,CAAA,CAECG,CAAAA,CAAezC,iBAAAA,CAAY,SAAY,CAC3C,IAAM0C,CAAAA,CAAiBtB,CAAAA,CAAQ,IAAA,GAC/B,GAAK,EAAA,CAACsB,CAAAA,EAAkBpB,CAAAA,CAAY,SAAW,CAAA,EAAML,CAAAA,EAAYO,CAAAA,CAAAA,CAIjE,CAAAC,EAAgB,IAAI,CAAA,CACpBE,CAAAA,CAAS,IAAI,EAEb,GAAI,CACF,MAAMX,CAAAA,CAAS0B,EAAgBpB,CAAAA,CAAY,MAAA,CAAS,CAAA,CAAIA,CAAAA,CAAc,MAAS,CAAA,CAC/ED,CAAAA,CAAW,EAAE,CAAA,CACbE,EAAe,EAAE,CAAA,CACjBK,CAAAA,CAAS,SAAS,KAAA,GACpB,CAAA,MAASe,CAAAA,CAAK,CACZhB,CAAAA,CAASgB,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,QAAU,wBAAwB,EACxE,CAAA,OAAE,CACAlB,EAAgB,KAAK,EACvB,EACF,CAAA,CAAG,CAACL,EAASE,CAAAA,CAAaL,CAAAA,CAAUO,CAAAA,CAAcR,CAAQ,CAAC,CAAA,CAErD4B,CAAAA,CAAgB5C,iBAAAA,CACnB6C,CAAAA,EAA0C,CAErCA,CAAAA,CAAE,GAAA,GAAQ,OAAA,EAAW,CAACA,EAAE,QAAA,GAC1BA,CAAAA,CAAE,cAAA,EAAe,CACjBJ,GAAa,EAEjB,CAAA,CACA,CAACA,CAAY,CACf,CAAA,CAEMK,CAAAA,CAAQ9C,iBAAAA,CAAY,IAAM,CAC9BqB,CAAAA,CAAW,EAAE,CAAA,CACbE,CAAAA,CAAe,EAAE,CAAA,CACjBI,CAAAA,CAAS,IAAI,EACf,CAAA,CAAG,EAAE,CAAA,CAECoB,GAAa3B,CAAAA,CAAQ,IAAA,EAAK,EAAKE,CAAAA,CAAY,OAAS,CAAA,GAAM,CAACL,CAAAA,EAAY,CAACO,EAE9E,OAAO,CACL,OAAA,CAAAJ,CAAAA,CACA,YAAAE,CAAAA,CACA,YAAA,CAAAE,CAAAA,CACA,KAAA,CAAAE,EACA,SAAA,CAAAqB,CAAAA,CACA,QAAA,CAAAnB,CAAAA,CACA,oBAAAC,CAAAA,CACA,mBAAA,CAAAE,CAAAA,CACA,sBAAA,CAAAM,EACA,YAAA,CAAAI,CAAAA,CACA,cAAAG,CAAAA,CACA,KAAA,CAAAE,CACF,CACF","file":"chunk-TOYU46SZ.cjs","sourcesContent":["import { useEffect, useRef, useCallback, useState } from \"react\";\n\nexport interface UseAutoScrollOptions {\n /** Whether auto-scroll is enabled */\n enabled?: boolean;\n /** Smooth scroll behavior */\n smooth?: boolean;\n /** Scroll to bottom when component mounts */\n scrollToBottomOnMount?: boolean;\n}\n\nexport interface UseAutoScrollReturn<T extends HTMLElement> {\n /** Ref to attach to the scrollable container */\n containerRef: React.RefObject<T | null>;\n /** Scroll to bottom programmatically (always forces scroll) */\n scrollToBottom: (behavior?: ScrollBehavior) => void;\n /** Whether the viewport is currently at the bottom */\n isAtBottom: boolean;\n}\n\n/**\n * Hook to automatically scroll to the bottom of a container\n * when new content is added, unless the user has scrolled up.\n *\n * Combines ResizeObserver + MutationObserver to catch all height changes\n * (image loads, panel expansion, streaming text, new messages).\n *\n * Uses a 1px tolerance for isAtBottom (matches assistant-ui) and\n * persists scroll behavior across content resize to prevent\n * the \"content outraces scroll\" bug.\n */\nexport function useAutoScroll<T extends HTMLElement>({\n enabled = true,\n smooth = true,\n scrollToBottomOnMount = true,\n}: UseAutoScrollOptions = {}): UseAutoScrollReturn<T> {\n const containerRef = useRef<T>(null);\n const [isAtBottom, setIsAtBottom] = useState(true);\n const lastScrollTopRef = useRef(0);\n\n // When scrollToBottom() is called, store the behavior.\n // On subsequent resize/mutation callbacks, re-scroll with the same behavior\n // until the bottom is actually reached. This prevents the \"content outraces\n // scroll\" bug where new content pushes the bottom away faster than smooth\n // scrolling can reach it.\n const scrollingToBottomBehaviorRef = useRef<ScrollBehavior | null>(null);\n\n const scrollToBottom = useCallback(\n (behavior?: ScrollBehavior) => {\n const container = containerRef.current;\n if (!container) return;\n\n const b = behavior ?? (smooth ? \"smooth\" : \"instant\");\n scrollingToBottomBehaviorRef.current = b;\n container.scrollTo({ top: container.scrollHeight, behavior: b });\n },\n [smooth],\n );\n\n // Determine if we're at the bottom (1px tolerance, or content fits without scroll)\n const computeIsAtBottom = useCallback((el: HTMLElement): boolean => {\n return (\n Math.abs(el.scrollHeight - el.scrollTop - el.clientHeight) < 1 ||\n el.scrollHeight <= el.clientHeight\n );\n }, []);\n\n // Scroll event handler — updates isAtBottom state\n const handleScroll = useCallback(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const newIsAtBottom = computeIsAtBottom(container);\n\n // If user is scrolling UP while we're in the middle of a scrollToBottom,\n // don't flip isAtBottom to false (ignore scroll-down momentum).\n if (!newIsAtBottom && lastScrollTopRef.current < container.scrollTop) {\n // Scroll is moving down — likely from our scrollToBottom call, ignore\n } else {\n if (newIsAtBottom) {\n scrollingToBottomBehaviorRef.current = null;\n }\n\n // Only update state when behavior ref is cleared (i.e. not mid-scroll)\n // or when we actually reached the bottom\n const shouldUpdate =\n newIsAtBottom || scrollingToBottomBehaviorRef.current === null;\n\n if (shouldUpdate) {\n setIsAtBottom(newIsAtBottom);\n }\n }\n\n lastScrollTopRef.current = container.scrollTop;\n }, [computeIsAtBottom]);\n\n // Content resize handler — called by both ResizeObserver and MutationObserver\n const handleContentResize = useCallback(() => {\n const scrollBehavior = scrollingToBottomBehaviorRef.current;\n if (scrollBehavior) {\n // We're in the middle of a scrollToBottom — keep chasing the bottom\n scrollToBottom(scrollBehavior);\n } else if (enabled) {\n // Auto-scroll only if already at bottom\n const container = containerRef.current;\n if (container && computeIsAtBottom(container)) {\n scrollToBottom(\"instant\");\n }\n }\n\n handleScroll();\n }, [enabled, scrollToBottom, computeIsAtBottom, handleScroll]);\n\n // ResizeObserver — catches height changes from image loads, layout shifts, etc.\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !enabled) return;\n\n const resizeObserver = new ResizeObserver(() => {\n handleContentResize();\n });\n\n resizeObserver.observe(container);\n return () => resizeObserver.disconnect();\n }, [enabled, handleContentResize]);\n\n // MutationObserver — catches new messages, streaming text, DOM changes\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !enabled) return;\n\n const mutationObserver = new MutationObserver((mutations) => {\n // Filter out style-only attribute mutations to prevent feedback loops\n // (e.g. components that write styles in response to viewport changes)\n const hasRelevantMutation = mutations.some(\n (m) => m.type !== \"attributes\" || m.attributeName !== \"style\",\n );\n if (hasRelevantMutation) {\n handleContentResize();\n }\n });\n\n mutationObserver.observe(container, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n });\n\n return () => mutationObserver.disconnect();\n }, [enabled, handleContentResize]);\n\n // Scroll listener\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n container.addEventListener(\"scroll\", handleScroll, { passive: true });\n return () => container.removeEventListener(\"scroll\", handleScroll);\n }, [handleScroll]);\n\n // Scroll to bottom on mount\n useEffect(() => {\n if (enabled && scrollToBottomOnMount) {\n // Use instant on mount — no need for smooth animation on initial load\n scrollingToBottomBehaviorRef.current = \"instant\";\n requestAnimationFrame(() => {\n scrollToBottom(\"instant\");\n });\n }\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return {\n containerRef,\n scrollToBottom,\n isAtBottom,\n };\n}\n","import { useState, useCallback, useRef, type KeyboardEvent } from \"react\";\n\ninterface UseMessageComposerOptions {\n /** Callback when message is submitted */\n onSubmit: (content: string, attachments?: File[]) => Promise<void>;\n /** Whether submission is disabled */\n disabled?: boolean;\n /** Maximum file size in bytes */\n maxFileSize?: number;\n /** Allowed file types (MIME types) */\n allowedFileTypes?: string[];\n}\n\n/**\n * Hook to manage message composer state and behavior.\n */\nexport function useMessageComposer({\n onSubmit,\n disabled = false,\n maxFileSize = 10 * 1024 * 1024, // 10MB\n allowedFileTypes,\n}: UseMessageComposerOptions) {\n const [content, setContent] = useState(\"\");\n const [attachments, setAttachments] = useState<File[]>([]);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n const handleContentChange = useCallback((value: string) => {\n setContent(value);\n setError(null);\n }, []);\n\n const handleAddAttachment = useCallback(\n (files: FileList | File[]) => {\n const fileArray = Array.from(files);\n const validFiles: File[] = [];\n\n for (const file of fileArray) {\n // Check file size\n if (file.size > maxFileSize) {\n setError(`File \"${file.name}\" exceeds maximum size`);\n continue;\n }\n\n // Check file type\n if (allowedFileTypes && !allowedFileTypes.includes(file.type)) {\n setError(`File type \"${file.type}\" is not allowed`);\n continue;\n }\n\n validFiles.push(file);\n }\n\n setAttachments((prev) => [...prev, ...validFiles]);\n },\n [maxFileSize, allowedFileTypes]\n );\n\n const handleRemoveAttachment = useCallback((index: number) => {\n setAttachments((prev) => prev.filter((_, i) => i !== index));\n }, []);\n\n const handleSubmit = useCallback(async () => {\n const trimmedContent = content.trim();\n if ((!trimmedContent && attachments.length === 0) || disabled || isSubmitting) {\n return;\n }\n\n setIsSubmitting(true);\n setError(null);\n\n try {\n await onSubmit(trimmedContent, attachments.length > 0 ? attachments : undefined);\n setContent(\"\");\n setAttachments([]);\n inputRef.current?.focus();\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to send message\");\n } finally {\n setIsSubmitting(false);\n }\n }, [content, attachments, disabled, isSubmitting, onSubmit]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLTextAreaElement>) => {\n // Submit on Enter without Shift\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n },\n [handleSubmit]\n );\n\n const clear = useCallback(() => {\n setContent(\"\");\n setAttachments([]);\n setError(null);\n }, []);\n\n const canSubmit = (content.trim() || attachments.length > 0) && !disabled && !isSubmitting;\n\n return {\n content,\n attachments,\n isSubmitting,\n error,\n canSubmit,\n inputRef,\n handleContentChange,\n handleAddAttachment,\n handleRemoveAttachment,\n handleSubmit,\n handleKeyDown,\n clear,\n };\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {a,b}from'./chunk-65VDOUZG.js';import {createContext,forwardRef,useContext}from'react';import {jsx,Fragment,jsxs}from'react/jsx-runtime';var d=createContext(null);function g(){let e=useContext(d);if(!e)throw new Error("useMessage must be used within a Message component");return e}var S=forwardRef(({message:e,viewerRole:t="user",children:r,...n},s)=>{let o=(e.participant?.role||"").toLowerCase()===(t||"").toLowerCase(),i=e.isStreaming??false;return jsx(d.Provider,{value:{message:e,isViewer:o,isStreaming:i},children:jsx("div",{ref:s,"data-role":e.participant?.role,"data-viewer":o,"data-streaming":i,...n,children:r})})});S.displayName="Message";var L=forwardRef(({children:e,...t},r)=>{let{message:n}=g();return jsx("div",{ref:r,...t,children:e??n.textContent})});L.displayName="MessageContent";var h=forwardRef(({format:e,...t},r)=>{let{message:n}=g(),s=typeof n.createdAt=="string"?new Date(n.createdAt):n.createdAt,o=e?e(s):s.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:true});return jsx("span",{ref:r,...t,children:o})});h.displayName="MessageTimestamp";var R=forwardRef(({children:e,autoScroll:t=true,onIsAtBottomChange:r,onScrollToBottomRef:n,...s},o)=>{let{containerRef:i,scrollToBottom:a$1,isAtBottom:p}=a({enabled:t});return {current:p}.current!==p&&r?.(p),n?.(a$1),jsx("div",{ref:c=>{i.current=c,typeof o=="function"?o(c):o&&(o.current=c);},...s,children:e})});R.displayName="MessageList";var M=createContext(null);function x(){let e=useContext(M);if(!e)throw new Error("useComposer must be used within a MessageComposer component");return e}var P=forwardRef(({onSubmit:e,disabled:t=false,children:r,className:n},s)=>{let o=b({onSubmit:e,disabled:t}),i=p=>{p.preventDefault(),o.handleSubmit();},a={...o,canSubmit:!!o.canSubmit};return jsx(M.Provider,{value:a,children:jsx("form",{ref:s,className:n,onSubmit:i,"data-submitting":o.isSubmitting,"data-can-submit":o.canSubmit,children:r})})});P.displayName="MessageComposer";var H=forwardRef((e,t)=>{let{content:r,handleContentChange:n,handleKeyDown:s,inputRef:o}=x();return jsx("textarea",{ref:a=>{o.current=a,typeof t=="function"?t(a):t&&(t.current=a);},value:r,onChange:a=>n(a.target.value),onKeyDown:s,...e})});H.displayName="ComposerInput";var E=forwardRef(({children:e,disabled:t,...r},n)=>{let{canSubmit:s,isSubmitting:o}=x();return jsx("button",{ref:n,type:"submit",disabled:t||!s,"data-submitting":o,...r,children:e})});E.displayName="ComposerSubmit";function G(e){let t=e.trim().split(/\s+/);return t.length===1?t[0].charAt(0).toUpperCase():(t[0].charAt(0)+t[t.length-1].charAt(0)).toUpperCase()}var N=forwardRef(({name:e,src:t,alt:r,role:n,fallback:s,children:o,...i},a)=>{let p=e?G(e):null;return jsx("div",{ref:a,"data-role":n,...i,children:o??jsx(Fragment,{children:t?jsx("img",{src:t,alt:r??e??n??"Avatar",style:{width:"100%",height:"100%"}}):s??p??n?.charAt(0).toUpperCase()})})});N.displayName="Avatar";var w=forwardRef(({content:e,isStreaming:t=false,showCursor:r=true,cursor:n,children:s,...o},i)=>jsxs("div",{ref:i,"data-streaming":t,...o,children:[s??e,t&&r&&(n??jsx("span",{"aria-hidden":"true",style:{display:"inline-block",width:"2px",height:"1em",backgroundColor:"currentColor",marginLeft:"2px",verticalAlign:"text-bottom",animation:"blink 1s step-end infinite"}}))]}));w.displayName="StreamingText";var T=createContext(null);function D(){let e=useContext(T);if(!e)throw new Error("useSuggestedActions must be used within a SuggestedActions component");return e}var I=forwardRef(({actions:e,onSelect:t,children:r,className:n},s)=>e.length===0?null:jsx(T.Provider,{value:{actions:e,onSelect:t},children:jsx("div",{ref:s,role:"group","aria-label":"Suggested actions",className:n,children:r})}));I.displayName="SuggestedActions";var k=forwardRef(({action:e,children:t,onClick:r,...n},s)=>{let{onSelect:o}=D();return jsx("button",{ref:s,type:"button",onClick:a=>{r?.(a),a.defaultPrevented||o(e);},...n,children:t??e.label})});k.displayName="ActionButton";var V=forwardRef(({children:e,dotCount:t=3,...r},n)=>jsx("div",{ref:n,role:"status","aria-label":"Assistant is typing",...r,children:e??jsx("span",{"aria-hidden":"true",children:Array.from({length:t}).map((s,o)=>jsx("span",{style:{display:"inline-block",width:"6px",height:"6px",borderRadius:"50%",backgroundColor:"currentColor",marginRight:o<t-1?"4px":0,animation:"typing 1.4s infinite ease-in-out",animationDelay:`${o*.2}s`}},o))})}));V.displayName="TypingIndicator";export{d as a,g as b,S as c,L as d,h as e,R as f,M as g,x as h,P as i,H as j,E as k,N as l,w as m,T as n,D as o,I as p,k as q,V as r};//# sourceMappingURL=chunk-W3HWTAF6.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-W3HWTAF6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/primitives/message.tsx","../src/primitives/message-list.tsx","../src/primitives/message-composer.tsx","../src/primitives/avatar.tsx","../src/primitives/streaming-text.tsx","../src/primitives/suggested-actions.tsx","../src/primitives/typing-indicator.tsx"],"names":["MessageContext","createContext","useMessage","context","useContext","Message","forwardRef","message","viewerRole","children","props","ref","isViewer","isStreaming","jsx","MessageContent","MessageTimestamp","format","date","formatted","MessageList","autoScroll","onIsAtBottomChange","onScrollToBottomRef","containerRef","scrollToBottom","isAtBottom","useAutoScroll","node","ComposerContext","useComposer","MessageComposer","onSubmit","disabled","className","composer","useMessageComposer","handleFormSubmit","e","contextValue","ComposerInput","content","handleContentChange","handleKeyDown","inputRef","ComposerSubmit","canSubmit","isSubmitting","getInitials","name","parts","Avatar","src","alt","role","fallback","initials","Fragment","StreamingText","showCursor","cursor","jsxs","SuggestedActionsContext","useSuggestedActions","SuggestedActions","actions","onSelect","ActionButton","action","onClick","TypingIndicator","dotCount","_","i"],"mappings":"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","file":"chunk-W3HWTAF6.js","sourcesContent":["import { createContext, forwardRef, useContext, type HTMLAttributes, type ReactNode } from \"react\";\nimport type { MessageData, ParticipantRole } from \"../types\";\n\ninterface MessageContextValue {\n\tmessage: MessageData;\n\tisViewer: boolean;\n\tisStreaming: boolean;\n}\n\nconst MessageContext = createContext<MessageContextValue | null>(null);\n\n/**\n * Hook to access the current message context.\n * Must be used within a Message component.\n */\nexport function useMessage() {\n\tconst context = useContext(MessageContext);\n\tif (!context) {\n\t\tthrow new Error(\"useMessage must be used within a Message component\");\n\t}\n\treturn context;\n}\n\nexport interface MessageProps extends HTMLAttributes<HTMLDivElement> {\n\t/** The message data */\n\tmessage: MessageData;\n\t/** The viewer's role (used to determine alignment) */\n\tviewerRole?: ParticipantRole;\n\t/** Children to render inside the message */\n\tchildren: ReactNode;\n}\n\n/**\n * Headless Message primitive.\n * Provides message context to children and data attributes for styling.\n */\nexport const Message = forwardRef<HTMLDivElement, MessageProps>(\n\t({ message, viewerRole = \"user\", children, ...props }, ref) => {\n\t\t// Case-insensitive comparison for role matching\n\t\tconst isViewer = (message.participant?.role || \"\").toLowerCase() === (viewerRole || \"\").toLowerCase();\n\t\tconst isStreaming = message.isStreaming ?? false;\n\n\t\treturn (\n\t\t\t<MessageContext.Provider value={{ message, isViewer, isStreaming }}>\n\t\t\t\t<div\n\t\t\t\t\tref={ref}\n\t\t\t\t\tdata-role={message.participant?.role}\n\t\t\t\t\tdata-viewer={isViewer}\n\t\t\t\t\tdata-streaming={isStreaming}\n\t\t\t\t\t{...props}>\n\t\t\t\t\t{children}\n\t\t\t\t</div>\n\t\t\t</MessageContext.Provider>\n\t\t);\n\t},\n);\n\nMessage.displayName = \"Message\";\n\nexport interface MessageContentProps extends HTMLAttributes<HTMLDivElement> {\n\t/** Custom content to render instead of message text */\n\tchildren?: ReactNode;\n}\n\n/**\n * Renders the message content.\n * By default renders the message's textContent.\n */\nexport const MessageContent = forwardRef<HTMLDivElement, MessageContentProps>(({ children, ...props }, ref) => {\n\tconst { message } = useMessage();\n\n\treturn (\n\t\t<div ref={ref} {...props}>\n\t\t\t{children ?? message.textContent}\n\t\t</div>\n\t);\n});\n\nMessageContent.displayName = \"MessageContent\";\n\nexport interface MessageTimestampProps extends HTMLAttributes<HTMLSpanElement> {\n\t/** Custom date formatter */\n\tformat?: (date: Date) => string;\n}\n\n/**\n * Renders the message timestamp.\n */\nexport const MessageTimestamp = forwardRef<HTMLSpanElement, MessageTimestampProps>(({ format, ...props }, ref) => {\n\tconst { message } = useMessage();\n\tconst date = typeof message.createdAt === \"string\" ? new Date(message.createdAt) : message.createdAt;\n\n\tconst formatted = format\n\t\t? format(date)\n\t\t: date.toLocaleTimeString(\"en-US\", {\n\t\t\t\thour: \"numeric\",\n\t\t\t\tminute: \"2-digit\",\n\t\t\t\thour12: true,\n\t\t\t});\n\n\treturn (\n\t\t<span ref={ref} {...props}>\n\t\t\t{formatted}\n\t\t</span>\n\t);\n});\n\nMessageTimestamp.displayName = \"MessageTimestamp\";\n\nexport { MessageContext };\n","import { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\nimport { useAutoScroll } from \"../hooks/use-auto-scroll\";\n\nexport interface MessageListProps extends HTMLAttributes<HTMLDivElement> {\n\t/** Messages to render */\n\tchildren: ReactNode;\n\t/** Whether to auto-scroll to bottom on new messages */\n\tautoScroll?: boolean;\n\t/** Whether the viewport is currently at the bottom (exposed for scroll-to-bottom button) */\n\tisAtBottom?: boolean;\n\t/** Callback to receive scroll state updates */\n\tonIsAtBottomChange?: (isAtBottom: boolean) => void;\n\t/** Callback to receive scrollToBottom function */\n\tonScrollToBottomRef?: (scrollToBottom: (behavior?: ScrollBehavior) => void) => void;\n}\n\n/**\n * Headless MessageList primitive.\n * Provides a scrollable container with auto-scroll behavior.\n * Exposes isAtBottom and scrollToBottom for scroll-to-bottom button integration.\n */\nexport const MessageList = forwardRef<HTMLDivElement, MessageListProps>(\n\t({ children, autoScroll = true, onIsAtBottomChange, onScrollToBottomRef, ...props }, ref) => {\n\t\tconst { containerRef, scrollToBottom, isAtBottom } = useAutoScroll<HTMLDivElement>({\n\t\t\tenabled: autoScroll,\n\t\t});\n\n\t\t// Notify parent of scroll state changes\n\t\tconst prevIsAtBottomRef = { current: isAtBottom };\n\t\tif (prevIsAtBottomRef.current !== isAtBottom) {\n\t\t\tonIsAtBottomChange?.(isAtBottom);\n\t\t}\n\n\t\t// Expose scrollToBottom to parent\n\t\tonScrollToBottomRef?.(scrollToBottom);\n\n\t\t// Merge refs\n\t\tconst mergedRef = (node: HTMLDivElement | null) => {\n\t\t\t(containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node;\n\t\t\tif (typeof ref === \"function\") {\n\t\t\t\tref(node);\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = node;\n\t\t\t}\n\t\t};\n\n\t\treturn (\n\t\t\t<div ref={mergedRef} {...props}>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\n\nMessageList.displayName = \"MessageList\";\n","import {\n createContext,\n useContext,\n forwardRef,\n type ReactNode,\n type TextareaHTMLAttributes,\n type ButtonHTMLAttributes,\n} from \"react\";\nimport { useMessageComposer } from \"../hooks/use-message-composer\";\n\ninterface ComposerContextValue {\n content: string;\n isSubmitting: boolean;\n canSubmit: boolean;\n error: string | null;\n handleContentChange: (value: string) => void;\n handleSubmit: () => Promise<void>;\n handleKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;\n inputRef: React.RefObject<HTMLTextAreaElement | null>;\n}\n\nconst ComposerContext = createContext<ComposerContextValue | null>(null);\n\n/**\n * Hook to access the composer context.\n * Must be used within a MessageComposer component.\n */\nexport function useComposer() {\n const context = useContext(ComposerContext);\n if (!context) {\n throw new Error(\"useComposer must be used within a MessageComposer component\");\n }\n return context;\n}\n\nexport interface MessageComposerProps {\n /** Callback when message is submitted */\n onSubmit: (content: string, attachments?: File[]) => Promise<void>;\n /** Whether the composer is disabled */\n disabled?: boolean;\n /** Children to render inside the composer */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Headless MessageComposer primitive.\n * Provides composer state and behavior to children.\n */\nexport const MessageComposer = forwardRef<HTMLFormElement, MessageComposerProps>(\n ({ onSubmit, disabled = false, children, className }, ref) => {\n const composer = useMessageComposer({ onSubmit, disabled });\n\n const handleFormSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n composer.handleSubmit();\n };\n\n const contextValue: ComposerContextValue = {\n ...composer,\n canSubmit: Boolean(composer.canSubmit),\n };\n\n return (\n <ComposerContext.Provider value={contextValue}>\n <form\n ref={ref}\n className={className}\n onSubmit={handleFormSubmit}\n data-submitting={composer.isSubmitting}\n data-can-submit={composer.canSubmit}\n >\n {children}\n </form>\n </ComposerContext.Provider>\n );\n }\n);\n\nMessageComposer.displayName = \"MessageComposer\";\n\nexport interface ComposerInputProps\n extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, \"onChange\" | \"value\"> {}\n\n/**\n * Text input for the message composer.\n */\nexport const ComposerInput = forwardRef<HTMLTextAreaElement, ComposerInputProps>(\n (props, ref) => {\n const { content, handleContentChange, handleKeyDown, inputRef } = useComposer();\n\n // Merge refs\n const mergedRef = (node: HTMLTextAreaElement | null) => {\n (inputRef as React.MutableRefObject<HTMLTextAreaElement | null>).current = node;\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n };\n\n return (\n <textarea\n ref={mergedRef}\n value={content}\n onChange={(e) => handleContentChange(e.target.value)}\n onKeyDown={handleKeyDown}\n {...props}\n />\n );\n }\n);\n\nComposerInput.displayName = \"ComposerInput\";\n\nexport interface ComposerSubmitProps extends ButtonHTMLAttributes<HTMLButtonElement> {}\n\n/**\n * Submit button for the message composer.\n */\nexport const ComposerSubmit = forwardRef<HTMLButtonElement, ComposerSubmitProps>(\n ({ children, disabled, ...props }, ref) => {\n const { canSubmit, isSubmitting } = useComposer();\n\n return (\n <button\n ref={ref}\n type=\"submit\"\n disabled={disabled || !canSubmit}\n data-submitting={isSubmitting}\n {...props}\n >\n {children}\n </button>\n );\n }\n);\n\nComposerSubmit.displayName = \"ComposerSubmit\";\n\nexport { ComposerContext };\n","import { forwardRef, type HTMLAttributes } from \"react\";\nimport type { ParticipantRole } from \"../types\";\n\nexport interface AvatarProps extends HTMLAttributes<HTMLDivElement> {\n /** Name for fallback initials */\n name?: string;\n /** Image URL */\n src?: string;\n /** Alt text for image */\n alt?: string;\n /** Participant role for styling */\n role?: ParticipantRole;\n /** Fallback content when no image or name */\n fallback?: React.ReactNode;\n}\n\n/**\n * Get initials from a name.\n */\nfunction getInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n if (parts.length === 1) {\n return parts[0].charAt(0).toUpperCase();\n }\n return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();\n}\n\n/**\n * Headless Avatar primitive.\n * Renders an image or fallback initials.\n */\nexport const Avatar = forwardRef<HTMLDivElement, AvatarProps>(\n ({ name, src, alt, role, fallback, children, ...props }, ref) => {\n const initials = name ? getInitials(name) : null;\n const altText = alt ?? name ?? role ?? \"Avatar\";\n\n return (\n <div ref={ref} data-role={role} {...props}>\n {children ?? (\n <>\n {src ? (\n <img src={src} alt={altText} style={{ width: \"100%\", height: \"100%\" }} />\n ) : (\n fallback ?? initials ?? role?.charAt(0).toUpperCase()\n )}\n </>\n )}\n </div>\n );\n }\n);\n\nAvatar.displayName = \"Avatar\";\n","import { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nexport interface StreamingTextProps extends HTMLAttributes<HTMLDivElement> {\n /** The content to display */\n content: string;\n /** Whether the text is currently streaming */\n isStreaming?: boolean;\n /** Show a cursor indicator while streaming */\n showCursor?: boolean;\n /** Custom cursor element */\n cursor?: ReactNode;\n /** Children override (takes precedence over content) */\n children?: ReactNode;\n}\n\n/**\n * Headless StreamingText primitive.\n * Renders text with streaming indicator support.\n */\nexport const StreamingText = forwardRef<HTMLDivElement, StreamingTextProps>(\n (\n { content, isStreaming = false, showCursor = true, cursor, children, ...props },\n ref\n ) => {\n const defaultCursor = (\n <span\n aria-hidden=\"true\"\n style={{\n display: \"inline-block\",\n width: \"2px\",\n height: \"1em\",\n backgroundColor: \"currentColor\",\n marginLeft: \"2px\",\n verticalAlign: \"text-bottom\",\n animation: \"blink 1s step-end infinite\",\n }}\n />\n );\n\n return (\n <div ref={ref} data-streaming={isStreaming} {...props}>\n {children ?? content}\n {isStreaming && showCursor && (cursor ?? defaultCursor)}\n </div>\n );\n }\n);\n\nStreamingText.displayName = \"StreamingText\";\n","import {\n createContext,\n useContext,\n forwardRef,\n type ReactNode,\n type ButtonHTMLAttributes,\n} from \"react\";\nimport type { SuggestedAction } from \"../types\";\n\ninterface SuggestedActionsContextValue {\n actions: SuggestedAction[];\n onSelect: (action: SuggestedAction) => void;\n}\n\nconst SuggestedActionsContext = createContext<SuggestedActionsContextValue | null>(null);\n\n/**\n * Hook to access suggested actions context.\n */\nexport function useSuggestedActions() {\n const context = useContext(SuggestedActionsContext);\n if (!context) {\n throw new Error(\n \"useSuggestedActions must be used within a SuggestedActions component\"\n );\n }\n return context;\n}\n\nexport interface SuggestedActionsProps {\n /** List of suggested actions */\n actions: SuggestedAction[];\n /** Callback when an action is selected */\n onSelect: (action: SuggestedAction) => void;\n /** Children to render */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Headless SuggestedActions primitive.\n * Provides context for rendering action buttons.\n */\nexport const SuggestedActions = forwardRef<HTMLDivElement, SuggestedActionsProps>(\n ({ actions, onSelect, children, className }, ref) => {\n if (actions.length === 0) {\n return null;\n }\n\n return (\n <SuggestedActionsContext.Provider value={{ actions, onSelect }}>\n <div ref={ref} role=\"group\" aria-label=\"Suggested actions\" className={className}>\n {children}\n </div>\n </SuggestedActionsContext.Provider>\n );\n }\n);\n\nSuggestedActions.displayName = \"SuggestedActions\";\n\nexport interface ActionButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** The action this button represents */\n action: SuggestedAction;\n /** Children to render inside button */\n children?: ReactNode;\n}\n\n/**\n * Button for a suggested action.\n */\nexport const ActionButton = forwardRef<HTMLButtonElement, ActionButtonProps>(\n ({ action, children, onClick, ...props }, ref) => {\n const { onSelect } = useSuggestedActions();\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (!e.defaultPrevented) {\n onSelect(action);\n }\n };\n\n return (\n <button ref={ref} type=\"button\" onClick={handleClick} {...props}>\n {children ?? action.label}\n </button>\n );\n }\n);\n\nActionButton.displayName = \"ActionButton\";\n\nexport { SuggestedActionsContext };\n","import { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nexport interface TypingIndicatorProps extends HTMLAttributes<HTMLDivElement> {\n /** Custom content to show while typing */\n children?: ReactNode;\n /** Number of dots to show */\n dotCount?: number;\n}\n\n/**\n * Headless TypingIndicator primitive.\n * Shows animated dots or custom content.\n */\nexport const TypingIndicator = forwardRef<HTMLDivElement, TypingIndicatorProps>(\n ({ children, dotCount = 3, ...props }, ref) => {\n return (\n <div ref={ref} role=\"status\" aria-label=\"Assistant is typing\" {...props}>\n {children ?? (\n <span aria-hidden=\"true\">\n {Array.from({ length: dotCount }).map((_, i) => (\n <span\n key={i}\n style={{\n display: \"inline-block\",\n width: \"6px\",\n height: \"6px\",\n borderRadius: \"50%\",\n backgroundColor: \"currentColor\",\n marginRight: i < dotCount - 1 ? \"4px\" : 0,\n animation: `typing 1.4s infinite ease-in-out`,\n animationDelay: `${i * 0.2}s`,\n }}\n />\n ))}\n </span>\n )}\n </div>\n );\n }\n);\n\nTypingIndicator.displayName = \"TypingIndicator\";\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {useState,useRef,useCallback}from'react';function
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import {useState,useRef,useCallback}from'react';function b(r={}){let[c,i]=useState({isStreaming:false,streamingMessageId:null,streamedContent:""}),n=useRef(null),m=useCallback(e=>{i({isStreaming:true,streamingMessageId:e,streamedContent:""}),n.current=new AbortController;},[]),p=useCallback(e=>{e.type==="content"&&e.content&&i(u=>({...u,streamedContent:u.streamedContent+e.content})),r.onChunk?.(e);},[r]),d=useCallback(()=>{n.current?.abort();let e=c.streamedContent;i({isStreaming:false,streamingMessageId:null,streamedContent:""}),r.onComplete?.(e);},[c.streamedContent,r]),S=useCallback(e=>{n.current?.abort(),i({isStreaming:false,streamingMessageId:null,streamedContent:""}),r.onError?.(e);},[r]);return {...c,startStreaming:m,appendContent:p,stopStreaming:d,handleError:S,abortSignal:n.current?.signal}}function x({maxCount:r=5,maxFileSize:c=10*1024*1024,allowedTypes:i}={}){let[n,m]=useState([]),p=useCallback(t=>{if(n.length>=r)return {success:false,error:`Maximum ${r} attachments allowed`};if(t.size>c)return {success:false,error:`File size exceeds ${Math.round(c/1024/1024)}MB limit`};if(i&&!i.includes(t.type))return {success:false,error:`File type ${t.type} not allowed`};let o=`${Date.now()}-${Math.random().toString(36).slice(2)}`;return m(a=>[...a,{file:t,id:o,progress:0,status:"pending"}]),{success:true}},[n.length,r,c,i]),d=useCallback(t=>{m(o=>o.filter(a=>a.id!==t));},[]),S=useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,progress:o,status:o<100?"uploading":"complete"}:s));},[]),e=useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,status:"error",error:o}:s));},[]),u=useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,url:o,status:"complete",progress:100}:s));},[]),f=useCallback(()=>{m([]);},[]),C=useCallback(()=>n.map(t=>t.file),[n]);return {attachments:n,addAttachment:p,removeAttachment:d,updateProgress:S,setError:e,setUrl:u,clear:f,getFiles:C,canAddMore:n.length<r}}export{b as a,x as b};//# sourceMappingURL=chunk-WG77GQR3.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-WG77GQR3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-streaming.ts","../src/hooks/use-attachments.ts"],"names":["useStreaming","options","state","setState","useState","abortControllerRef","useRef","startStreaming","useCallback","messageId","appendContent","chunk","prev","stopStreaming","finalContent","handleError","error","useAttachments","maxCount","maxFileSize","allowedTypes","attachments","setAttachments","addAttachment","file","id","removeAttachment","updateProgress","progress","a","setError","setUrl","url","clear","getFiles"],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-streaming.ts","../src/hooks/use-attachments.ts"],"names":["useStreaming","options","state","setState","useState","abortControllerRef","useRef","startStreaming","useCallback","messageId","appendContent","chunk","prev","stopStreaming","finalContent","handleError","error","useAttachments","maxCount","maxFileSize","allowedTypes","attachments","setAttachments","addAttachment","file","id","removeAttachment","updateProgress","progress","a","setError","setUrl","url","clear","getFiles"],"mappings":"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","file":"chunk-WG77GQR3.js","sourcesContent":["import { useState, useCallback, useRef } from \"react\";\nimport type { StreamingState, StreamChunk, StreamingOptions } from \"../types\";\n\n/**\n * Hook to manage streaming message state.\n */\nexport function useStreaming(options: StreamingOptions = {}) {\n const [state, setState] = useState<StreamingState>({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const startStreaming = useCallback((messageId: string) => {\n setState({\n isStreaming: true,\n streamingMessageId: messageId,\n streamedContent: \"\",\n });\n abortControllerRef.current = new AbortController();\n }, []);\n\n const appendContent = useCallback(\n (chunk: StreamChunk) => {\n if (chunk.type === \"content\" && chunk.content) {\n setState((prev) => ({\n ...prev,\n streamedContent: prev.streamedContent + chunk.content,\n }));\n }\n options.onChunk?.(chunk);\n },\n [options]\n );\n\n const stopStreaming = useCallback(() => {\n abortControllerRef.current?.abort();\n const finalContent = state.streamedContent;\n\n setState({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n\n options.onComplete?.(finalContent);\n }, [state.streamedContent, options]);\n\n const handleError = useCallback(\n (error: Error) => {\n abortControllerRef.current?.abort();\n setState({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n options.onError?.(error);\n },\n [options]\n );\n\n return {\n ...state,\n startStreaming,\n appendContent,\n stopStreaming,\n handleError,\n abortSignal: abortControllerRef.current?.signal,\n };\n}\n","import { useState, useCallback } from \"react\";\n\ninterface AttachmentState {\n file: File;\n id: string;\n progress: number;\n status: \"pending\" | \"uploading\" | \"complete\" | \"error\";\n error?: string;\n url?: string;\n}\n\ninterface UseAttachmentsOptions {\n /** Maximum number of attachments */\n maxCount?: number;\n /** Maximum file size in bytes */\n maxFileSize?: number;\n /** Allowed MIME types */\n allowedTypes?: string[];\n}\n\n/**\n * Hook to manage file attachments with upload progress.\n */\nexport function useAttachments({\n maxCount = 5,\n maxFileSize = 10 * 1024 * 1024,\n allowedTypes,\n}: UseAttachmentsOptions = {}) {\n const [attachments, setAttachments] = useState<AttachmentState[]>([]);\n\n const addAttachment = useCallback(\n (file: File): { success: boolean; error?: string } => {\n // Check count\n if (attachments.length >= maxCount) {\n return { success: false, error: `Maximum ${maxCount} attachments allowed` };\n }\n\n // Check size\n if (file.size > maxFileSize) {\n return {\n success: false,\n error: `File size exceeds ${Math.round(maxFileSize / 1024 / 1024)}MB limit`,\n };\n }\n\n // Check type\n if (allowedTypes && !allowedTypes.includes(file.type)) {\n return { success: false, error: `File type ${file.type} not allowed` };\n }\n\n const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n setAttachments((prev) => [\n ...prev,\n {\n file,\n id,\n progress: 0,\n status: \"pending\",\n },\n ]);\n\n return { success: true };\n },\n [attachments.length, maxCount, maxFileSize, allowedTypes]\n );\n\n const removeAttachment = useCallback((id: string) => {\n setAttachments((prev) => prev.filter((a) => a.id !== id));\n }, []);\n\n const updateProgress = useCallback((id: string, progress: number) => {\n setAttachments((prev) =>\n prev.map((a) =>\n a.id === id\n ? { ...a, progress, status: progress < 100 ? \"uploading\" : \"complete\" }\n : a\n )\n );\n }, []);\n\n const setError = useCallback((id: string, error: string) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === id ? { ...a, status: \"error\", error } : a))\n );\n }, []);\n\n const setUrl = useCallback((id: string, url: string) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === id ? { ...a, url, status: \"complete\", progress: 100 } : a))\n );\n }, []);\n\n const clear = useCallback(() => {\n setAttachments([]);\n }, []);\n\n const getFiles = useCallback(() => {\n return attachments.map((a) => a.file);\n }, [attachments]);\n\n return {\n attachments,\n addAttachment,\n removeAttachment,\n updateProgress,\n setError,\n setUrl,\n clear,\n getFiles,\n canAddMore: attachments.length < maxCount,\n };\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var react=require('react');function
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
'use strict';var react=require('react');function b(r={}){let[c,i]=react.useState({isStreaming:false,streamingMessageId:null,streamedContent:""}),n=react.useRef(null),m=react.useCallback(e=>{i({isStreaming:true,streamingMessageId:e,streamedContent:""}),n.current=new AbortController;},[]),p=react.useCallback(e=>{e.type==="content"&&e.content&&i(u=>({...u,streamedContent:u.streamedContent+e.content})),r.onChunk?.(e);},[r]),d=react.useCallback(()=>{n.current?.abort();let e=c.streamedContent;i({isStreaming:false,streamingMessageId:null,streamedContent:""}),r.onComplete?.(e);},[c.streamedContent,r]),S=react.useCallback(e=>{n.current?.abort(),i({isStreaming:false,streamingMessageId:null,streamedContent:""}),r.onError?.(e);},[r]);return {...c,startStreaming:m,appendContent:p,stopStreaming:d,handleError:S,abortSignal:n.current?.signal}}function x({maxCount:r=5,maxFileSize:c=10*1024*1024,allowedTypes:i}={}){let[n,m]=react.useState([]),p=react.useCallback(t=>{if(n.length>=r)return {success:false,error:`Maximum ${r} attachments allowed`};if(t.size>c)return {success:false,error:`File size exceeds ${Math.round(c/1024/1024)}MB limit`};if(i&&!i.includes(t.type))return {success:false,error:`File type ${t.type} not allowed`};let o=`${Date.now()}-${Math.random().toString(36).slice(2)}`;return m(a=>[...a,{file:t,id:o,progress:0,status:"pending"}]),{success:true}},[n.length,r,c,i]),d=react.useCallback(t=>{m(o=>o.filter(a=>a.id!==t));},[]),S=react.useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,progress:o,status:o<100?"uploading":"complete"}:s));},[]),e=react.useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,status:"error",error:o}:s));},[]),u=react.useCallback((t,o)=>{m(a=>a.map(s=>s.id===t?{...s,url:o,status:"complete",progress:100}:s));},[]),f=react.useCallback(()=>{m([]);},[]),C=react.useCallback(()=>n.map(t=>t.file),[n]);return {attachments:n,addAttachment:p,removeAttachment:d,updateProgress:S,setError:e,setUrl:u,clear:f,getFiles:C,canAddMore:n.length<r}}exports.a=b;exports.b=x;//# sourceMappingURL=chunk-ZKMXEECD.cjs.map
|
|
2
|
+
//# sourceMappingURL=chunk-ZKMXEECD.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-streaming.ts","../src/hooks/use-attachments.ts"],"names":["useStreaming","options","state","setState","useState","abortControllerRef","useRef","startStreaming","useCallback","messageId","appendContent","chunk","prev","stopStreaming","finalContent","handleError","error","useAttachments","maxCount","maxFileSize","allowedTypes","attachments","setAttachments","addAttachment","file","id","removeAttachment","updateProgress","progress","a","setError","setUrl","url","clear","getFiles"],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-streaming.ts","../src/hooks/use-attachments.ts"],"names":["useStreaming","options","state","setState","useState","abortControllerRef","useRef","startStreaming","useCallback","messageId","appendContent","chunk","prev","stopStreaming","finalContent","handleError","error","useAttachments","maxCount","maxFileSize","allowedTypes","attachments","setAttachments","addAttachment","file","id","removeAttachment","updateProgress","progress","a","setError","setUrl","url","clear","getFiles"],"mappings":"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","file":"chunk-ZKMXEECD.cjs","sourcesContent":["import { useState, useCallback, useRef } from \"react\";\nimport type { StreamingState, StreamChunk, StreamingOptions } from \"../types\";\n\n/**\n * Hook to manage streaming message state.\n */\nexport function useStreaming(options: StreamingOptions = {}) {\n const [state, setState] = useState<StreamingState>({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const startStreaming = useCallback((messageId: string) => {\n setState({\n isStreaming: true,\n streamingMessageId: messageId,\n streamedContent: \"\",\n });\n abortControllerRef.current = new AbortController();\n }, []);\n\n const appendContent = useCallback(\n (chunk: StreamChunk) => {\n if (chunk.type === \"content\" && chunk.content) {\n setState((prev) => ({\n ...prev,\n streamedContent: prev.streamedContent + chunk.content,\n }));\n }\n options.onChunk?.(chunk);\n },\n [options]\n );\n\n const stopStreaming = useCallback(() => {\n abortControllerRef.current?.abort();\n const finalContent = state.streamedContent;\n\n setState({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n\n options.onComplete?.(finalContent);\n }, [state.streamedContent, options]);\n\n const handleError = useCallback(\n (error: Error) => {\n abortControllerRef.current?.abort();\n setState({\n isStreaming: false,\n streamingMessageId: null,\n streamedContent: \"\",\n });\n options.onError?.(error);\n },\n [options]\n );\n\n return {\n ...state,\n startStreaming,\n appendContent,\n stopStreaming,\n handleError,\n abortSignal: abortControllerRef.current?.signal,\n };\n}\n","import { useState, useCallback } from \"react\";\n\ninterface AttachmentState {\n file: File;\n id: string;\n progress: number;\n status: \"pending\" | \"uploading\" | \"complete\" | \"error\";\n error?: string;\n url?: string;\n}\n\ninterface UseAttachmentsOptions {\n /** Maximum number of attachments */\n maxCount?: number;\n /** Maximum file size in bytes */\n maxFileSize?: number;\n /** Allowed MIME types */\n allowedTypes?: string[];\n}\n\n/**\n * Hook to manage file attachments with upload progress.\n */\nexport function useAttachments({\n maxCount = 5,\n maxFileSize = 10 * 1024 * 1024,\n allowedTypes,\n}: UseAttachmentsOptions = {}) {\n const [attachments, setAttachments] = useState<AttachmentState[]>([]);\n\n const addAttachment = useCallback(\n (file: File): { success: boolean; error?: string } => {\n // Check count\n if (attachments.length >= maxCount) {\n return { success: false, error: `Maximum ${maxCount} attachments allowed` };\n }\n\n // Check size\n if (file.size > maxFileSize) {\n return {\n success: false,\n error: `File size exceeds ${Math.round(maxFileSize / 1024 / 1024)}MB limit`,\n };\n }\n\n // Check type\n if (allowedTypes && !allowedTypes.includes(file.type)) {\n return { success: false, error: `File type ${file.type} not allowed` };\n }\n\n const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n setAttachments((prev) => [\n ...prev,\n {\n file,\n id,\n progress: 0,\n status: \"pending\",\n },\n ]);\n\n return { success: true };\n },\n [attachments.length, maxCount, maxFileSize, allowedTypes]\n );\n\n const removeAttachment = useCallback((id: string) => {\n setAttachments((prev) => prev.filter((a) => a.id !== id));\n }, []);\n\n const updateProgress = useCallback((id: string, progress: number) => {\n setAttachments((prev) =>\n prev.map((a) =>\n a.id === id\n ? { ...a, progress, status: progress < 100 ? \"uploading\" : \"complete\" }\n : a\n )\n );\n }, []);\n\n const setError = useCallback((id: string, error: string) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === id ? { ...a, status: \"error\", error } : a))\n );\n }, []);\n\n const setUrl = useCallback((id: string, url: string) => {\n setAttachments((prev) =>\n prev.map((a) => (a.id === id ? { ...a, url, status: \"complete\", progress: 100 } : a))\n );\n }, []);\n\n const clear = useCallback(() => {\n setAttachments([]);\n }, []);\n\n const getFiles = useCallback(() => {\n return attachments.map((a) => a.file);\n }, [attachments]);\n\n return {\n attachments,\n addAttachment,\n removeAttachment,\n updateProgress,\n setError,\n setUrl,\n clear,\n getFiles,\n canAddMore: attachments.length < maxCount,\n };\n}\n"]}
|
package/dist/client/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
'use strict';var chunkKSMAVBLY_cjs=require('../chunk-KSMAVBLY.cjs'),react=require('react');function
|
|
1
|
+
'use strict';var chunkKSMAVBLY_cjs=require('../chunk-KSMAVBLY.cjs'),react=require('react');function E(t){return t.baseUrl?t.baseUrl.replace(/\/api\/?$/,""):t.bundleUrl?.includes("localhost")||t.bundleUrl?.includes("127.0.0.1")||false?"http://localhost:8003":"https://api.miiflow.ai"}function U(){let t="miiflow-user-id",n=null;try{n=localStorage.getItem(t);}catch{}if(!n){n=`muid_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;try{localStorage.setItem(t,n);}catch{}}return n}async function ue(t){let n=E(t),u=await fetch(`${n}/api/embed/init`,{method:"POST",headers:{"Content-Type":"application/json","X-Embed-Public-Key":t.publicKey,"x-mii-user-id":U()},body:JSON.stringify({assistant_id:t.assistantId,user_data:{user_id:t.userId,name:t.userName,email:t.userEmail}})});if(!u.ok){let p=await u.text();throw new Error(`Init failed: ${u.status} - ${p}`)}let c=await u.json();if(!c.success)throw new Error(c.error||"Failed to initialize session");return {token:c.token,config:c.config,session_id:c.session_id}}async function ce(t,n){let u=E(t),c=await fetch(`${u}/api/embed/graphql`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`,"x-mii-user-id":U()},body:JSON.stringify({operationName:"CreateThread",variables:{input:{assistantId:n.config.assistant_id,name:"New Thread",isPreview:false}},query:`mutation CreateThread($input: CreateThreadInput!) {
|
|
2
2
|
createThread(input: $input) {
|
|
3
3
|
thread { id status name isPreview }
|
|
4
4
|
}
|
|
5
|
-
}`})});if(!
|
|
6
|
-
`);
|
|
7
|
-
`)?Z="":Z=
|
|
8
|
-
`).replace(/\\"/g,'"').replace(/\\t/g," ").replace(/\\\\/g,"\\"));}else if(i==="answer"){let n=e.chunk?.trim()||"",l=g.trim();n&&l&&n===l||(g+=e.chunk||"");}else C+=e.chunk||"";e.previous_message_id&&d.onUserMessageIdUpdate(u,e.previous_message_id),o();}else if(e.type==="claude_text"){g+=e.chunk||"";let i=s.find(n=>n.type==="claude_text");i?i.content+=e.chunk||"":s.push({type:"claude_text",content:e.chunk||"",orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_thinking")s.push({type:"claude_thinking",content:e.content||"",orchestrator:"claude_agent_sdk"}),o();else if(e.type==="claude_file_read"){let i={toolUseId:e.tool_use_id,operation:"read",filePath:e.file_path,status:e.status,content:e.content,totalLines:e.total_lines,language:e.language,error:e.error,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);n>=0?s[n].fileOperationData=i:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_file_edit"){let i={toolUseId:e.tool_use_id,operation:"edit",filePath:e.file_path,status:e.status,oldString:e.old_string,newString:e.new_string,error:e.error,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);n>=0?s[n].fileOperationData=i:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_file_write"){let i={toolUseId:e.tool_use_id,operation:"write",filePath:e.file_path,status:e.status,error:e.error,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);n>=0?s[n].fileOperationData=i:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_bash"){let i={toolUseId:e.tool_use_id,command:e.command,description:e.description,status:e.status,stdout:e.stdout,stderr:e.stderr,exitCode:e.exit_code,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="terminal"&&l.toolUseId===e.tool_use_id);n>=0?s[n].terminalData=i:s.push({type:"terminal",content:"",toolUseId:e.tool_use_id,terminalData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_search"){let i={toolUseId:e.tool_use_id,tool:e.tool,pattern:e.pattern,path:e.path,status:e.status,results:(e.results||[]).map(l=>({filePath:l.file_path,lineNumber:l.line_number,snippet:l.snippet})),totalCount:e.total_count||0,error:e.error,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="search_results"&&l.toolUseId===e.tool_use_id);n>=0?s[n].searchResultsData=i:s.push({type:"search_results",content:"",toolUseId:e.tool_use_id,searchResultsData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_web_search"||e.type==="claude_web_fetch"){let i={toolUseId:e.tool_use_id,operation:e.type==="claude_web_search"?"search":"fetch",query:e.query,url:e.url,status:e.status,results:e.results,content:e.content,error:e.error,durationMs:e.duration_ms},n=s.findIndex(l=>l.type==="web_operation"&&l.toolUseId===e.tool_use_id);n>=0?s[n].webOperationData=i:s.push({type:"web_operation",content:"",toolUseId:e.tool_use_id,webOperationData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_subagent_start"){let i={subagentId:e.subagent_id,subagentType:e.subagent_type,description:e.description,prompt:e.prompt,status:"running",nestedChunks:[]};s.push({type:"subagent",content:"",toolUseId:e.parent_tool_use_id,subagentData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_subagent_chunk"){let i=s.findIndex(n=>n.type==="subagent"&&n.subagentData?.subagentId===e.subagent_id);i>=0&&s[i].subagentData&&s[i].subagentData.nestedChunks.push({type:e.is_tool?"tool":"answer",content:e.chunk||"",toolName:e.tool_name,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="claude_subagent_complete"){let i=s.findIndex(n=>n.type==="subagent"&&n.subagentData?.subagentId===e.subagent_id);i>=0&&s[i].subagentData&&(s[i].subagentData.status="completed",s[i].subagentData.result=e.result,s[i].subagentData.durationMs=e.duration_ms),o();}else if(e.type==="claude_tool_use"||e.type==="claude_tool_result"){let i={toolUseId:e.tool_use_id,toolName:e.tool_name,toolDescription:e.tool_description,toolInput:e.tool_input,status:e.type==="claude_tool_use"?"pending":e.is_error?"error":"completed",content:e.content,isError:e.is_error,durationMs:e.duration_ms},n=s.findIndex(l=>l.claudeToolData?.toolUseId===e.tool_use_id);n>=0?s[n].claudeToolData=i:s.push({type:"tool",content:e.content||"",toolUseId:e.tool_use_id,toolName:e.tool_name,toolDescription:e.tool_description,status:i.status==="pending"?"planned":"completed",claudeToolData:i,orchestrator:"claude_agent_sdk"}),o();}else if(e.type==="clarification_needed"){N();let i={question:e.question||"",options:e.options||[],context:e.context,allowFreeText:e.allow_free_text!==!1,subtaskId:e.subtask_id,subtaskDescription:e.subtask_description,subagentName:e.subagent_name,subagentRole:e.subagent_role};s.push({type:"clarification_needed",content:i.question,clarificationData:i,subtaskId:e.subtask_id}),B=i,g||(g=i.question),o();}else if(e.type==="assistant_complete"){N(),K=!0;let i=e.message?.text_content||g,n=e.message?.id,l=e.message?.metadata?.sources;d.onComplete(f,i,n,s,v,l,B),g=i,n&&(f=n);break}else if(e.type==="client_tool_invocation"&&e.invocation&&d.onToolInvocation)d.onToolInvocation(e.invocation);else {if(e.type==="error")throw new Error(e.error||"Stream error");if(e.type==="done"){f&&!K?(N(),d.onComplete(f,g||"",e.message_id,s,v,void 0,B)):e.message_id&&f&&d.onMessageUpdate({id:f,isStreaming:!1}),e.message_id&&(f=e.message_id);break}}}catch(e){if(e instanceof Error&&e.message!=="Stream error"&&(e.message.startsWith("Stream error")||e.message.startsWith("HTTP error")))throw e}}}return {assistantMsgId:f,assistantContent:g}}function Ee(t){let[a,u]=react.useState([]),[d,p]=react.useState(false),[g,f]=react.useState(null),[s,v]=react.useState(null),[B,K]=react.useState(true),[T,C]=react.useState(null),m=react.useRef(t);m.current=t;let S=react.useRef(s);S.current=s;let j=react.useRef(d);j.current=d;let E=react.useRef(new Map),I=react.useRef(new Map);react.useEffect(()=>{let r=false;async function o(){try{let c=await ue(m.current);r||(v(c),K(!1));}catch(c){r||(C(c instanceof Error?c.message:"Failed to initialize"),K(false));}}return o(),()=>{r=true;}},[t.publicKey,t.assistantId]);let z=react.useMemo(()=>Ae(s),[s]),W=chunkKSMAVBLY_cjs.b(z),P=react.useRef(new Map),q=react.useCallback(async r=>{let o=S.current;if(!o)throw new Error("Not initialized");let c=await de(m.current,o,r);return P.current.set(c,{id:c,filename:r.name,mimeType:r.type,size:r.size,isImage:r.type.startsWith("image/"),isVideo:r.type.startsWith("video/"),isDocument:!r.type.startsWith("image/")&&!r.type.startsWith("video/")}),c},[]),J=react.useCallback(r=>{P.current.delete(r);},[]),O=react.useCallback(async r=>{let o=S.current;if(!o)throw new Error("Not initialized");let{invocation_id:c,tool_name:h,parameters:D}=r;console.log(`[Miiflow] Tool invocation received: "${h}" (id: ${c})`);let _=E.current.get(h);if(!_)return false;try{let w=await Promise.race([_(D),new Promise((F,k)=>setTimeout(()=>k(new Error("Tool execution timeout (30s)")),3e4))]);return console.log(`[Miiflow] Tool "${h}" executed successfully (id: ${c})`),await V(m.current,o,{invocation_id:c,result:w}),console.log(`[Miiflow] Tool result sent for "${h}" (id: ${c})`),!0}catch(w){return console.error(`[Miiflow] Tool '${h}' execution failed:`,w),await V(m.current,o,{invocation_id:c,error:w instanceof Error?w.message:String(w)}),true}},[]);react.useEffect(()=>{if(!s)return;let r=s,o=null,c=null,h=null,D=0,_=false;function w(){if(_)return;let F=ve(m.current,r);o=new WebSocket(F),o.onopen=()=>{console.log("[Miiflow] WebSocket connected"),D=0,c=setInterval(()=>{o?.readyState===WebSocket.OPEN&&o.send(JSON.stringify({type:"heartbeat"}));},Ie);},o.onmessage=k=>{try{let e=JSON.parse(k.data);e.type==="client_tool_invocation"&&e.invocation&&O(e.invocation).then(async i=>{if(!i){let n=m.current.onToolInvocationFallback;n&&await n(e.invocation)||V(m.current,r,{invocation_id:e.invocation.invocation_id,error:`No handler found for tool '${e.invocation.tool_name}'`}).catch(console.error);}}).catch(console.error);}catch{}},o.onclose=()=>{if(c&&(clearInterval(c),c=null),!_){let k=Math.min(De*Math.pow(2,D),xe);D++,console.log(`[Miiflow] WebSocket closed, reconnecting in ${k}ms`),h=setTimeout(w,k);}},o.onerror=k=>{console.error("[Miiflow] WebSocket error:",k);};}return w(),()=>{_=true,c&&clearInterval(c),h&&clearTimeout(h),o&&(o.onclose=null,o.close());}},[s,O]);let H=react.useCallback(async r=>{let o=S.current;if(!o)throw new Error("Not initialized");await pe(m.current,o,r);},[]),L=react.useCallback(async(r,o)=>{let c=S.current,h=!!r.trim(),D=o&&o.length>0;if(!h&&!D||j.current||!c)return;let _=`msg-${Date.now()}`,w=o?.map(i=>P.current.get(i)).filter(Boolean),F={id:_,textContent:r,participant:{id:"user",name:m.current.userName||"You",role:"user"},createdAt:new Date().toISOString(),attachments:w?.length?w:void 0};o?.forEach(i=>P.current.delete(i));let k=`assistant-pending-${Date.now()}`,e={id:k,textContent:"",participant:{id:"assistant",name:c.config.branding?.custom_name||c.config.assistant_name,role:"assistant",avatarUrl:c.config.branding?.assistant_avatar},createdAt:new Date().toISOString(),isStreaming:true};u(i=>[...i,F,e]),p(true),f(k),m.current.onUserMessageCreated?.({id:_,content:r});try{let i=M(m.current),n=await fetch(`${i}/assistant/message/stream/`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${c.token}`,"x-mii-user-id":U()},body:JSON.stringify({thread_id:c.config.thread_id,text_content:r,message_id:_,metadata:{},attachment_ids:o||[]})});if(!n.ok)throw new Error(`HTTP error: ${n.status}`);let l=n.body?.getReader();if(!l)throw new Error("No response body");let ne=await Me(l,c,_,{onMessageCreate:y=>{f(y.id),u(x=>[...x.filter(R=>R.id!==k),y]);},onMessageUpdate:y=>{u(x=>x.map(A=>A.id===y.id?{...A,...y}:A));},onUserMessageIdUpdate:(y,x)=>{u(A=>A.map(R=>R.id===y?{...R,id:x}:R));},onComplete:(y,x,A,R,ae,_e,be)=>{y&&u(we=>we.map(se=>se.id===y?{...se,id:A||se.id,textContent:x,isStreaming:!1,reasoning:R,suggestedActions:ae,citations:_e,pendingClarification:be}:se)),m.current.onAssistantMessageComplete?.({id:A||y||"",content:x});},onToolInvocation:async y=>{if(!await O(y)){let A=m.current.onToolInvocationFallback;if(!(A?await A(y):!1)){let ae=S.current;ae&&await V(m.current,ae,{invocation_id:y.invocation_id,error:`No handler found for tool '${y.tool_name}'`});}}}});ne.assistantMsgId&&u(y=>y.map(x=>x.id===ne.assistantMsgId?{...x,isStreaming:!1}:x));}catch(i){console.error("[Miiflow] Send error:",i);let n=S.current,l={id:`error-${Date.now()}`,textContent:"Sorry, I encountered an error. Please try again.",participant:{id:"assistant",name:n?.config.branding?.custom_name||n?.config.assistant_name||"Assistant",role:"assistant",avatarUrl:n?.config.branding?.assistant_avatar},createdAt:new Date().toISOString()};u(ne=>[...ne.filter(y=>y.id!==k),l]),C(i instanceof Error?i.message:"Send failed");}finally{p(false),f(null);}},[O]),X=react.useCallback(async()=>{let r=S.current;if(!r)throw new Error("Not initialized");let o=await ce(m.current,r);o.token||console.warn("[Miiflow] CreateThread did not return new token \u2014 tools may register to wrong thread");let c={...r,config:{...r.config,thread_id:o.threadId},token:o.token||r.token};if(S.current=c,v(c),u([]),I.current.size>0){console.log(`[Miiflow] Re-registering ${I.current.size} tools on new thread`);try{await Q(m.current,c,Array.from(I.current.values()));}catch(h){console.warn("[Miiflow] Failed to re-register tools:",h);}}return o.threadId},[]),ee=react.useCallback(async r=>{let o=S.current;if(!o)throw new Error("Not initialized");ie(r),E.current.set(r.name,r.handler);let c=re(r);I.current.set(r.name,c);try{await Q(m.current,o,[c]),console.log(`[Miiflow] Tool registered: "${r.name}"`);}catch(h){throw E.current.delete(r.name),I.current.delete(r.name),h}},[]),Z=react.useCallback(async r=>{let o=S.current;if(!o)throw new Error("Not initialized");for(let _ of r)ie(_);let c=new Map(E.current),h=new Map(I.current),D=[];for(let _ of r){E.current.set(_.name,_.handler);let w=re(_);I.current.set(_.name,w),D.push(w);}try{await Q(m.current,o,D);let _=r.map(w=>w.name);console.log(`[Miiflow] Tools registered: ${JSON.stringify(_)} (${r.length} tools)`);}catch(_){throw E.current=c,I.current=h,_}},[]),te=react.useMemo(()=>a.map(r=>({id:r.id,textContent:r.textContent?.replace(/\[ref:[^\]]+\]/g,"")||r.textContent,participant:r.participant,createdAt:r.createdAt,isStreaming:r.isStreaming,reasoning:r.reasoning,suggestedActions:r.suggestedActions,citations:r.citations,attachments:r.attachments,pendingClarification:r.pendingClarification})),[a]),N=react.useCallback(r=>{v(r);},[]);return {messages:te,isStreaming:d,streamingMessageId:g,sendMessage:L,uploadFile:q,removeUploadedAttachment:J,session:s,loading:B,error:T,branding:z,brandingCSSVars:W,startNewThread:X,registerTool:ee,registerTools:Z,sendSystemEvent:H,handleToolInvocation:O,updateSession:N}}function le(t){try{let a=t.split(".");if(a.length!==3)return null;let u=a[1].replace(/-/g,"+").replace(/_/g,"/"),d=atob(u),p=JSON.parse(d);return typeof p.exp=="number"?p.exp*1e3:null}catch{return null}}function Oe(t,a){let u=le(t);return u===null?true:u-Date.now()<=a}function Pe(t){let a=le(t);return a===null?true:Date.now()>=a}function Ne(t){let a=le(t);return a===null?0:Math.max(0,a-Date.now())}exports.ToolValidationError=b;exports.createThread=ce;exports.getBackendBaseUrl=M;exports.getOrCreateUserId=U;exports.getTimeUntilExpiry=Ne;exports.initSession=ue;exports.isTokenExpired=Pe;exports.isTokenExpiringSoon=Oe;exports.parseTokenExpiry=le;exports.registerToolsOnBackend=Q;exports.sendSystemEvent=pe;exports.sendToolResult=V;exports.serializeToolDefinition=re;exports.updateUser=ye;exports.uploadFile=de;exports.useMiiflowChat=Ee;exports.validateToolDefinition=ie;//# sourceMappingURL=index.cjs.map
|
|
5
|
+
}`})});if(!c.ok)throw new Error(`Failed to create thread: ${c.status}`);let p=await c.json(),_=p.data?.createThread?.thread?.id;if(!_)throw new Error("No thread ID returned");return {threadId:_,token:p.token}}async function ke(t,n,u){let c=E(t);await fetch(`${c}/api/embed/update`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`},body:JSON.stringify({user_data:u})});}async function de(t,n,u){let p=`${E(t)}/api/embed/upload-attachment`,_=new FormData;_.append("file",u);let f=await fetch(p,{method:"POST",headers:{Authorization:`Bearer ${n.token}`,"x-mii-user-id":U()},body:_});if(!f.ok){let P=await f.text();throw new Error(`Upload failed: ${f.status} - ${P}`)}let s=(await f.json()).attachment?.id;if(!s)throw new Error("No attachment ID returned");return s}async function pe(t,n,u){let c=E(t),p=await fetch(`${c}/api/embed/system-event`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`,"x-mii-user-id":U()},body:JSON.stringify({thread_id:n.config.thread_id,system_event:{action:u.action,description:u.description,followUpInstruction:u.followUpInstruction,metadata:u.metadata||{}}})});if(!p.ok){let f=await p.text();throw new Error(`Failed to send system event: ${p.status} - ${f}`)}let _=await p.json();if(!_.success)throw new Error(_.error||"Failed to send system event")}async function G(t,n,u){let c=E(t),p=await fetch(`${c}/api/embed/tool-result`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`},body:JSON.stringify(u)});if(!p.ok){let f=await p.text();throw new Error(`Failed to send tool result: ${p.status} - ${f}`)}let _=await p.json();if(!_.success)throw new Error(`Failed to send tool result: ${_.error}`)}async function Q(t,n,u){let c=E(t);if(u.length===1){let p=await fetch(`${c}/api/embed/register-tool`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`},body:JSON.stringify(u[0])});if(!p.ok){let f=await p.text();throw new Error(`Failed to register tool: ${p.status} - ${f}`)}let _=await p.json();if(!_.success)throw new Error(`Failed to register tool: ${_.error||"Unknown error"}`)}else if(u.length>1){let p=await fetch(`${c}/api/embed/register-tools`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.token}`},body:JSON.stringify(u)});if(!p.ok){let f=await p.text();throw new Error(`Failed to register tools: ${p.status} - ${f}`)}let _=await p.json();if(!_.success)throw new Error(`Failed to register tools: ${_.error||"Unknown error"}`)}}var ge=new Set(["string","number","integer","boolean","array","object","null"]),Se=/^[a-zA-Z_][a-zA-Z0-9_]*$/,y=class extends Error{constructor(n){super(n),this.name="ToolValidationError";}};function ie(t){if(!t.name)throw new y("Tool name is required");if(!t.description)throw new y("Tool description is required");if(!t.parameters)throw new y("Tool parameters schema is required");if(typeof t.handler!="function")throw new y("Tool handler must be a function");Ce(t.name),Te(t.description),Ie(t.parameters);}function Ce(t){if(typeof t!="string")throw new y("Tool name must be a string");if(t.length===0)throw new y("Tool name cannot be empty");if(t.length>64)throw new y("Tool name too long (max 64 characters)");if(!Se.test(t))throw new y("Tool name must start with letter/underscore and contain only alphanumeric characters and underscores")}function Te(t){if(typeof t!="string")throw new y("Tool description must be a string");if(t.trim().length===0)throw new y("Tool description cannot be empty");if(t.length>500)throw new y("Tool description too long (max 500 characters)")}function Ie(t){if(typeof t!="object"||t===null||Array.isArray(t))throw new y("Parameters must be a JSON Schema object");if(t.type!=="object")throw new y("Parameters schema must be of type 'object' (function parameters)");if(t.properties&&typeof t.properties=="object")for(let[n,u]of Object.entries(t.properties))oe(n,u);if(t.required!==void 0){if(!Array.isArray(t.required))throw new y("'required' must be an array");for(let n of t.required)if(typeof n!="string")throw new y("'required' array must contain only strings")}if(t.additionalProperties!==void 0&&typeof t.additionalProperties!="boolean"&&(typeof t.additionalProperties!="object"||t.additionalProperties===null))throw new y("'additionalProperties' must be boolean or object")}function oe(t,n){if(typeof n!="object"||n===null||Array.isArray(n))throw new y(`Property '${t}' schema must be an object`);if(n.type!==void 0){let u=Array.isArray(n.type)?n.type:[n.type];for(let c of u)if(!ge.has(c))throw new y(`Invalid type '${c}' for property '${t}'. Valid types: ${Array.from(ge).join(", ")}`)}if(n.enum!==void 0&&!Array.isArray(n.enum))throw new y(`Property '${t}' enum must be an array`);if(n.properties&&typeof n.properties=="object")for(let[u,c]of Object.entries(n.properties))oe(`${t}.${u}`,c);n.items&&(Array.isArray(n.items)?n.items.forEach((u,c)=>{oe(`${t}[${c}]`,u);}):oe(`${t}[]`,n.items));}function re(t){return {name:t.name,description:t.description,parameters:t.parameters}}var De=21e3,xe=1e3,ve=3e4;function Ae(t,n){if(t.webSocketUrl){let f=new URL(t.webSocketUrl);return f.pathname=`/ws/assistant/thread/${n.config.thread_id}/`,f.searchParams.set("role","user"),f.searchParams.set("user_id",U()),f.searchParams.set("embed_token",n.token),f.toString()}let p=E(t).replace(/\/api$/,"").replace(/^https:/,"wss:").replace(/^http:/,"ws:"),_=U();return `${p}/ws/assistant/thread/${n.config.thread_id}/?role=user&user_id=${encodeURIComponent(_)}&embed_token=${encodeURIComponent(n.token)}`}function Me(t){let n=t?.config.branding;return n?{customName:n.custom_name,messageFontSize:n.message_font_size,welcomeMessage:n.welcome_message,chatboxPlaceholder:n.chatbox_placeholder,backgroundBubbleColor:n.background_bubble_color,headerBackgroundColor:n.header_background_color,showHeader:n.show_header,rotatingPlaceholders:n.rotating_placeholders,presetQuestions:n.preset_questions,chatbotLogo:n.chatbot_logo,assistantAvatar:n.assistant_avatar}:null}async function Ee(t,n,u,c){let p=new TextDecoder,_=Date.now(),f="",b=null,s=[],P,z,ee=false,I="answer",g="",S,F,A,x,B,W,N,q,J,O,H,L,X,V,te=false,Z="",ne=n.config.branding,o=()=>{(g||I==="tool")&&(s.push({type:I,content:g,toolName:S,toolDescription:F,success:A,status:x,subtaskId:B,planData:W,subtaskData:N,isSynthesis:q,isReplan:J,toolArgs:O,replanAttempt:H,maxReplans:L,failureReason:X,progress:V}),g="",S=void 0,F=void 0,A=void 0,x=void 0,B=void 0,W=void 0,N=void 0,q=void 0,J=void 0,O=void 0,H=void 0,L=void 0,X=void 0,V=void 0);},d=()=>{let m=s.map(C=>C);return (g||I==="tool")&&m.push({type:I,content:g,toolName:S,toolDescription:F,success:A,status:x,subtaskId:B,planData:W,subtaskData:N,isSynthesis:q,isReplan:J,toolArgs:O,replanAttempt:H,maxReplans:L,failureReason:X,progress:V}),m},i=()=>{let m=d();if(b)c.onMessageUpdate({id:b,textContent:f,reasoning:m,suggestedActions:P});else {b=`assistant-${Date.now()}`;let C={id:b,textContent:f,participant:{id:"assistant",name:ne?.custom_name||n.config.assistant_name,role:"assistant",avatarUrl:ne?.assistant_avatar},createdAt:new Date().toISOString(),isStreaming:true,reasoning:m,suggestedActions:P};c.onMessageCreate(C);}};for(;;){let{done:m,value:C}=await t.read();if(m)break;let h=p.decode(C,{stream:true}),j=(Z+h).split(`
|
|
6
|
+
`);h.endsWith(`
|
|
7
|
+
`)?Z="":Z=j.pop()||"";for(let T of j){if(!T.startsWith("data: "))continue;let M=T.slice(6);if(M==="[DONE]")break;try{let e=JSON.parse(M);if(e.type==="assistant_chunk"){if(e.is_tool_planned){(g||I!=="answer")&&(o(),I="answer"),s.push({type:"tool",content:"",toolName:e.tool_name,toolDescription:e.tool_description,status:"planned",subtaskId:e.subtask_id}),i();continue}if(e.is_tool_executing){for(let a=s.length-1;a>=0;a--){let l=s[a];if(l.type==="tool"&&l.toolName===e.tool_name&&(e.subtask_id===void 0||l.subtaskId===e.subtask_id)){s[a].status="executing";break}}i();continue}if(e.is_observation){for(let a=s.length-1;a>=0;a--){let l=s[a];if(l.type==="tool"&&l.toolName===e.tool_name&&(e.subtask_id===void 0||l.subtaskId===e.subtask_id)){s[a].status="completed";break}}i();continue}if(e.suggested_actions){P=e.suggested_actions.map(a=>({id:a.action,label:a.label,value:a.action})),i();continue}if(e.is_wave_start){(g||I!=="answer")&&(o(),I="answer"),s.push({type:"wave_start",content:"",waveNumber:e.wave_number,isParallel:!0,waveData:{waveNumber:e.wave_number,subtaskIds:e.subtask_ids||[],parallelCount:e.parallel_count||0,totalWaves:e.total_waves||1}}),i();continue}if(e.is_wave_complete){s.push({type:"wave_complete",content:"",waveNumber:e.wave_number,isParallel:!0,waveData:{waveNumber:e.wave_number,subtaskIds:[],parallelCount:0,totalWaves:0,completedIds:e.completed_ids||[],success:e.success,executionTime:e.execution_time}}),i();continue}if(e.is_parallel_subtask_start){s.push({type:"parallel_subtask_start",content:"",subtaskId:e.subtask_id,waveNumber:e.wave_number,isParallel:!0,parallelSubtaskData:{subtaskId:e.subtask_id,waveNumber:e.wave_number,description:e.description}}),i();continue}if(e.is_parallel_subtask_complete){s.push({type:"parallel_subtask_complete",content:"",subtaskId:e.subtask_id,waveNumber:e.wave_number,isParallel:!0,success:e.success,parallelSubtaskData:{subtaskId:e.subtask_id,waveNumber:e.wave_number,success:e.success,result:e.result,error:e.error,executionTime:e.execution_time}}),i();continue}if(e.is_multi_agent_planning){te=!0,(g||I!=="answer")&&(o(),I="answer"),s.push({type:"multi_agent_planning",content:"",isMultiAgent:!0}),i();continue}if(e.is_reasoning&&e.reasoning_delta){let a=s.findIndex(l=>l.type==="thinking"&&l.isMultiAgent);a>=0?s[a]={...s[a],content:(s[a].content||"")+e.reasoning_delta}:s.push({type:"thinking",content:e.reasoning_delta,isMultiAgent:!0}),i();continue}if(e.is_multi_agent_planning_complete){let a=s.findIndex(l=>l.type==="multi_agent_planning"&&l.isMultiAgent);a>=0?s[a]={...s[a],subagentAllocations:e.subagents||[]}:s.push({type:"multi_agent_planning",content:"",isMultiAgent:!0,subagentAllocations:e.subagents||[]}),i();continue}if(e.is_multi_agent_execution_start)continue;if(e.is_subagent_start){s.push({type:"subagent_start",content:"",isMultiAgent:!0,subagentInfo:{id:e.subagent_id,name:e.subagent_name,task:e.task,status:"running"}}),i();continue}if(e.is_subagent_progress){let a=s.findIndex(l=>l.type==="subagent_start"&&l.subagentInfo?.id===e.subagent_id);a!==-1&&s[a].subagentInfo&&(s[a]={...s[a],content:e.progress||""}),i();continue}if(e.is_subagent_complete){s.push({type:"subagent_complete",content:"",isMultiAgent:!0,subagentInfo:{id:e.subagent_id,name:e.subagent_name,status:"completed",result:e.result,executionTime:e.execution_time}}),i();continue}if(e.is_subagent_failed){s.push({type:"subagent_failed",content:"",isMultiAgent:!0,subagentInfo:{id:e.subagent_id,name:e.subagent_name,status:"failed",error:e.error}}),i();continue}if(e.is_synthesis_start&&te){s.push({type:"synthesis",content:"",isMultiAgent:!0,isSynthesis:!0}),i();continue}if(e.plan_data){let a=e.plan_data;W={goal:a.goal||"",reasoning:a.reasoning||"",subtasks:(a.subtasks||[]).map(l=>({id:Number(l.id),description:l.description,required_tools:l.required_tools,dependencies:l.dependencies,status:"pending"})),total_subtasks:a.subtasks?.length||0,completed_subtasks:0,failed_subtasks:0,progress_percentage:0};}e.subtask_data&&(N=e.subtask_data),e.is_synthesis_start&&(q=!0),e.is_replan&&(J=!0),e.tool_args&&(O=e.tool_args),e.replan_attempt!==void 0&&(H=e.replan_attempt),e.max_replans!==void 0&&(L=e.max_replans),e.failure_reason&&(X=e.failure_reason),e.progress&&(V=e.progress);let r="answer";if(e.is_thinking?r="thinking":e.is_planning||e.is_plan_complete||e.is_replanning?r="planning":e.is_subtask_start||e.is_subtask_complete||e.is_subtask_failed?r="subtask":e.is_progress_update&&(r="progress"),r!==I&&(o(),I=r),e.tool_name&&(S=e.tool_name),e.success!==void 0&&(A=e.success),e.subtask_id!==void 0&&(B=e.subtask_id),r==="thinking"){g+=e.chunk||"";let a=g.match(/"thought"\s*:\s*"((?:[^"\\]|\\.)*)"/);a&&(g=a[1].replace(/\\n/g,`
|
|
8
|
+
`).replace(/\\"/g,'"').replace(/\\t/g," ").replace(/\\\\/g,"\\"));}else if(r==="answer"){let a=e.chunk?.trim()||"",l=f.trim();a&&l&&a===l||(f+=e.chunk||"");}else g+=e.chunk||"";e.previous_message_id&&c.onUserMessageIdUpdate(u,e.previous_message_id),i();}else if(e.type==="claude_text"){f+=e.chunk||"";let r=s.find(a=>a.type==="claude_text");r?r.content+=e.chunk||"":s.push({type:"claude_text",content:e.chunk||"",orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_thinking")s.push({type:"claude_thinking",content:e.content||"",orchestrator:"claude_agent_sdk"}),i();else if(e.type==="claude_file_read"){let r={toolUseId:e.tool_use_id,operation:"read",filePath:e.file_path,status:e.status,content:e.content,totalLines:e.total_lines,language:e.language,error:e.error,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);a>=0?s[a].fileOperationData=r:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_file_edit"){let r={toolUseId:e.tool_use_id,operation:"edit",filePath:e.file_path,status:e.status,oldString:e.old_string,newString:e.new_string,error:e.error,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);a>=0?s[a].fileOperationData=r:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_file_write"){let r={toolUseId:e.tool_use_id,operation:"write",filePath:e.file_path,status:e.status,error:e.error,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="file_operation"&&l.toolUseId===e.tool_use_id);a>=0?s[a].fileOperationData=r:s.push({type:"file_operation",content:"",toolUseId:e.tool_use_id,fileOperationData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_bash"){let r={toolUseId:e.tool_use_id,command:e.command,description:e.description,status:e.status,stdout:e.stdout,stderr:e.stderr,exitCode:e.exit_code,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="terminal"&&l.toolUseId===e.tool_use_id);a>=0?s[a].terminalData=r:s.push({type:"terminal",content:"",toolUseId:e.tool_use_id,terminalData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_search"){let r={toolUseId:e.tool_use_id,tool:e.tool,pattern:e.pattern,path:e.path,status:e.status,results:(e.results||[]).map(l=>({filePath:l.file_path,lineNumber:l.line_number,snippet:l.snippet})),totalCount:e.total_count||0,error:e.error,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="search_results"&&l.toolUseId===e.tool_use_id);a>=0?s[a].searchResultsData=r:s.push({type:"search_results",content:"",toolUseId:e.tool_use_id,searchResultsData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_web_search"||e.type==="claude_web_fetch"){let r={toolUseId:e.tool_use_id,operation:e.type==="claude_web_search"?"search":"fetch",query:e.query,url:e.url,status:e.status,results:e.results,content:e.content,error:e.error,durationMs:e.duration_ms},a=s.findIndex(l=>l.type==="web_operation"&&l.toolUseId===e.tool_use_id);a>=0?s[a].webOperationData=r:s.push({type:"web_operation",content:"",toolUseId:e.tool_use_id,webOperationData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_subagent_start"){let r={subagentId:e.subagent_id,subagentType:e.subagent_type,description:e.description,prompt:e.prompt,status:"running",nestedChunks:[]};s.push({type:"subagent",content:"",toolUseId:e.parent_tool_use_id,subagentData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_subagent_chunk"){let r=s.findIndex(a=>a.type==="subagent"&&a.subagentData?.subagentId===e.subagent_id);r>=0&&s[r].subagentData&&s[r].subagentData.nestedChunks.push({type:e.is_tool?"tool":"answer",content:e.chunk||"",toolName:e.tool_name,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="claude_subagent_complete"){let r=s.findIndex(a=>a.type==="subagent"&&a.subagentData?.subagentId===e.subagent_id);r>=0&&s[r].subagentData&&(s[r].subagentData.status="completed",s[r].subagentData.result=e.result,s[r].subagentData.durationMs=e.duration_ms),i();}else if(e.type==="claude_tool_use"||e.type==="claude_tool_result"){let r={toolUseId:e.tool_use_id,toolName:e.tool_name,toolDescription:e.tool_description,toolInput:e.tool_input,status:e.type==="claude_tool_use"?"pending":e.is_error?"error":"completed",content:e.content,isError:e.is_error,durationMs:e.duration_ms},a=s.findIndex(l=>l.claudeToolData?.toolUseId===e.tool_use_id);a>=0?s[a].claudeToolData=r:s.push({type:"tool",content:e.content||"",toolUseId:e.tool_use_id,toolName:e.tool_name,toolDescription:e.tool_description,status:r.status==="pending"?"planned":"completed",claudeToolData:r,orchestrator:"claude_agent_sdk"}),i();}else if(e.type==="clarification_needed"){o();let r={question:e.question||"",options:e.options||[],context:e.context,allowFreeText:e.allow_free_text!==!1,subtaskId:e.subtask_id,subtaskDescription:e.subtask_description,subagentName:e.subagent_name,subagentRole:e.subagent_role};s.push({type:"clarification_needed",content:r.question,clarificationData:r,subtaskId:e.subtask_id}),z=r,f||(f=r.question),i();}else if(e.type==="assistant_complete"){o(),ee=!0;let r=e.message?.text_content||f,a=e.message?.id,l=e.message?.metadata?.sources,w=(Date.now()-_)/1e3;c.onComplete(b,r,a,s,P,l,z,w),f=r,a&&(b=a);break}else if(e.type==="client_tool_invocation"&&e.invocation&&c.onToolInvocation)c.onToolInvocation(e.invocation);else {if(e.type==="error")throw new Error(e.error||"Stream error");if(e.type==="done"){if(b&&!ee){o();let r=(Date.now()-_)/1e3;c.onComplete(b,f||"",e.message_id,s,P,void 0,z,r);}else e.message_id&&b&&c.onMessageUpdate({id:b,isStreaming:!1});e.message_id&&(b=e.message_id);break}}}catch(e){if(e instanceof Error&&e.message!=="Stream error"&&(e.message.startsWith("Stream error")||e.message.startsWith("HTTP error")))throw e}}}return {assistantMsgId:b,assistantContent:f}}function Oe(t){let[n,u]=react.useState([]),[c,p]=react.useState(false),[_,f]=react.useState(null),[b,s]=react.useState(null),[P,z]=react.useState(true),[ee,I]=react.useState(null),g=react.useRef(t);g.current=t;let S=react.useRef(b);S.current=b;let F=react.useRef(c);F.current=c;let A=react.useRef(new Map),x=react.useRef(new Map);react.useEffect(()=>{let o=false;async function d(){try{let i=await ue(g.current);o||(s(i),z(!1));}catch(i){o||(I(i instanceof Error?i.message:"Failed to initialize"),z(false));}}return d(),()=>{o=true;}},[t.publicKey,t.assistantId]);let B=react.useMemo(()=>Me(b),[b]),W=chunkKSMAVBLY_cjs.b(B),N=react.useRef(new Map),q=react.useCallback(async o=>{let d=S.current;if(!d)throw new Error("Not initialized");let i=await de(g.current,d,o);return N.current.set(i,{id:i,filename:o.name,mimeType:o.type,size:o.size,isImage:o.type.startsWith("image/"),isVideo:o.type.startsWith("video/"),isDocument:!o.type.startsWith("image/")&&!o.type.startsWith("video/")}),i},[]),J=react.useCallback(o=>{N.current.delete(o);},[]),O=react.useCallback(async o=>{let d=S.current;if(!d)throw new Error("Not initialized");let{invocation_id:i,tool_name:m,parameters:C}=o;console.log(`[Miiflow] Tool invocation received: "${m}" (id: ${i})`);let h=A.current.get(m);if(!h)return false;try{let k=await Promise.race([h(C),new Promise((j,T)=>setTimeout(()=>T(new Error("Tool execution timeout (30s)")),3e4))]);return console.log(`[Miiflow] Tool "${m}" executed successfully (id: ${i})`),await G(g.current,d,{invocation_id:i,result:k}),console.log(`[Miiflow] Tool result sent for "${m}" (id: ${i})`),!0}catch(k){return console.error(`[Miiflow] Tool '${m}' execution failed:`,k),await G(g.current,d,{invocation_id:i,error:k instanceof Error?k.message:String(k)}),true}},[]);react.useEffect(()=>{if(!b)return;let o=b,d=null,i=null,m=null,C=0,h=false;function k(){if(h)return;let j=Ae(g.current,o);d=new WebSocket(j),d.onopen=()=>{console.log("[Miiflow] WebSocket connected"),C=0,i=setInterval(()=>{d?.readyState===WebSocket.OPEN&&d.send(JSON.stringify({type:"heartbeat"}));},De);},d.onmessage=T=>{try{let M=JSON.parse(T.data);M.type==="client_tool_invocation"&&M.invocation&&O(M.invocation).then(async e=>{if(!e){let r=g.current.onToolInvocationFallback;r&&await r(M.invocation)||G(g.current,o,{invocation_id:M.invocation.invocation_id,error:`No handler found for tool '${M.invocation.tool_name}'`}).catch(console.error);}}).catch(console.error);}catch{}},d.onclose=()=>{if(i&&(clearInterval(i),i=null),!h){let T=Math.min(xe*Math.pow(2,C),ve);C++,console.log(`[Miiflow] WebSocket closed, reconnecting in ${T}ms`),m=setTimeout(k,T);}},d.onerror=T=>{console.error("[Miiflow] WebSocket error:",T);};}return k(),()=>{h=true,i&&clearInterval(i),m&&clearTimeout(m),d&&(d.onclose=null,d.close());}},[b,O]);let H=react.useCallback(async o=>{let d=S.current;if(!d)throw new Error("Not initialized");await pe(g.current,d,o);},[]),L=react.useCallback(async(o,d)=>{let i=S.current,m=!!o.trim(),C=d&&d.length>0;if(!m&&!C||F.current||!i)return;let h=`msg-${Date.now()}`,k=d?.map(e=>N.current.get(e)).filter(Boolean),j={id:h,textContent:o,participant:{id:"user",name:g.current.userName||"You",role:"user"},createdAt:new Date().toISOString(),attachments:k?.length?k:void 0};d?.forEach(e=>N.current.delete(e));let T=`assistant-pending-${Date.now()}`,M={id:T,textContent:"",participant:{id:"assistant",name:i.config.branding?.custom_name||i.config.assistant_name,role:"assistant",avatarUrl:i.config.branding?.assistant_avatar},createdAt:new Date().toISOString(),isStreaming:true};u(e=>[...e,j,M]),p(true),f(T),g.current.onUserMessageCreated?.({id:h,content:o});try{let e=E(g.current),r=await fetch(`${e}/assistant/message/stream/`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i.token}`,"x-mii-user-id":U()},body:JSON.stringify({thread_id:i.config.thread_id,text_content:o,message_id:h,metadata:{},attachment_ids:d||[]})});if(!r.ok)throw new Error(`HTTP error: ${r.status}`);let a=r.body?.getReader();if(!a)throw new Error("No response body");let l=await Ee(a,i,h,{onMessageCreate:w=>{f(w.id),u(D=>[...D.filter(R=>R.id!==T),w]);},onMessageUpdate:w=>{u(D=>D.map(v=>v.id===w.id?{...v,...w}:v));},onUserMessageIdUpdate:(w,D)=>{u(v=>v.map(R=>R.id===w?{...R,id:D}:R));},onComplete:(w,D,v,R,ae,_e,be,we)=>{w&&u(ye=>ye.map(se=>se.id===w?{...se,id:v||se.id,textContent:D,isStreaming:!1,reasoning:R,suggestedActions:ae,citations:_e,pendingClarification:be,executionTime:we}:se)),g.current.onAssistantMessageComplete?.({id:v||w||"",content:D});},onToolInvocation:async w=>{if(!await O(w)){let v=g.current.onToolInvocationFallback;if(!(v?await v(w):!1)){let ae=S.current;ae&&await G(g.current,ae,{invocation_id:w.invocation_id,error:`No handler found for tool '${w.tool_name}'`});}}}});l.assistantMsgId&&u(w=>w.map(D=>D.id===l.assistantMsgId?{...D,isStreaming:!1}:D));}catch(e){console.error("[Miiflow] Send error:",e);let r=S.current,a={id:`error-${Date.now()}`,textContent:"Sorry, I encountered an error. Please try again.",participant:{id:"assistant",name:r?.config.branding?.custom_name||r?.config.assistant_name||"Assistant",role:"assistant",avatarUrl:r?.config.branding?.assistant_avatar},createdAt:new Date().toISOString()};u(l=>[...l.filter(w=>w.id!==T),a]),I(e instanceof Error?e.message:"Send failed");}finally{p(false),f(null);}},[O]),X=react.useCallback(async()=>{let o=S.current;if(!o)throw new Error("Not initialized");let d=await ce(g.current,o);d.token||console.warn("[Miiflow] CreateThread did not return new token \u2014 tools may register to wrong thread");let i={...o,config:{...o.config,thread_id:d.threadId},token:d.token||o.token};if(S.current=i,s(i),u([]),x.current.size>0){console.log(`[Miiflow] Re-registering ${x.current.size} tools on new thread`);try{await Q(g.current,i,Array.from(x.current.values()));}catch(m){console.warn("[Miiflow] Failed to re-register tools:",m);}}return d.threadId},[]),V=react.useCallback(async o=>{let d=S.current;if(!d)throw new Error("Not initialized");ie(o),A.current.set(o.name,o.handler);let i=re(o);x.current.set(o.name,i);try{await Q(g.current,d,[i]),console.log(`[Miiflow] Tool registered: "${o.name}"`);}catch(m){throw A.current.delete(o.name),x.current.delete(o.name),m}},[]),te=react.useCallback(async o=>{let d=S.current;if(!d)throw new Error("Not initialized");for(let h of o)ie(h);let i=new Map(A.current),m=new Map(x.current),C=[];for(let h of o){A.current.set(h.name,h.handler);let k=re(h);x.current.set(h.name,k),C.push(k);}try{await Q(g.current,d,C);let h=o.map(k=>k.name);console.log(`[Miiflow] Tools registered: ${JSON.stringify(h)} (${o.length} tools)`);}catch(h){throw A.current=i,x.current=m,h}},[]),Z=react.useMemo(()=>n.map(o=>({id:o.id,textContent:o.textContent?.replace(/\[ref:[^\]]+\]/g,"")||o.textContent,participant:o.participant,createdAt:o.createdAt,isStreaming:o.isStreaming,reasoning:o.reasoning,suggestedActions:o.suggestedActions,citations:o.citations,attachments:o.attachments,pendingClarification:o.pendingClarification,executionTime:o.executionTime})),[n]),ne=react.useCallback(o=>{s(o);},[]);return {messages:Z,isStreaming:c,streamingMessageId:_,sendMessage:L,uploadFile:q,removeUploadedAttachment:J,session:b,loading:P,error:ee,branding:B,brandingCSSVars:W,startNewThread:X,registerTool:V,registerTools:te,sendSystemEvent:H,handleToolInvocation:O,updateSession:ne}}function le(t){try{let n=t.split(".");if(n.length!==3)return null;let u=n[1].replace(/-/g,"+").replace(/_/g,"/"),c=atob(u),p=JSON.parse(c);return typeof p.exp=="number"?p.exp*1e3:null}catch{return null}}function Pe(t,n){let u=le(t);return u===null?true:u-Date.now()<=n}function Ne(t){let n=le(t);return n===null?true:Date.now()>=n}function Ue(t){let n=le(t);return n===null?0:Math.max(0,n-Date.now())}exports.ToolValidationError=y;exports.createThread=ce;exports.getBackendBaseUrl=E;exports.getOrCreateUserId=U;exports.getTimeUntilExpiry=Ue;exports.initSession=ue;exports.isTokenExpired=Ne;exports.isTokenExpiringSoon=Pe;exports.parseTokenExpiry=le;exports.registerToolsOnBackend=Q;exports.sendSystemEvent=pe;exports.sendToolResult=G;exports.serializeToolDefinition=re;exports.updateUser=ke;exports.uploadFile=de;exports.useMiiflowChat=Oe;exports.validateToolDefinition=ie;//# sourceMappingURL=index.cjs.map
|
|
9
9
|
//# sourceMappingURL=index.cjs.map
|