@opencx/widget 3.0.56 → 3.0.58

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@opencx/widget",
3
3
  "private": false,
4
- "version": "3.0.56",
4
+ "version": "3.0.58",
5
5
  "type": "module",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -18,13 +18,25 @@
18
18
  "url": "https://github.com/openchatai"
19
19
  },
20
20
  "peerDependencies": {
21
+ "@types/react": ">=18 <20",
22
+ "@types/react-dom": ">=18 <20",
21
23
  "lucide-react": "^0.412.0",
22
- "react": "^18.3.1",
24
+ "react": ">=18 <20",
25
+ "react-dom": ">=18 <20",
23
26
  "rehype-raw": "^7.0.0"
24
27
  },
25
28
  "peerDependenciesMeta": {
26
29
  "react": {
27
30
  "optional": true
31
+ },
32
+ "react-dom": {
33
+ "optional": true
34
+ },
35
+ "@types/react": {
36
+ "optional": true
37
+ },
38
+ "@types/react-dom": {
39
+ "optional": true
28
40
  }
29
41
  },
30
42
  "optionalDependencies": {
@@ -34,46 +46,21 @@
34
46
  "@radix-ui/react-avatar": "^1.1.0",
35
47
  "@radix-ui/react-dialog": "^1.1.5",
36
48
  "@radix-ui/react-dropdown-menu": "^2.1.4",
49
+ "@radix-ui/react-popover": "^1.1.2",
37
50
  "@radix-ui/react-slot": "^1.1.0",
38
51
  "@radix-ui/react-switch": "^1.1.0",
39
52
  "@radix-ui/react-tooltip": "^1.1.2",
40
53
  "clsx": "^2.1.1",
41
- "date-fns": "^4.1.0",
42
54
  "framer-motion": "^11.3.30",
43
55
  "lodash.isequal": "^4.5.0",
44
- "lodash.set": "^4.3.2",
45
56
  "lucide-react": "^0.436.0",
46
- "mutative": "^1.0.11",
47
57
  "openapi-fetch": "^0.13.4",
48
58
  "openapi-typescript": "^7.5.2",
49
59
  "react-dropzone": "^14.3.5",
50
- "react-hot-toast": "^2.4.1",
51
60
  "tinycolor2": "^1.6.0",
52
61
  "uuid": "^11.0.4",
53
- "whatwg-fetch": "^3.6.20",
54
62
  "zod": "^3.23.8"
55
63
  },
56
- "overrides": {
57
- "@opencx/widget": {
58
- "react": {
59
- "optional": true,
60
- "dependencies": {
61
- "react-hot-toast": "^2.4.1",
62
- "react-markdown": "^9.0.1",
63
- "framer-motion": "^11.3.30",
64
- "date-fns": "^4.1.0"
65
- }
66
- }
67
- }
68
- },
69
- "conditionalDependencies": {
70
- "react": {
71
- "react-hot-toast": "^2.4.1",
72
- "react-markdown": "^9.0.1",
73
- "framer-motion": "^11.3.30",
74
- "date-fns": "^4.1.0"
75
- }
76
- },
77
64
  "files": [
78
65
  "dist",
79
66
  "dist-embed"
@@ -99,18 +86,9 @@
99
86
  "devDependencies": {
100
87
  "@biomejs/biome": "1.9.4",
101
88
  "@changesets/cli": "^2.27.9",
102
- "@radix-ui/react-popover": "^1.1.2",
103
89
  "@tailwindcss/typography": "^0.5.15",
104
- "@testing-library/dom": "^10.4.0",
105
- "@testing-library/jest-dom": "^6.5.0",
106
- "@testing-library/react": "^16.0.1",
107
- "@testing-library/user-event": "^14.5.2",
108
- "@types/lodash.debounce": "^4.0.9",
109
90
  "@types/lodash.isequal": "^4.5.8",
110
- "@types/lodash.set": "^4.3.9",
111
91
  "@types/node": "^20.14.8",
112
- "@types/react": "^18.3.4",
113
- "@types/react-dom": "^18.3.0",
114
92
  "@types/tinycolor2": "^1.4.6",
115
93
  "@uiw/react-iframe": "^1.0.3",
116
94
  "@vitejs/plugin-react": "^4.3.4",
@@ -118,11 +96,8 @@
118
96
  "autoprefixer": "^10.4.20",
119
97
  "class-variance-authority": "^0.7.0",
120
98
  "jsdom": "^25.0.1",
121
- "mutative": "^1.0.11",
122
99
  "postcss": "^8.4.41",
123
100
  "postcss-prefix-selector": "^1.16.1",
124
- "react": "^18.3.1",
125
- "react-dom": "^18.3.1",
126
101
  "react-markdown": "^9.0.1",
127
102
  "react-use": "^17.5.1",
128
103
  "rehype-raw": "^7.0.0",
@@ -1,18 +0,0 @@
1
- "use strict";const g=require("react"),Wt=require("react/jsx-runtime"),qt=require("./widget.ctx-CKRA-jh1.cjs"),Bt=require("uuid");class Gt{constructor(t){this.components=[];const{components:n}=t;if(n&&n.forEach(r=>this.register(r)),this.components.length===0)throw new Error("No components registered");if(!this.get("fallback"))throw new Error("No fallback component registered")}register(t){const n=this.components.findIndex(r=>r.key===t.key);return n!==-1?this.components[n]=t:this.components.push(t),this}get(t){const n=this.components.find(r=>r.key.toUpperCase()===t.toUpperCase());return n||null}getComponent(t){var n;return(n=this.get(t))==null?void 0:n.component}}function Ht(e){const t=g.createContext({});return[()=>{const r=g.useContext(t);if(r===void 0)throw new Error("useSafeContext must be used within a Provider");return r},t.Provider]}const $t="3.0.56",[K,Kt]=Ht();function zt({options:e,children:t,components:n,storage:r}){const o=g.useRef(!1),[s,i]=g.useState(null),d=g.useMemo(()=>new Gt({components:n}),[n]);return g.useEffect(()=>{o.current||(o.current=!0,qt.WidgetCtx.initialize({config:e,storage:r}).then(i))},[]),s?Wt.jsx(Kt,{value:{widgetCtx:s,components:n,componentStore:d,version:$t},children:t}):null}function kt(){const{widgetCtx:e}=K();return e.config}function ee(e){return g.useSyncExternalStore(e.subscribe,e.get,e.get)}function Yt(){const{widgetCtx:e}=K();return{contactState:ee(e.contactCtx.state),createUnverifiedContact:e.contactCtx.createUnverifiedContact}}function et(){const{widgetCtx:e}=K();return{messagesState:ee(e.messageCtx.state),sendMessage:e.messageCtx.sendMessage}}function tt(){const{widgetCtx:e}=K(),t=ee(e.sessionCtx.sessionState),n=ee(e.sessionCtx.sessionsState);return{sessionState:t,sessionsState:n,loadMoreSessions:e.sessionCtx.loadMoreSessions}}function Jt(){var i;const{sessionState:e}=tt(),{messagesState:t}=et(),n=((i=e.session)==null?void 0:i.assignee.kind)==="ai",r=t.messages.length>0?t.messages[t.messages.length-1]:null,o=(r==null?void 0:r.type)==="FROM_USER";return{isAwaitingBotReply:(n||e.isCreatingSession)&&(t.isSendingMessage||o)}}var Xt=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Qt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function Zt(e){if(e.__esModule)return e;var t=e.default;if(typeof t=="function"){var n=function r(){return this instanceof r?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};n.prototype=t.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(e).forEach(function(r){var o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(n,r,o.get?o:{enumerable:!0,get:function(){return e[r]}})}),n}var Oe={exports:{}},ye={};/**
2
- * @license React
3
- * use-sync-external-store-shim.production.min.js
4
- *
5
- * Copyright (c) Facebook, Inc. and its affiliates.
6
- *
7
- * This source code is licensed under the MIT license found in the
8
- * LICENSE file in the root directory of this source tree.
9
- */var ze;function en(){if(ze)return ye;ze=1;var e=g;function t(u,l){return u===l&&(u!==0||1/u===1/l)||u!==u&&l!==l}var n=typeof Object.is=="function"?Object.is:t,r=e.useState,o=e.useEffect,s=e.useLayoutEffect,i=e.useDebugValue;function d(u,l){var c=l(),y=r({inst:{value:c,getSnapshot:l}}),h=y[0].inst,T=y[1];return s(function(){h.value=c,h.getSnapshot=l,_(h)&&T({inst:h})},[u,c,l]),o(function(){return _(h)&&T({inst:h}),u(function(){_(h)&&T({inst:h})})},[u]),i(c),c}function _(u){var l=u.getSnapshot;u=u.value;try{var c=l();return!n(u,c)}catch{return!0}}function f(u,l){return l()}var a=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?f:d;return ye.useSyncExternalStore=e.useSyncExternalStore!==void 0?e.useSyncExternalStore:a,ye}var ge={};/**
10
- * @license React
11
- * use-sync-external-store-shim.development.js
12
- *
13
- * Copyright (c) Facebook, Inc. and its affiliates.
14
- *
15
- * This source code is licensed under the MIT license found in the
16
- * LICENSE file in the root directory of this source tree.
17
- */var ke;function tn(){return ke||(ke=1,process.env.NODE_ENV!=="production"&&function(){typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error);var e=g,t=e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function n(R){{for(var v=arguments.length,w=new Array(v>1?v-1:0),S=1;S<v;S++)w[S-1]=arguments[S];r("error",R,w)}}function r(R,v,w){{var S=t.ReactDebugCurrentFrame,I=S.getStackAddendum();I!==""&&(v+="%s",w=w.concat([I]));var m=w.map(function(D){return String(D)});m.unshift("Warning: "+v),Function.prototype.apply.call(console[R],console,m)}}function o(R,v){return R===v&&(R!==0||1/R===1/v)||R!==R&&v!==v}var s=typeof Object.is=="function"?Object.is:o,i=e.useState,d=e.useEffect,_=e.useLayoutEffect,f=e.useDebugValue,a=!1,u=!1;function l(R,v,w){a||e.startTransition!==void 0&&(a=!0,n("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var S=v();if(!u){var I=v();s(S,I)||(n("The result of getSnapshot should be cached to avoid an infinite loop"),u=!0)}var m=i({inst:{value:S,getSnapshot:v}}),D=m[0].inst,P=m[1];return _(function(){D.value=S,D.getSnapshot=v,c(D)&&P({inst:D})},[R,S,v]),d(function(){c(D)&&P({inst:D});var B=function(){c(D)&&P({inst:D})};return R(B)},[R]),f(S),S}function c(R){var v=R.getSnapshot,w=R.value;try{var S=v();return!s(w,S)}catch{return!0}}function y(R,v,w){return v()}var h=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",T=!h,p=T?y:l,k=e.useSyncExternalStore!==void 0?e.useSyncExternalStore:p;ge.useSyncExternalStore=k,typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error)}()),ge}process.env.NODE_ENV==="production"?Oe.exports=en():Oe.exports=tn();var nn=Oe.exports;const H=()=>{},L=H(),Ee=Object,E=e=>e===L,N=e=>typeof e=="function",$=(e,t)=>({...e,...t}),rn=e=>N(e.then),ue=new WeakMap;let on=0;const oe=e=>{const t=typeof e,n=e&&e.constructor,r=n==Date;let o,s;if(Ee(e)===e&&!r&&n!=RegExp){if(o=ue.get(e),o)return o;if(o=++on+"~",ue.set(e,o),n==Array){for(o="@",s=0;s<e.length;s++)o+=oe(e[s])+",";ue.set(e,o)}if(n==Ee){o="#";const i=Ee.keys(e).sort();for(;!E(s=i.pop());)E(e[s])||(o+=s+":"+oe(e[s])+",");ue.set(e,o)}}else o=r?e.toJSON():t=="symbol"?e.toString():t=="string"?JSON.stringify(e):""+e;return o},q=new WeakMap,ve={},ce={},Pe="undefined",de=typeof window!=Pe,Re=typeof document!=Pe,sn=()=>de&&typeof window.requestAnimationFrame!=Pe,nt=(e,t)=>{const n=q.get(e);return[()=>!E(t)&&e.get(t)||ve,r=>{if(!E(t)){const o=e.get(t);t in ce||(ce[t]=o),n[5](t,$(o,r),o||ve)}},n[6],()=>!E(t)&&t in ce?ce[t]:!E(t)&&e.get(t)||ve]};let Ce=!0;const an=()=>Ce,[Te,De]=de&&window.addEventListener?[window.addEventListener.bind(window),window.removeEventListener.bind(window)]:[H,H],un=()=>{const e=Re&&document.visibilityState;return E(e)||e!=="hidden"},cn=e=>(Re&&document.addEventListener("visibilitychange",e),Te("focus",e),()=>{Re&&document.removeEventListener("visibilitychange",e),De("focus",e)}),fn=e=>{const t=()=>{Ce=!0,e()},n=()=>{Ce=!1};return Te("online",t),Te("offline",n),()=>{De("online",t),De("offline",n)}},ln={isOnline:an,isVisible:un},dn={initFocus:cn,initReconnect:fn},Ye=!g.useId,se=!de||"Deno"in window,pn=e=>sn()?window.requestAnimationFrame(e):setTimeout(e,1),Se=se?g.useEffect:g.useLayoutEffect,we=typeof navigator<"u"&&navigator.connection,Je=!se&&we&&(["slow-2g","2g"].includes(we.effectiveType)||we.saveData),Le=e=>{if(N(e))try{e=e()}catch{e=""}const t=e;return e=typeof e=="string"?e:(Array.isArray(e)?e.length:e)?oe(e):"",[e,t]};let _n=0;const Ae=()=>++_n,rt=0,ot=1,st=2,hn=3;var re={__proto__:null,ERROR_REVALIDATE_EVENT:hn,FOCUS_EVENT:rt,MUTATE_EVENT:st,RECONNECT_EVENT:ot};async function it(...e){const[t,n,r,o]=e,s=$({populateCache:!0,throwOnError:!0},typeof o=="boolean"?{revalidate:o}:o||{});let i=s.populateCache;const d=s.rollbackOnError;let _=s.optimisticData;const f=l=>typeof d=="function"?d(l):d!==!1,a=s.throwOnError;if(N(n)){const l=n,c=[],y=t.keys();for(const h of y)!/^\$(inf|sub)\$/.test(h)&&l(t.get(h)._k)&&c.push(h);return Promise.all(c.map(u))}return u(n);async function u(l){const[c]=Le(l);if(!c)return;const[y,h]=nt(t,c),[T,p,k,R]=q.get(t),v=()=>{const M=T[c];return(N(s.revalidate)?s.revalidate(y().data,l):s.revalidate!==!1)&&(delete k[c],delete R[c],M&&M[0])?M[0](st).then(()=>y().data):y().data};if(e.length<3)return v();let w=r,S;const I=Ae();p[c]=[I,0];const m=!E(_),D=y(),P=D.data,B=D._c,z=E(B)?P:B;if(m&&(_=N(_)?_(z,P):_,h({data:_,_c:z})),N(w))try{w=w(z)}catch(M){S=M}if(w&&rn(w))if(w=await w.catch(M=>{S=M}),I!==p[c][0]){if(S)throw S;return w}else S&&m&&f(S)&&(i=!0,h({data:z,_c:L}));if(i&&!S)if(N(i)){const M=i(w,z);h({data:M,error:L,_c:L})}else h({data:w,error:L,_c:L});if(p[c][1]=Ae(),Promise.resolve(v()).then(()=>{h({_c:L})}),S){if(a)throw S;return}return w}}const Xe=(e,t)=>{for(const n in e)e[n][0]&&e[n][0](t)},yn=(e,t)=>{if(!q.has(e)){const n=$(dn,t),r={},o=it.bind(L,e);let s=H;const i={},d=(a,u)=>{const l=i[a]||[];return i[a]=l,l.push(u),()=>l.splice(l.indexOf(u),1)},_=(a,u,l)=>{e.set(a,u);const c=i[a];if(c)for(const y of c)y(u,l)},f=()=>{if(!q.has(e)&&(q.set(e,[r,{},{},{},o,_,d]),!se)){const a=n.initFocus(setTimeout.bind(L,Xe.bind(L,r,rt))),u=n.initReconnect(setTimeout.bind(L,Xe.bind(L,r,ot)));s=()=>{a&&a(),u&&u(),q.delete(e)}}};return f(),[e,o,f,s]}return[e,q.get(e)[4]]},gn=(e,t,n,r,o)=>{const s=n.errorRetryCount,i=o.retryCount,d=~~((Math.random()+.5)*(1<<(i<8?i:8)))*n.errorRetryInterval;!E(s)&&i>s||setTimeout(r,d,o)},En=(e,t)=>oe(e)==oe(t),[at,vn]=yn(new Map),Sn=$({onLoadingSlow:H,onSuccess:H,onError:H,onErrorRetry:gn,onDiscarded:H,revalidateOnFocus:!0,revalidateOnReconnect:!0,revalidateIfStale:!0,shouldRetryOnError:!0,errorRetryInterval:Je?1e4:5e3,focusThrottleInterval:5*1e3,dedupingInterval:2*1e3,loadingTimeout:Je?5e3:3e3,compare:En,isPaused:()=>!1,cache:at,mutate:vn,fallback:{}},ln),wn=(e,t)=>{const n=$(e,t);if(t){const{use:r,fallback:o}=e,{use:s,fallback:i}=t;r&&s&&(n.use=r.concat(s)),o&&i&&(n.fallback=$(o,i))}return n},mn=g.createContext({}),bn="$inf$",ut=de&&window.__SWR_DEVTOOLS_USE__,On=ut?window.__SWR_DEVTOOLS_USE__:[],Rn=()=>{ut&&(window.__SWR_DEVTOOLS_REACT__=g)},Cn=e=>N(e[1])?[e[0],e[1],e[2]||{}]:[e[0],null,(e[1]===null?e[2]:e[1])||{}],Tn=()=>$(Sn,g.useContext(mn)),Dn=e=>(t,n,r)=>e(t,n&&((...s)=>{const[i]=Le(t),[,,,d]=q.get(at);if(i.startsWith(bn))return n(...s);const _=d[i];return E(_)?n(...s):(delete d[i],_)}),r),An=On.concat(Dn),xn=e=>function(...n){const r=Tn(),[o,s,i]=Cn(n),d=wn(r,i);let _=e;const{use:f}=d,a=(f||[]).concat(An);for(let u=a.length;u--;)_=a[u](_);return _(o,s||d.fetcher||null,d)},jn=(e,t,n)=>{const r=t[e]||(t[e]=[]);return r.push(n),()=>{const o=r.indexOf(n);o>=0&&(r[o]=r[r.length-1],r.pop())}};Rn();const Qe=g.use||(e=>{if(e.status==="pending")throw e;if(e.status==="fulfilled")return e.value;throw e.status==="rejected"?e.reason:(e.status="pending",e.then(t=>{e.status="fulfilled",e.value=t},t=>{e.status="rejected",e.reason=t}),e)}),me={dedupe:!0},Pn=(e,t,n)=>{const{cache:r,compare:o,suspense:s,fallbackData:i,revalidateOnMount:d,revalidateIfStale:_,refreshInterval:f,refreshWhenHidden:a,refreshWhenOffline:u,keepPreviousData:l}=n,[c,y,h,T]=q.get(r),[p,k]=Le(e),R=g.useRef(!1),v=g.useRef(!1),w=g.useRef(p),S=g.useRef(t),I=g.useRef(n),m=()=>I.current,D=()=>m().isVisible()&&m().isOnline(),[P,B,z,M]=nt(r,p),Y=g.useRef({}).current,Vt=E(i)?n.fallback[p]:i,Fe=(b,O)=>{for(const x in Y){const C=x;if(C==="data"){if(!o(b[C],O[C])&&(!E(b[C])||!o(ae,O[C])))return!1}else if(O[C]!==b[C])return!1}return!0},Ne=g.useMemo(()=>{const b=!p||!t?!1:E(d)?m().isPaused()||s?!1:E(_)?!0:_:d,O=j=>{const U=$(j);return delete U._k,b?{isValidating:!0,isLoading:!0,...U}:U},x=P(),C=M(),F=O(x),Z=x===C?F:O(C);let A=F;return[()=>{const j=O(P());return Fe(j,A)?(A.data=j.data,A.isLoading=j.isLoading,A.isValidating=j.isValidating,A.error=j.error,A):(A=j,j)},()=>Z]},[r,p]),J=nn.useSyncExternalStore(g.useCallback(b=>z(p,(O,x)=>{Fe(x,O)||b()}),[r,p]),Ne[0],Ne[1]),Ue=!R.current,Mt=c[p]&&c[p].length>0,X=J.data,Q=E(X)?Vt:X,ie=J.error,We=g.useRef(Q),ae=l?E(X)?We.current:X:Q,qe=Mt&&!E(ie)?!1:Ue&&!E(d)?d:m().isPaused()?!1:s?E(Q)?!1:_:E(Q)||_,Be=!!(p&&t&&Ue&&qe),Ft=E(J.isValidating)?Be:J.isValidating,Nt=E(J.isLoading)?Be:J.isLoading,ne=g.useCallback(async b=>{const O=S.current;if(!p||!O||v.current||m().isPaused())return!1;let x,C,F=!0;const Z=b||{},A=!h[p]||!Z.dedupe,j=()=>Ye?!v.current&&p===w.current&&R.current:p===w.current,U={isValidating:!1,isLoading:!1},He=()=>{B(U)},$e=()=>{const V=h[p];V&&V[1]===C&&delete h[p]},Ke={isValidating:!0};E(P().data)&&(Ke.isLoading=!0);try{if(A&&(B(Ke),n.loadingTimeout&&E(P().data)&&setTimeout(()=>{F&&j()&&m().onLoadingSlow(p,n)},n.loadingTimeout),h[p]=[O(k),Ae()]),[x,C]=h[p],x=await x,A&&setTimeout($e,n.dedupingInterval),!h[p]||h[p][1]!==C)return A&&j()&&m().onDiscarded(p),!1;U.error=L;const V=y[p];if(!E(V)&&(C<=V[0]||C<=V[1]||V[1]===0))return He(),A&&j()&&m().onDiscarded(p),!1;const W=P().data;U.data=o(W,x)?W:x,A&&j()&&m().onSuccess(x,p,n)}catch(V){$e();const W=m(),{shouldRetryOnError:_e}=W;W.isPaused()||(U.error=V,A&&j()&&(W.onError(V,p,W),(_e===!0||N(_e)&&_e(V))&&(!m().revalidateOnFocus||!m().revalidateOnReconnect||D())&&W.onErrorRetry(V,p,W,Ut=>{const he=c[p];he&&he[0]&&he[0](re.ERROR_REVALIDATE_EVENT,Ut)},{retryCount:(Z.retryCount||0)+1,dedupe:!0})))}return F=!1,He(),!0},[p,r]),Ge=g.useCallback((...b)=>it(r,w.current,...b),[]);if(Se(()=>{S.current=t,I.current=n,E(X)||(We.current=X)}),Se(()=>{if(!p)return;const b=ne.bind(L,me);let O=0;const C=jn(p,c,(F,Z={})=>{if(F==re.FOCUS_EVENT){const A=Date.now();m().revalidateOnFocus&&A>O&&D()&&(O=A+m().focusThrottleInterval,b())}else if(F==re.RECONNECT_EVENT)m().revalidateOnReconnect&&D()&&b();else{if(F==re.MUTATE_EVENT)return ne();if(F==re.ERROR_REVALIDATE_EVENT)return ne(Z)}});return v.current=!1,w.current=p,R.current=!0,B({_k:k}),qe&&(E(Q)||se?b():pn(b)),()=>{v.current=!0,C()}},[p]),Se(()=>{let b;function O(){const C=N(f)?f(P().data):f;C&&b!==-1&&(b=setTimeout(x,C))}function x(){!P().error&&(a||m().isVisible())&&(u||m().isOnline())?ne(me).then(O):O()}return O(),()=>{b&&(clearTimeout(b),b=-1)}},[f,a,u,p]),g.useDebugValue(ae),s&&E(Q)&&p){if(!Ye&&se)throw new Error("Fallback data is required when using suspense in SSR.");S.current=t,I.current=n,v.current=!1;const b=T[p];if(!E(b)){const O=Ge(b);Qe(O)}if(E(ie)){const O=ne(me);E(ae)||(O.status="fulfilled",O.value=!0),Qe(O)}else throw ie}return{mutate:Ge,get data(){return Y.data=!0,ae},get error(){return Y.error=!0,ie},get isValidating(){return Y.isValidating=!0,Ft},get isLoading(){return Y.isLoading=!0,Nt}}},Ln=xn(Pn);function In(){const{widgetCtx:e}=K();return Ln([e.config.token],e.api.widgetPrelude,{revalidateOnFocus:!1})}function Vn(){const{widgetCtx:e}=K();return{routerState:ee(e.routerCtx.state),toSessionsScreen:e.routerCtx.toSessionsScreen,toChatScreen:e.routerCtx.toChatScreen}}var ct={},xe=function(e,t){return xe=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,r){n.__proto__=r}||function(n,r){for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(n[o]=r[o])},xe(e,t)};function ft(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");xe(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}exports.__assign=function(){return exports.__assign=Object.assign||function(t){for(var n,r=1,o=arguments.length;r<o;r++){n=arguments[r];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(t[s]=n[s])}return t},exports.__assign.apply(this,arguments)};function Ie(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]]);return n}function lt(e,t,n,r){var o=arguments.length,s=o<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,i;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(e,t,n,r);else for(var d=e.length-1;d>=0;d--)(i=e[d])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s}function dt(e,t){return function(n,r){t(n,r,e)}}function pt(e,t,n,r,o,s){function i(p){if(p!==void 0&&typeof p!="function")throw new TypeError("Function expected");return p}for(var d=r.kind,_=d==="getter"?"get":d==="setter"?"set":"value",f=!t&&e?r.static?e:e.prototype:null,a=t||(f?Object.getOwnPropertyDescriptor(f,r.name):{}),u,l=!1,c=n.length-1;c>=0;c--){var y={};for(var h in r)y[h]=h==="access"?{}:r[h];for(var h in r.access)y.access[h]=r.access[h];y.addInitializer=function(p){if(l)throw new TypeError("Cannot add initializers after decoration has completed");s.push(i(p||null))};var T=(0,n[c])(d==="accessor"?{get:a.get,set:a.set}:a[_],y);if(d==="accessor"){if(T===void 0)continue;if(T===null||typeof T!="object")throw new TypeError("Object expected");(u=i(T.get))&&(a.get=u),(u=i(T.set))&&(a.set=u),(u=i(T.init))&&o.unshift(u)}else(u=i(T))&&(d==="field"?o.unshift(u):a[_]=u)}f&&Object.defineProperty(f,r.name,a),l=!0}function _t(e,t,n){for(var r=arguments.length>2,o=0;o<t.length;o++)n=r?t[o].call(e,n):t[o].call(e);return r?n:void 0}function ht(e){return typeof e=="symbol"?e:"".concat(e)}function yt(e,t,n){return typeof t=="symbol"&&(t=t.description?"[".concat(t.description,"]"):""),Object.defineProperty(e,"name",{configurable:!0,value:n?"".concat(n," ",t):t})}function gt(e,t){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(e,t)}function Et(e,t,n,r){function o(s){return s instanceof n?s:new n(function(i){i(s)})}return new(n||(n=Promise))(function(s,i){function d(a){try{f(r.next(a))}catch(u){i(u)}}function _(a){try{f(r.throw(a))}catch(u){i(u)}}function f(a){a.done?s(a.value):o(a.value).then(d,_)}f((r=r.apply(e,t||[])).next())})}function vt(e,t){var n={label:0,sent:function(){if(s[0]&1)throw s[1];return s[1]},trys:[],ops:[]},r,o,s,i=Object.create((typeof Iterator=="function"?Iterator:Object).prototype);return i.next=d(0),i.throw=d(1),i.return=d(2),typeof Symbol=="function"&&(i[Symbol.iterator]=function(){return this}),i;function d(f){return function(a){return _([f,a])}}function _(f){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,f[0]&&(n=0)),n;)try{if(r=1,o&&(s=f[0]&2?o.return:f[0]?o.throw||((s=o.return)&&s.call(o),0):o.next)&&!(s=s.call(o,f[1])).done)return s;switch(o=0,s&&(f=[f[0]&2,s.value]),f[0]){case 0:case 1:s=f;break;case 4:return n.label++,{value:f[1],done:!1};case 5:n.label++,o=f[1],f=[0];continue;case 7:f=n.ops.pop(),n.trys.pop();continue;default:if(s=n.trys,!(s=s.length>0&&s[s.length-1])&&(f[0]===6||f[0]===2)){n=0;continue}if(f[0]===3&&(!s||f[1]>s[0]&&f[1]<s[3])){n.label=f[1];break}if(f[0]===6&&n.label<s[1]){n.label=s[1],s=f;break}if(s&&n.label<s[2]){n.label=s[2],n.ops.push(f);break}s[2]&&n.ops.pop(),n.trys.pop();continue}f=t.call(e,n)}catch(a){f=[6,a],o=0}finally{r=s=0}if(f[0]&5)throw f[1];return{value:f[0]?f[1]:void 0,done:!0}}}var pe=Object.create?function(e,t,n,r){r===void 0&&(r=n);var o=Object.getOwnPropertyDescriptor(t,n);(!o||("get"in o?!t.__esModule:o.writable||o.configurable))&&(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,o)}:function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]};function St(e,t){for(var n in e)n!=="default"&&!Object.prototype.hasOwnProperty.call(t,n)&&pe(t,e,n)}function le(e){var t=typeof Symbol=="function"&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&typeof e.length=="number")return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function Ve(e,t){var n=typeof Symbol=="function"&&e[Symbol.iterator];if(!n)return e;var r=n.call(e),o,s=[],i;try{for(;(t===void 0||t-- >0)&&!(o=r.next()).done;)s.push(o.value)}catch(d){i={error:d}}finally{try{o&&!o.done&&(n=r.return)&&n.call(r)}finally{if(i)throw i.error}}return s}function wt(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(Ve(arguments[t]));return e}function mt(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;for(var r=Array(e),o=0,t=0;t<n;t++)for(var s=arguments[t],i=0,d=s.length;i<d;i++,o++)r[o]=s[i];return r}function Me(e,t,n){if(n||arguments.length===2)for(var r=0,o=t.length,s;r<o;r++)(s||!(r in t))&&(s||(s=Array.prototype.slice.call(t,0,r)),s[r]=t[r]);return e.concat(s||Array.prototype.slice.call(t))}function te(e){return this instanceof te?(this.v=e,this):new te(e)}function bt(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r=n.apply(e,t||[]),o,s=[];return o=Object.create((typeof AsyncIterator=="function"?AsyncIterator:Object).prototype),d("next"),d("throw"),d("return",i),o[Symbol.asyncIterator]=function(){return this},o;function i(c){return function(y){return Promise.resolve(y).then(c,u)}}function d(c,y){r[c]&&(o[c]=function(h){return new Promise(function(T,p){s.push([c,h,T,p])>1||_(c,h)})},y&&(o[c]=y(o[c])))}function _(c,y){try{f(r[c](y))}catch(h){l(s[0][3],h)}}function f(c){c.value instanceof te?Promise.resolve(c.value.v).then(a,u):l(s[0][2],c)}function a(c){_("next",c)}function u(c){_("throw",c)}function l(c,y){c(y),s.shift(),s.length&&_(s[0][0],s[0][1])}}function Ot(e){var t,n;return t={},r("next"),r("throw",function(o){throw o}),r("return"),t[Symbol.iterator]=function(){return this},t;function r(o,s){t[o]=e[o]?function(i){return(n=!n)?{value:te(e[o](i)),done:!1}:s?s(i):i}:s}}function Rt(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],n;return t?t.call(e):(e=typeof le=="function"?le(e):e[Symbol.iterator](),n={},r("next"),r("throw"),r("return"),n[Symbol.asyncIterator]=function(){return this},n);function r(s){n[s]=e[s]&&function(i){return new Promise(function(d,_){i=e[s](i),o(d,_,i.done,i.value)})}}function o(s,i,d,_){Promise.resolve(_).then(function(f){s({value:f,done:d})},i)}}function Ct(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var Mn=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t};function Tt(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)n!=="default"&&Object.prototype.hasOwnProperty.call(e,n)&&pe(t,e,n);return Mn(t,e),t}function Dt(e){return e&&e.__esModule?e:{default:e}}function At(e,t,n,r){if(n==="a"&&!r)throw new TypeError("Private accessor was defined without a getter");if(typeof t=="function"?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return n==="m"?r:n==="a"?r.call(e):r?r.value:t.get(e)}function xt(e,t,n,r,o){if(r==="m")throw new TypeError("Private method is not writable");if(r==="a"&&!o)throw new TypeError("Private accessor was defined without a setter");if(typeof t=="function"?e!==t||!o:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return r==="a"?o.call(e,n):o?o.value=n:t.set(e,n),n}function jt(e,t){if(t===null||typeof t!="object"&&typeof t!="function")throw new TypeError("Cannot use 'in' operator on non-object");return typeof e=="function"?t===e:e.has(t)}function Pt(e,t,n){if(t!=null){if(typeof t!="object"&&typeof t!="function")throw new TypeError("Object expected.");var r,o;if(n){if(!Symbol.asyncDispose)throw new TypeError("Symbol.asyncDispose is not defined.");r=t[Symbol.asyncDispose]}if(r===void 0){if(!Symbol.dispose)throw new TypeError("Symbol.dispose is not defined.");r=t[Symbol.dispose],n&&(o=r)}if(typeof r!="function")throw new TypeError("Object not disposable.");o&&(r=function(){try{o.call(this)}catch(s){return Promise.reject(s)}}),e.stack.push({value:t,dispose:r,async:n})}else n&&e.stack.push({async:!0});return t}var Fn=typeof SuppressedError=="function"?SuppressedError:function(e,t,n){var r=new Error(n);return r.name="SuppressedError",r.error=e,r.suppressed=t,r};function Lt(e){function t(s){e.error=e.hasError?new Fn(s,e.error,"An error was suppressed during disposal."):s,e.hasError=!0}var n,r=0;function o(){for(;n=e.stack.pop();)try{if(!n.async&&r===1)return r=0,e.stack.push(n),Promise.resolve().then(o);if(n.dispose){var s=n.dispose.call(n.value);if(n.async)return r|=2,Promise.resolve(s).then(o,function(i){return t(i),o()})}else r|=1}catch(i){t(i)}if(r===1)return e.hasError?Promise.reject(e.error):Promise.resolve();if(e.hasError)throw e.error}return o()}function It(e,t){return typeof e=="string"&&/^\.\.?\//.test(e)?e.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i,function(n,r,o,s,i){return r?t?".jsx":".js":o&&(!s||!i)?n:o+s+"."+i.toLowerCase()+"js"}):e}const Nn={__extends:ft,__assign:exports.__assign,__rest:Ie,__decorate:lt,__param:dt,__esDecorate:pt,__runInitializers:_t,__propKey:ht,__setFunctionName:yt,__metadata:gt,__awaiter:Et,__generator:vt,__createBinding:pe,__exportStar:St,__values:le,__read:Ve,__spread:wt,__spreadArrays:mt,__spreadArray:Me,__await:te,__asyncGenerator:bt,__asyncDelegator:Ot,__asyncValues:Rt,__makeTemplateObject:Ct,__importStar:Tt,__importDefault:Dt,__classPrivateFieldGet:At,__classPrivateFieldSet:xt,__classPrivateFieldIn:jt,__addDisposableResource:Pt,__disposeResources:Lt,__rewriteRelativeImportExtension:It},Un=Object.freeze(Object.defineProperty({__proto__:null,__addDisposableResource:Pt,get __assign(){return exports.__assign},__asyncDelegator:Ot,__asyncGenerator:bt,__asyncValues:Rt,__await:te,__awaiter:Et,__classPrivateFieldGet:At,__classPrivateFieldIn:jt,__classPrivateFieldSet:xt,__createBinding:pe,__decorate:lt,__disposeResources:Lt,__esDecorate:pt,__exportStar:St,__extends:ft,__generator:vt,__importDefault:Dt,__importStar:Tt,__makeTemplateObject:Ct,__metadata:gt,__param:dt,__propKey:ht,__read:Ve,__rest:Ie,__rewriteRelativeImportExtension:It,__runInitializers:_t,__setFunctionName:yt,__spread:wt,__spreadArray:Me,__spreadArrays:mt,__values:le,default:Nn},Symbol.toStringTag,{value:"Module"})),Wn=Zt(Un);var fe={},Ze;function qn(){if(Ze)return fe;Ze=1,Object.defineProperty(fe,"__esModule",{value:!0});var e=g;function t(){var n=e.useRef(!1),r=e.useCallback(function(){return n.current},[]);return e.useEffect(function(){return n.current=!0,function(){n.current=!1}},[]),r}return fe.default=t,fe}Object.defineProperty(ct,"__esModule",{value:!0});var je=Wn,be=g,Bn=je.__importDefault(qn());function Gn(e,t,n){t===void 0&&(t=[]),n===void 0&&(n={loading:!1});var r=be.useRef(0),o=Bn.default(),s=be.useState(n),i=s[0],d=s[1],_=be.useCallback(function(){for(var f=[],a=0;a<arguments.length;a++)f[a]=arguments[a];var u=++r.current;return i.loading||d(function(l){return je.__assign(je.__assign({},l),{loading:!0})}),e.apply(void 0,f).then(function(l){return o()&&u===r.current&&d({value:l,loading:!1}),l},function(l){return o()&&u===r.current&&d({error:l,loading:!1}),l})},t);return[i,_]}var Hn=ct.default=Gn;const G=new Map;function $n(){const[e,t]=g.useState([]),{widgetCtx:{api:n}}=K();function r(a){const u=a.map(l=>({file:l,id:Bt.v4(),status:"pending",progress:0}));t(l=>[...l,...u]),u.forEach(i)}function o(a,u){t(l=>l.map(c=>c.id===a?{...c,...u}:c))}function s(a){t(u=>u.filter(l=>l.id!==a))}const i=async a=>{const u=new AbortController;G.set(a.id,u);try{t(c=>c.map(y=>y.id===a.id?{...y,status:"uploading",progress:0}:y));const l=await n.uploadFile({file:a.file,abortSignal:u.signal,onProgress:c=>{o(a.id,{progress:c})}});o(a.id,{status:"success",fileUrl:l.fileUrl,progress:100})}catch(l){u.signal.aborted||o(a.id,{status:"error",error:l instanceof Error?l.message:"Upload failed",progress:0})}finally{G.delete(a.id)}},d=a=>{const u=G.get(a);u&&(u.abort(),G.delete(a)),s(a)},_=g.useMemo(()=>e.filter(a=>a.status==="success"&&a.fileUrl),[e]);function f(){G.forEach(a=>a.abort()),G.clear(),t([])}return g.useEffect(()=>()=>{G.forEach(a=>a.abort()),G.clear()},[]),{allFiles:e,appendFiles:r,handleCancelUpload:d,successFiles:_,emptyTheFiles:f,getFileById:a=>e.find(u=>u.id===a),getUploadProgress:a=>{var u;return((u=e.find(l=>l.id===a))==null?void 0:u.progress)??0},getUploadStatus:a=>{var u;return(u=e.find(l=>l.id===a))==null?void 0:u.status},hasErrors:e.some(a=>a.status==="error"),isUploading:e.some(a=>a.status==="uploading")}}exports.WidgetProvider=zt;exports.__rest=Ie;exports.__spreadArray=Me;exports._default=Hn;exports.commonjsGlobal=Xt;exports.getDefaultExportFromCjs=Qt;exports.useConfig=kt;exports.useContact=Yt;exports.useIsAwaitingBotReply=Jt;exports.useMessages=et;exports.usePreludeData=In;exports.usePrimitiveState=ee;exports.useSessions=tt;exports.useUploadFiles=$n;exports.useWidget=K;exports.useWidgetRouter=Vn;
18
- //# sourceMappingURL=useUploadFiles-B0ayL3Vk.cjs.map
@@ -1,5 +0,0 @@
1
- "use strict";const M=require("openapi-fetch"),O=require("lodash.isequal"),A=require("uuid"),F=g=>{console.log(g.error)},_=g=>{const n=M({baseUrl:g.baseUrl}),i={onRequest:g.onRequest,onResponse:g.onResponse,onError:g.onError||F};return n.use(i),n};class U{constructor({config:n}){var a;this.userToken=null,this.constructClientOptions=t=>{const s=this.config.apiUrl||"https://api.open.cx",e={"X-Bot-Token":this.config.token,"Content-Type":"application/json",Accept:"application/json",Authorization:t?`Bearer ${t}`:void 0};return{baseUrl:s,headers:e}},this.createOpenAPIClient=({baseUrl:t,headers:s})=>_({baseUrl:t,onRequest:({request:e})=>{Object.entries(s).forEach(([o,r])=>{r&&e.headers.set(o,r)})}}),this.setAuthToken=t=>{this.userToken=t;const{baseUrl:s,headers:e}=this.constructClientOptions(t);this.client=this.createOpenAPIClient({baseUrl:s,headers:e})},this.getExternalWidgetConfig=async()=>await this.client.GET("/backend/widget/v2/config",{params:{header:{"X-Bot-Token":this.config.token}}}),this.widgetPrelude=async()=>await this.client.GET("/backend/widget/v2/prelude",{params:{header:{"X-Bot-Token":this.config.token}}}),this.sendMessage=async(t,s)=>await this.client.POST("/backend/widget/v2/chat/send",{body:t,signal:s}),this.createUnverifiedContact=async t=>await this.client.POST("/backend/widget/v2/contact/create-unverified",{params:{header:{"x-bot-token":this.config.token}},body:t}),this.createSession=async t=>await this.client.POST("/backend/widget/v2/create-session",{body:t}),this.pollSessionAndHistory=async({sessionId:t,lastMessageTimestamp:s,abortSignal:e})=>{const o=s?{lastMessageTimestamp:s}:void 0;return await this.client.GET("/backend/widget/v2/poll/{sessionId}",{params:{path:{sessionId:t},query:o},signal:e})},this.getSessions=async({cursor:t,filters:s,abortSignal:e})=>await this.client.GET("/backend/widget/v2/sessions",{params:{query:{cursor:t,filters:JSON.stringify(s)}},signal:e}),this.uploadFile=async({file:t,abortSignal:s,onProgress:e})=>new Promise((o,r)=>{const l=new FormData;l.append("file",t);const c=new XMLHttpRequest;if(s&&(s.addEventListener("abort",()=>{c.abort(),r(new DOMException("Aborted","AbortError"))}),s.aborted)){r(new DOMException("Aborted","AbortError"));return}c.upload.addEventListener("progress",d=>{if(d.lengthComputable&&e){const x=Math.round(d.loaded/d.total*100);e(x)}}),c.addEventListener("load",()=>{if(c.status>=200&&c.status<300)try{const d=JSON.parse(c.responseText);o(d)}catch(d){r(new Error(`Failed to parse response: ${d}`))}else r(new Error(`Upload failed with status: ${c.status}`))}),c.addEventListener("error",()=>{r(new Error("Network error occurred"))}),c.addEventListener("timeout",()=>{r(new Error("Upload timed out"))});const{baseUrl:f}=this.constructClientOptions(this.userToken),C=`${f}/backend/widget/v2/upload`;c.open("POST",C),c.setRequestHeader("X-Bot-Token",this.config.token),this.userToken&&c.setRequestHeader("Authorization",`Bearer ${this.userToken}`),c.send(l)}),this.vote=async t=>await this.client.POST("/backend/widget/v2/chat/vote",{body:t}),this.config=n;const{baseUrl:i,headers:h}=this.constructClientOptions((a=n.user)==null?void 0:a.token);this.client=this.createOpenAPIClient({baseUrl:i,headers:h})}}class b{constructor(n){this.subscribers=new Set,this.get=()=>this.state,this.set=i=>{O(this.state,i)||(this.state=i,this.notifySubscribers(i))},this.setPartial=i=>{if(i==null)return;const h={...this.state,...i};this.set(h)},this.reset=()=>{this.set(this.initialState)},this.notifySubscribers=i=>{Array.from(this.subscribers).forEach(a=>{try{a(i)}catch(t){console.error(t)}})},this.subscribe=i=>(this.subscribers.add(i),()=>{this.subscribers.delete(i)}),this.state=n,this.initialState=n}}class T{constructor(){this.state=new b({isPolling:!1,isError:!1}),this.abortController=new AbortController,this.reset=()=>{var n;this.abortController.abort("Resetting poller"),(n=this.stopPolling)==null||n.call(this),this.stopPolling=null},this.stopPolling=null,this.startPolling=(n,i)=>{if(this.stopPolling)return;const h=[],a=async()=>{this.abortController=new AbortController,this.state.setPartial({isPolling:!0});try{await n(this.abortController.signal)}catch(t){if(this.abortController.signal.aborted)return;console.error("Failed to poll:",t),this.state.setPartial({isError:!0})}finally{this.state.setPartial({isPolling:!1})}this.abortController.signal.aborted?console.log("Poller aborted, not scheduling anymore"):h.push(setTimeout(a,i))};a(),this.stopPolling=()=>{h.forEach(clearTimeout),this.state.reset()}}}}function D(g){try{const n=g();return n instanceof Promise?n.then(i=>({data:i})).catch(i=>({error:i})):{data:n}}catch(n){return{error:n}}}class L{constructor({api:n,config:i,sessionCtx:h,messageCtx:a,sessionPollingIntervalSeconds:t}){this.poller=new T,this.registerPolling=()=>{this.sessionCtx.sessionState.subscribe(({session:s})=>{s!=null&&s.id?this.poller.startPolling(async e=>{this.hackAndSlash(s.id,e)},this.sessionPollingIntervalSeconds*1e3):this.poller.reset()})},this.hackAndSlash=async(s,e)=>{var c;this.messageCtx.state.get().messages.length===0&&this.messageCtx.state.setPartial({isInitialFetchLoading:!0});const o=this.messageCtx.state.get().messages,r=o.length>0?(c=o[o.length-1])==null?void 0:c.timestamp:void 0,{data:l}=await this.api.pollSessionAndHistory({sessionId:s,abortSignal:e,lastMessageTimestamp:r});if(l!=null&&l.session&&(this.sessionCtx.sessionState.setPartial({session:l.session}),this.sessionCtx.setSessions([l.session])),l!=null&&l.history&&l.history.length>0){const f=this.messageCtx.state.get().messages,S=l.history.map(this.mapHistoryToMessage).filter(C=>!f.some(d=>d.id===C.id));this.messageCtx.state.setPartial({messages:[...f,...S]})}this.messageCtx.state.get().isInitialFetchLoading&&this.messageCtx.state.setPartial({isInitialFetchLoading:!1})},this.mapHistoryToMessage=s=>{var r,l;const e={id:s.publicId,timestamp:s.sentAt||"",attachments:s.attachments||void 0};if(s.sender.kind==="user")return{...e,type:"FROM_USER",content:s.content.text||"",deliveredAt:s.sentAt||""};if(s.sender.kind==="agent")return{...e,type:"FROM_AGENT",component:"agent_message",data:{message:s.content.text||""},agent:{name:s.sender.name||"",avatar:s.sender.avatar||"",id:null,isAi:!1}};const o=s.actionCalls&&s.actionCalls.length>0?s.actionCalls[s.actionCalls.length-1]:void 0;return{...e,type:"FROM_BOT",component:"bot_message",agent:{id:null,name:((r=this.config.bot)==null?void 0:r.name)||"",isAi:!0,avatar:((l=this.config.bot)==null?void 0:l.avatar)||""},data:{message:s.content.text||"",action:o?{name:o.actionName,data:this.extractActionResult(o)}:void 0}}},this.extractActionResult=s=>{const e=s.result;if(e===null||typeof e!="object")return e;if("responseBodyText"in e&&typeof e.responseBodyText=="string"){const o=e.responseBodyText,r=D(()=>JSON.parse(o)).data;if(r)return r}return s.result},this.api=n,this.config=i,this.sessionCtx=h,this.messageCtx=a,this.sessionPollingIntervalSeconds=t,this.registerPolling()}}class B{constructor({config:n,api:i,storageCtx:h}){var a;this.shouldCollectData=()=>{var t;return!!(!((t=this.state.get().contact)!=null&&t.token)&&this.config.collectUserData)},this.autoCreateUnverifiedUserIfNotExists=async()=>{var t,s,e,o,r,l,c,f,S,C,d,x,P,m;if(!((t=this.config.user)!=null&&t.token)){if(this.config.collectUserData&&!((e=(s=this.config.user)==null?void 0:s.data)!=null&&e.email)){if((o=this.config.extraDataCollectionFields)!=null&&o.length)return;const v=await((r=this.storageCtx)==null?void 0:r.getContactToken());v&&await this.setUnverifiedContact(v);return}if(!((c=(l=this.config.user)==null?void 0:l.data)!=null&&c.email)){const v=await((f=this.storageCtx)==null?void 0:f.getContactToken());if(v){await this.setUnverifiedContact(v);return}}await this.createUnverifiedContact({email:(C=(S=this.config.user)==null?void 0:S.data)==null?void 0:C.email,non_verified_name:((x=(d=this.config.user)==null?void 0:d.data)==null?void 0:x.name)||"Anonymous",non_verified_custom_data:(m=(P=this.config.user)==null?void 0:P.data)==null?void 0:m.customData})}},this.createUnverifiedContact=async(t,s)=>{this.state.setPartial({extraCollectedData:s});try{this.state.setPartial({isCreatingUnverifiedContact:!0,isErrorCreatingUnverifiedContact:!1});const{data:e}=await this.api.createUnverifiedContact(t);e!=null&&e.token?await this.setUnverifiedContact(e.token):this.state.setPartial({isErrorCreatingUnverifiedContact:!0})}finally{this.state.setPartial({isCreatingUnverifiedContact:!1})}},this.setUnverifiedContact=async t=>{var o,r,l,c;const s=await((o=this.storageCtx)==null?void 0:o.getExternalContactId()),e=((r=this.config.user)==null?void 0:r.externalId)||s||A.v4();this.api.setAuthToken(t),await((l=this.storageCtx)==null?void 0:l.setContactToken(t)),await((c=this.storageCtx)==null?void 0:c.setExternalContactId(e)),this.state.setPartial({contact:{token:t,externalId:e}})},this.config=n,this.storageCtx=h,this.api=i,this.state=new b({contact:(a=n.user)!=null&&a.token?{token:n.user.token,externalId:n.user.externalId}:null,extraCollectedData:void 0,isCreatingUnverifiedContact:!1,isErrorCreatingUnverifiedContact:!1}),this.autoCreateUnverifiedUserIfNotExists()}}function y(){return A.v4()}class q{constructor({api:n,contactCtx:i,sessionsPollingIntervalSeconds:h}){this.sessionsRefresher=new T,this.sessionState=new b({session:null,isCreatingSession:!1}),this.sessionsState=new b({data:[],cursor:void 0,isLastPage:!1,didStartInitialFetch:!1,isInitialFetchLoading:!0}),this.reset=async()=>{this.sessionState.reset()},this.registerSessionsRefresherWrapper=()=>{var a;(a=this.contactCtx.state.get().contact)!=null&&a.token&&!this.sessionsState.get().didStartInitialFetch?this.registerSessionsRefresher():this.contactCtx.state.subscribe(({contact:t})=>{t!=null&&t.token&&!this.sessionsState.get().didStartInitialFetch&&this.registerSessionsRefresher()})},this.registerSessionsRefresher=()=>{this.sessionsRefresher.startPolling(async()=>{this.sessionsState.get().didStartInitialFetch===!1&&this.sessionsState.setPartial({didStartInitialFetch:!0}),await this.refreshSessions(),this.sessionsState.get().isInitialFetchLoading===!0&&this.sessionsState.setPartial({isInitialFetchLoading:!1})},this.sessionsPollingIntervalSeconds*1e3)},this.createSession=async()=>{var e;this.sessionState.setPartial({session:null,isCreatingSession:!0});const a=(e=this.contactCtx.state.get().contact)==null?void 0:e.externalId,{data:t,error:s}=await this.api.createSession({customData:a?{external_id:a}:void 0});return t?(this.sessionState.setPartial({session:t,isCreatingSession:!1}),t):(console.error("Failed to create session:",s),null)},this.loadMoreSessions=async()=>{if(this.sessionsState.get().isLastPage)return;const{data:a}=await this.getSessions({cursor:this.sessionsState.get().cursor});if(a){const s=[...this.sessionsState.get().data,...a.items].filter((e,o,r)=>o===r.findIndex(l=>e.id===l.id));this.sessionsState.setPartial({data:s,cursor:a.next||void 0,isLastPage:a.next===null})}},this.getSessions=async({cursor:a})=>{var s,e;if(!((s=this.contactCtx.state.get().contact)!=null&&s.token))return{data:null};const t=(e=this.contactCtx.state.get().contact)==null?void 0:e.externalId;return await this.api.getSessions({cursor:a,filters:t?{external_id:t}:{}})},this.setSessions=a=>{const t=[...a,...this.sessionsState.get().data].filter((s,e,o)=>e===o.findIndex(r=>s.id===r.id));this.sessionsState.setPartial({data:t})},this.refreshSessions=async()=>{const{data:a}=await this.getSessions({cursor:void 0});a&&this.setSessions(a.items)},this.api=n,this.contactCtx=i,this.sessionsPollingIntervalSeconds=h,this.registerSessionsRefresherWrapper()}}class ${constructor({config:n,api:i,sessionCtx:h,contactCtx:a}){this.state=new b({messages:[],isSendingMessage:!1,lastAIResMightSolveUserIssue:!1,isInitialFetchLoading:!1}),this.sendMessageAbortController=new AbortController,this.reset=()=>{this.sendMessageAbortController.abort("Resetting chat"),this.state.reset()},this.sendMessage=async t=>{var l,c,f,S,C,d,x,P;if(!t.content.trim()&&(!t.attachments||t.attachments.length===0)){console.warn("Cannot send an empty message of no content or attachments");return}const s=this.state.get().isSendingMessage,e=((l=this.sessionCtx.sessionState.get().session)==null?void 0:l.assignee.kind)==="ai",o=this.state.get().messages,r=o.length>0?o[o.length-1]:void 0;if(e&&s||e&&(r==null?void 0:r.type)==="FROM_USER"){console.warn("Cannot send messages while awaiting AI response");return}this.sendMessageAbortController=new AbortController,this.state.setPartial({lastAIResMightSolveUserIssue:!1});try{this.state.setPartial({isSendingMessage:!0});const m=this.toUserMessage(t.content.trim(),t.attachments||void 0),v=this.state.get().messages;if(this.state.setPartial({messages:[...v,m]}),!((c=this.sessionCtx.sessionState.get().session)!=null&&c.id)){if(!await this.sessionCtx.createSession()){console.error("Failed to create session");return}this.sessionCtx.refreshSessions()}const E=(f=this.sessionCtx.sessionState.get().session)==null?void 0:f.id;if(!E)return;const{data:u}=await this.api.sendMessage({uuid:m.id,bot_token:this.config.token,headers:this.config.headers,query_params:this.config.queryParams,session_id:E,content:m.content,attachments:t.attachments,clientContext:this.config.context},this.sendMessageAbortController.signal);if(u!=null&&u.success){const w=this.toBotMessage(u);if(w){const I=this.state.get().messages;if(!!I.some(R=>R.id===w.id)){this.state.setPartial({lastAIResMightSolveUserIssue:((S=u.autopilotResponse)==null?void 0:S.mightSolveUserIssue)||((C=u.uiResponse)==null?void 0:C.mightSolveUserIssue)});return}this.state.setPartial({messages:[...I,w],lastAIResMightSolveUserIssue:((d=u.autopilotResponse)==null?void 0:d.mightSolveUserIssue)||((x=u.uiResponse)==null?void 0:x.mightSolveUserIssue)})}}else{const w=this.toBotErrorMessage(((P=u==null?void 0:u.error)==null?void 0:P.message)||"Unknown error occurred"),I=this.state.get().messages;this.state.setPartial({messages:[...I,w]})}}catch(m){this.sendMessageAbortController.signal.aborted||console.error("Failed to send message:",m)}finally{this.state.setPartial({isSendingMessage:!1})}},this.toUserMessage=(t,s)=>{const e=(()=>{const o=this.contactCtx.state.get().extraCollectedData;return this.state.get().messages.length===0&&o&&Object.keys(o).length>0?`${Object.entries(o).filter(([l,c])=>!!c).map(([l,c])=>`${l}: ${c}`).join(`
2
- `)}
3
-
4
- ${t}`:t})();return{id:y(),type:"FROM_USER",content:e,deliveredAt:new Date().toISOString(),attachments:s,timestamp:new Date().toISOString()}},this.toBotMessage=t=>{var s;return t.success&&t.autopilotResponse?{type:"FROM_BOT",id:t.autopilotResponse.id||y(),timestamp:new Date().toISOString(),component:"bot_message",agent:this.config.bot?{name:this.config.bot.name||"",isAi:!0,avatar:this.config.bot.avatar||"",id:null}:void 0,data:{message:t.autopilotResponse.value.content,action:(s=t.uiResponse)!=null&&s.value.name?{name:t.uiResponse.value.name,data:t.uiResponse.value.request_response}:void 0}}:null},this.toBotErrorMessage=t=>({type:"FROM_BOT",id:y(),timestamp:new Date().toISOString(),component:"TEXT",data:{message:t,variant:"error",action:void 0}}),this.config=n,this.api=i,this.sessionCtx=h,this.contactCtx=a}}class N{constructor({config:n,contactCtx:i,sessionCtx:h,resetChat:a}){this.registerRoutingListener=()=>{this.contactCtx.state.subscribe(({contact:t})=>{t!=null&&t.token&&this.state.get().screen==="welcome"&&this.state.setPartial({screen:"sessions"})}),this.sessionCtx.sessionsState.subscribe(({isInitialFetchLoading:t,data:s})=>{var e;s.length||((e=this.config.router)==null?void 0:e.goToChatIfNoSessions)!==!1&&!t&&this.state.get().screen!=="chat"&&this.toChatScreen()})},this.toSessionsScreen=()=>{this.resetChat(),this.state.setPartial({screen:"sessions"})},this.toChatScreen=t=>{if(this.resetChat(),t){const s=this.sessionCtx.sessionsState.get().data.find(e=>e.id===t);if(!s)return;this.sessionCtx.sessionState.setPartial({session:s})}this.state.setPartial({screen:"chat"})},this.state=new b({screen:i.shouldCollectData()?"welcome":"sessions"}),this.config=n,this.contactCtx=i,this.sessionCtx=h,this.resetChat=a,this.registerRoutingListener()}}class H{constructor({storage:n}){this.KEYS={contactToken:"opencx__widget__contactToken",externalContactId:"opencx__widget__externalContactId"},this.setContactToken=async i=>{await this.storage.set(this.KEYS.contactToken,i)},this.getContactToken=async()=>this.storage.get(this.KEYS.contactToken),this.setExternalContactId=async i=>{await this.storage.set(this.KEYS.externalContactId,i)},this.getExternalContactId=async()=>this.storage.get(this.KEYS.externalContactId),this.storage=n}}const p=class p{constructor({config:n,storage:i}){if(this.resetChat=()=>{this.sessionCtx.reset(),this.messageCtx.reset()},!p.pollingIntervalsSeconds)throw Error("Widget polling values are not defined, did you call WidgetCtx.initialize()");this.config=n,this.api=new U({config:n}),this.storageCtx=i?new H({storage:i}):void 0,this.contactCtx=new B({api:this.api,config:this.config,storageCtx:this.storageCtx}),this.sessionCtx=new q({api:this.api,contactCtx:this.contactCtx,sessionsPollingIntervalSeconds:p.pollingIntervalsSeconds.sessions}),this.messageCtx=new $({config:this.config,api:this.api,sessionCtx:this.sessionCtx,contactCtx:this.contactCtx}),this.activeSessionPollingCtx=new L({api:this.api,config:this.config,sessionCtx:this.sessionCtx,messageCtx:this.messageCtx,sessionPollingIntervalSeconds:p.pollingIntervalsSeconds.session}),this.routerCtx=new N({config:this.config,contactCtx:this.contactCtx,sessionCtx:this.sessionCtx,resetChat:this.resetChat})}};p.pollingIntervalsSeconds=null,p.initialize=async({config:n,storage:i})=>{var a,t;const h=await new U({config:n}).getExternalWidgetConfig();return p.pollingIntervalsSeconds={session:((a=h.data)==null?void 0:a.sessionPollingIntervalSeconds)||10,sessions:((t=h.data)==null?void 0:t.sessionsPollingIntervalSeconds)||60},new p({config:n,storage:i})};let k=p;exports.PrimitiveState=b;exports.WidgetCtx=k;
5
- //# sourceMappingURL=widget.ctx-CKRA-jh1.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"widget.ctx-CKRA-jh1.cjs","sources":["../src/headless/core/api/client.ts","../src/headless/core/api/api-caller.ts","../src/headless/core/utils/PrimitiveState.ts","../src/headless/core/utils/Poller.ts","../src/headless/core/utils/run-catching.ts","../src/headless/core/context/active-session-polling.ctx.ts","../src/headless/core/context/contact.ctx.ts","../src/headless/core/utils/uuid.ts","../src/headless/core/context/session.ctx.ts","../src/headless/core/context/message.ctx.ts","../src/headless/core/context/router.ctx.ts","../src/headless/core/context/storage.ctx.ts","../src/headless/core/context/widget.ctx.ts"],"sourcesContent":["import createClient, { type Middleware } from \"openapi-fetch\";\nimport type { paths } from \"./schema\";\nimport type { components } from \"./schema\";\n\ntype Options = {\n baseUrl: string;\n onRequest?: Middleware[\"onRequest\"];\n onResponse?: Middleware[\"onResponse\"];\n onError?: Middleware[\"onError\"];\n};\n\nconst defaultOnError: Middleware[\"onError\"] = (onErrorOptions) => {\n console.log(onErrorOptions.error);\n};\n\nexport const basicClient = (options: Options) => {\n const client = createClient<paths>({\n baseUrl: options.baseUrl,\n });\n\n const middlewares: Middleware = {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n onError: options.onError || defaultOnError,\n };\n\n client.use(middlewares);\n return client;\n};\n\nexport type Endpoint = keyof paths;\nexport type Dto = components[\"schemas\"];\n","import { type Dto, type Endpoint, basicClient } from \"./client\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport type { SendMessageDto, VoteInputDto } from \"../types/schemas\";\n\nexport class ApiCaller {\n private client: ReturnType<typeof basicClient>;\n private config: WidgetConfig;\n private userToken: string | null = null;\n\n constructor({\n config,\n }: {\n config: WidgetConfig;\n }) {\n this.config = config;\n const { baseUrl, headers } = this.constructClientOptions(\n config.user?.token,\n );\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n }\n\n private constructClientOptions = (token: string | null | undefined) => {\n const baseUrl =\n import.meta.env.MODE === \"test\"\n ? \"http://localhost:8080\"\n : this.config.apiUrl || \"https://api.open.cx\";\n const headers = {\n \"X-Bot-Token\": this.config.token,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: token ? `Bearer ${token}` : undefined,\n };\n\n return { baseUrl, headers };\n };\n\n private createOpenAPIClient = ({\n baseUrl,\n headers,\n }: ReturnType<typeof this.constructClientOptions>) => {\n return basicClient({\n baseUrl,\n onRequest: ({ request }) => {\n Object.entries(headers).forEach(([key, value]) => {\n if (value) {\n request.headers.set(key, value);\n }\n });\n },\n });\n };\n\n setAuthToken = (token: string) => {\n this.userToken = token;\n const { baseUrl, headers } = this.constructClientOptions(token);\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n };\n\n getExternalWidgetConfig = async () => {\n return await this.client.GET(\"/backend/widget/v2/config\", {\n params: { header: { \"X-Bot-Token\": this.config.token } },\n });\n };\n\n widgetPrelude = async () => {\n return await this.client.GET(\"/backend/widget/v2/prelude\", {\n params: { header: { \"X-Bot-Token\": this.config.token } },\n });\n };\n\n sendMessage = async (body: SendMessageDto, abortSignal?: AbortSignal) => {\n return await this.client.POST(\"/backend/widget/v2/chat/send\", {\n body,\n signal: abortSignal,\n });\n };\n\n createUnverifiedContact = async (body: Dto[\"CreateUnverifiedContactDto\"]) => {\n return await this.client.POST(\n \"/backend/widget/v2/contact/create-unverified\",\n {\n params: { header: { \"x-bot-token\": this.config.token } },\n body,\n },\n );\n };\n\n createSession = async (body: Dto[\"CreateWidgetSessionDto\"]) => {\n return await this.client.POST(\"/backend/widget/v2/create-session\", {\n body,\n });\n };\n\n pollSessionAndHistory = async ({\n sessionId,\n lastMessageTimestamp,\n abortSignal,\n }: {\n sessionId: string;\n lastMessageTimestamp?: string;\n abortSignal: AbortSignal;\n }) => {\n const query = lastMessageTimestamp ? { lastMessageTimestamp } : undefined;\n return await this.client.GET(\"/backend/widget/v2/poll/{sessionId}\", {\n params: { path: { sessionId }, query },\n signal: abortSignal,\n });\n };\n\n getSessions = async ({\n cursor,\n filters,\n abortSignal,\n }: {\n cursor: string | undefined;\n filters: Record<string, string>;\n abortSignal?: AbortSignal;\n }) => {\n return await this.client.GET(\"/backend/widget/v2/sessions\", {\n params: { query: { cursor, filters: JSON.stringify(filters) } },\n signal: abortSignal,\n });\n };\n\n /**\n * openapi-fetch usually works fine for file uploads, but this time around it parses the payload in a weird way and results in 413 errors (payload too large)\n * Anyway, good old XHR even does it better with progress events\n */\n uploadFile = async ({\n file,\n abortSignal,\n onProgress,\n }: {\n file: File;\n abortSignal: AbortSignal;\n onProgress?: (percentage: number) => void;\n }): Promise<Dto[\"UploadWidgetFileResponseDto\"]> => {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append(\"file\", file);\n\n const xhr = new XMLHttpRequest();\n\n // Set up abort functionality\n if (abortSignal) {\n abortSignal.addEventListener(\"abort\", () => {\n xhr.abort();\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n });\n\n // If already aborted, reject immediately\n if (abortSignal.aborted) {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n }\n\n xhr.upload.addEventListener(\"progress\", (event) => {\n if (event.lengthComputable && onProgress) {\n const percentage = Math.round((event.loaded / event.total) * 100);\n onProgress(percentage);\n }\n });\n\n // Handle completion\n xhr.addEventListener(\"load\", () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n const data = JSON.parse(xhr.responseText);\n resolve(data);\n } catch (error) {\n reject(new Error(`Failed to parse response: ${error}`));\n }\n } else {\n reject(new Error(`Upload failed with status: ${xhr.status}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n reject(new Error(\"Network error occurred\"));\n });\n\n xhr.addEventListener(\"timeout\", () => {\n reject(new Error(\"Upload timed out\"));\n });\n\n const { baseUrl } = this.constructClientOptions(this.userToken);\n\n const path = \"/backend/widget/v2/upload\" satisfies Endpoint\n const uploadUrl = `${baseUrl}${path}`;\n xhr.open(\"POST\", uploadUrl);\n\n xhr.setRequestHeader(\"X-Bot-Token\", this.config.token);\n if (this.userToken) {\n xhr.setRequestHeader(\"Authorization\", `Bearer ${this.userToken}`);\n }\n\n xhr.send(formData);\n });\n };\n\n vote = async (body: VoteInputDto) => {\n return await this.client.POST(\"/backend/widget/v2/chat/vote\", { body });\n };\n}\n","import isEqual from \"lodash.isequal\";\n\nexport type Subscriber<T> = (data: T) => void;\n\nexport class PrimitiveState<S> {\n private subscribers = new Set<Subscriber<S>>();\n private state: S;\n private initialState: S;\n\n constructor(state: S) {\n this.state = state;\n this.initialState = state;\n }\n\n get = (): S => this.state;\n\n set = (newState: S): void => {\n if (!isEqual(this.state, newState)) {\n this.state = newState;\n this.notifySubscribers(newState);\n }\n };\n\n setPartial = (_s: Partial<S>): void => {\n if (_s === undefined || _s === null) return;\n const newState = { ...this.state, ..._s };\n this.set(newState);\n };\n\n reset = (): void => {\n this.set(this.initialState);\n };\n\n private notifySubscribers = (state: S) => {\n const subscribersArray = Array.from(this.subscribers);\n subscribersArray.forEach((callback) => {\n try {\n callback(state);\n } catch (error) {\n if (import.meta.env.MODE !== \"test\") {\n console.error(error);\n }\n }\n });\n };\n\n subscribe = (callback: Subscriber<S>): (() => void) => {\n this.subscribers.add(callback);\n\n return () => {\n this.subscribers.delete(callback);\n };\n };\n}\n","import { PrimitiveState } from \"./PrimitiveState\";\n\nexport type PollingState = {\n isPolling: boolean;\n isError: boolean;\n};\n\nexport class Poller {\n state = new PrimitiveState<PollingState>({\n isPolling: false,\n isError: false,\n });\n private abortController = new AbortController();\n\n reset = () => {\n this.abortController.abort(\"Resetting poller\");\n this.stopPolling?.();\n this.stopPolling = null;\n };\n\n private stopPolling: (() => void) | null = null;\n\n startPolling = (\n cb: (abortSignal: AbortSignal) => Promise<void>,\n intervalMs: number,\n ) => {\n if (this.stopPolling) return;\n\n const timeouts: NodeJS.Timeout[] = [];\n\n const poll = async () => {\n this.abortController = new AbortController();\n this.state.setPartial({ isPolling: true });\n\n try {\n await cb(this.abortController.signal);\n } catch (error) {\n if (this.abortController.signal.aborted) {\n // If aborted, just return and do not schedule the nest poll\n return;\n }\n console.error(\"Failed to poll:\", error);\n this.state.setPartial({ isError: true });\n } finally {\n this.state.setPartial({ isPolling: false });\n }\n\n // Another check to stop scheduling polls in case someone removes the early return in the catch above\n if (this.abortController.signal.aborted) {\n console.log(\"Poller aborted, not scheduling anymore\");\n } else {\n timeouts.push(setTimeout(poll, intervalMs));\n }\n };\n\n poll();\n\n this.stopPolling = () => {\n timeouts.forEach(clearTimeout);\n this.state.reset();\n };\n };\n}\n","export type Result<T, E> =\n | { data: T; error?: undefined }\n | { data?: undefined; error: E };\n\n/**\n * Many thanks to @m-tabaza for this utility... Kotlin vibes\n */\nexport function runCatching<T, E = unknown>(\n callback: () => Promise<T>,\n): Promise<Result<T, E>>;\nexport function runCatching<T, E = unknown>(callback: () => T): Result<T, E>;\nexport function runCatching<T, E = unknown>(\n callback: () => T | Promise<T>,\n): Result<T, E> | Promise<Result<T, E>> {\n try {\n const result = callback();\n\n if (result instanceof Promise) {\n return result.then((data) => ({ data })).catch((error: E) => ({ error }));\n }\n\n return { data: result };\n } catch (error) {\n return { error: error as E };\n }\n}\n","import type { ApiCaller } from \"../api/api-caller\";\nimport type { MessageType } from \"../types/messages\";\nimport type { ActionCallDto, MessageDto } from \"../types/schemas\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport { Poller } from \"../utils/Poller\";\nimport { runCatching } from \"../utils/run-catching\";\nimport type { MessageCtx } from \"./message.ctx\";\nimport type { SessionCtx } from \"./session.ctx\";\n\nexport class ActiveSessionPollingCtx {\n private api: ApiCaller;\n private config: WidgetConfig;\n private sessionCtx: SessionCtx;\n private messageCtx: MessageCtx;\n private sessionPollingIntervalSeconds: number;\n\n private poller = new Poller();\n\n constructor({\n api,\n config,\n sessionCtx,\n messageCtx,\n sessionPollingIntervalSeconds,\n }: {\n api: ApiCaller;\n config: WidgetConfig;\n sessionCtx: SessionCtx;\n messageCtx: MessageCtx;\n sessionPollingIntervalSeconds: number;\n }) {\n this.api = api;\n this.config = config;\n this.sessionCtx = sessionCtx;\n this.messageCtx = messageCtx;\n this.sessionPollingIntervalSeconds = sessionPollingIntervalSeconds;\n\n this.registerPolling();\n }\n\n private registerPolling = () => {\n this.sessionCtx.sessionState.subscribe(({ session }) => {\n if (session?.id) {\n this.poller.startPolling(async (abortSignal) => {\n this.hackAndSlash(session.id, abortSignal);\n }, this.sessionPollingIntervalSeconds * 1000);\n } else {\n this.poller.reset();\n }\n });\n };\n\n private hackAndSlash = async (\n sessionId: string,\n abortSignal: AbortSignal,\n ): Promise<void> => {\n /**\n * This is a bit of an implicit contract... there are two cases here\n * 1. If there are no messages in state, it means the user selected a previous session from the sessions screen and got routed to the chat,\n * in this case, we want to show a loading indicator until the initial fetch is done\n * 2. There is a single message in state, which is the optimistically rendered user message,\n * in this case, we don't want to show a loading indicator\n */\n if (this.messageCtx.state.get().messages.length === 0) {\n this.messageCtx.state.setPartial({ isInitialFetchLoading: true });\n }\n\n const messages = this.messageCtx.state.get().messages;\n const lastMessageTimestamp =\n messages.length > 0\n ? messages[messages.length - 1]?.timestamp\n : undefined;\n\n const { data } = await this.api.pollSessionAndHistory({\n sessionId,\n abortSignal,\n lastMessageTimestamp,\n });\n\n if (data?.session) {\n this.sessionCtx.sessionState.setPartial({ session: data.session });\n this.sessionCtx.setSessions([data.session]);\n }\n\n if (data?.history && data.history.length > 0) {\n // Get a fresh reference to current messages after the poll is done\n const prevMessages = this.messageCtx.state.get().messages;\n const newMessages = data.history\n .map(this.mapHistoryToMessage)\n .filter(\n (newMsg) =>\n !prevMessages.some((existingMsg) => existingMsg.id === newMsg.id),\n );\n this.messageCtx.state.setPartial({\n messages: [...prevMessages, ...newMessages],\n });\n }\n\n if (this.messageCtx.state.get().isInitialFetchLoading) {\n this.messageCtx.state.setPartial({ isInitialFetchLoading: false });\n }\n };\n\n mapHistoryToMessage = (history: MessageDto): MessageType => {\n const commonFields = {\n id: history.publicId,\n timestamp: history.sentAt || \"\",\n attachments: history.attachments || undefined,\n };\n\n if (history.sender.kind === \"user\") {\n return {\n ...commonFields,\n type: \"FROM_USER\",\n content: history.content.text || \"\",\n deliveredAt: history.sentAt || \"\",\n };\n }\n\n if (history.sender.kind === \"agent\") {\n return {\n ...commonFields,\n type: \"FROM_AGENT\",\n component: \"agent_message\",\n data: {\n message: history.content.text || \"\",\n },\n agent: {\n name: history.sender.name || \"\",\n avatar: history.sender.avatar || \"\",\n id: null,\n isAi: false,\n },\n };\n }\n\n const action =\n history.actionCalls && history.actionCalls.length > 0\n ? history.actionCalls[history.actionCalls.length - 1]\n : undefined;\n\n return {\n ...commonFields,\n type: \"FROM_BOT\",\n component: \"bot_message\",\n agent: {\n id: null,\n name: this.config.bot?.name || \"\",\n isAi: true,\n avatar: this.config.bot?.avatar || \"\",\n },\n data: {\n message: history.content.text || \"\",\n action: action\n ? {\n name: action.actionName,\n data: this.extractActionResult(action),\n }\n : undefined,\n },\n };\n };\n\n extractActionResult = (action: ActionCallDto) => {\n const result = action.result;\n\n if (result === null) return result;\n if (typeof result !== \"object\") return result;\n\n if (\n \"responseBodyText\" in result &&\n typeof result.responseBodyText === \"string\"\n ) {\n const responseBodyText = result.responseBodyText;\n const parsed = runCatching(() => JSON.parse(responseBodyText)).data;\n if (parsed) return parsed;\n }\n\n return action.result;\n };\n}\n","import { PrimitiveState } from \"../utils/PrimitiveState\";\nimport { ApiCaller } from \"../api/api-caller\";\nimport { type WidgetConfig } from \"../types/widget-config\";\nimport { type Dto } from \"../api/client\";\nimport type { StorageCtx } from \"./storage.ctx\";\nimport { v4 } from \"uuid\";\n\ntype ContactState = {\n contact: {\n token: string;\n externalId: string | undefined;\n } | null;\n extraCollectedData: Record<string, string> | undefined;\n isCreatingUnverifiedContact: boolean;\n isErrorCreatingUnverifiedContact: boolean;\n};\n\nexport class ContactCtx {\n private config: WidgetConfig;\n private storageCtx?: StorageCtx;\n private api: ApiCaller;\n state: PrimitiveState<ContactState>;\n\n constructor({\n config,\n api,\n storageCtx,\n }: {\n api: ApiCaller;\n config: WidgetConfig;\n storageCtx?: StorageCtx;\n }) {\n this.config = config;\n this.storageCtx = storageCtx;\n this.api = api;\n\n this.state = new PrimitiveState<ContactState>({\n contact: config.user?.token\n ? {\n token: config.user.token,\n // Set optional externalId from config... not local storage\n externalId: config.user.externalId,\n }\n : null,\n extraCollectedData: undefined,\n isCreatingUnverifiedContact: false,\n isErrorCreatingUnverifiedContact: false,\n });\n\n this.autoCreateUnverifiedUserIfNotExists();\n }\n\n shouldCollectData = (): boolean => {\n if (!this.state.get().contact?.token && this.config.collectUserData) {\n return true;\n }\n return false;\n };\n\n private autoCreateUnverifiedUserIfNotExists = async () => {\n /**\n * If token is passed in config... we consider it as a verified user and do nothing (we don't force generate an externalId)\n * If a non-verified user take their token and place it in the config... the backend will refuse their requests saying that a non-verified token must have an externalId to create and get sessions\n */\n if (this.config.user?.token) return;\n\n /**\n * If collectUserData is true... we check if the user entered their credentials before, otherwise, show them the welcome screen so they can enter their credentials\n */\n if (this.config.collectUserData && !this.config.user?.data?.email) {\n /**\n * If extra data collection fields are passed,\n * we do not check for a persisted token.\n * This will force the contact to enter the extra data fields every time they visit the page.\n */\n if (this.config.extraDataCollectionFields?.length) {\n return;\n }\n\n const persistedToken = await this.storageCtx?.getContactToken();\n if (persistedToken) {\n await this.setUnverifiedContact(persistedToken);\n }\n // return early whether there is a persisted token or not\n return;\n }\n\n /**\n * If there is no email, then it is an anonymous contact, we check if the contact is persisted or we create a new one\n */\n if (!this.config.user?.data?.email) {\n const persistedToken = await this.storageCtx?.getContactToken();\n if (persistedToken) {\n await this.setUnverifiedContact(persistedToken);\n // return early only if there is a persisted token\n return;\n }\n }\n\n /**\n * If we reach here... then it is one of two\n * 1. There is an email passed in the config, let's just upsert the unverified contact without checking for persistence; maybe the email in the config did change.\n * 2. It is an anonymous contact (without an email) using this device for the first time.\n *\n * This is still safe even if the email in the config is tampered with by the contact, because there is a client-side externalId that will be generated for the current device...\n * So, only sessions created on this device will be accessible.\n */\n await this.createUnverifiedContact({\n email: this.config.user?.data?.email,\n non_verified_name: this.config.user?.data?.name || \"Anonymous\",\n non_verified_custom_data: this.config.user?.data?.customData,\n });\n };\n\n createUnverifiedContact = async (\n payload: Dto[\"CreateUnverifiedContactDto\"],\n extraCollectedData?: Record<string, string>,\n ): Promise<void> => {\n this.state.setPartial({ extraCollectedData });\n\n try {\n this.state.setPartial({\n isCreatingUnverifiedContact: true,\n isErrorCreatingUnverifiedContact: false,\n });\n\n const { data } = await this.api.createUnverifiedContact(payload);\n if (data?.token) {\n await this.setUnverifiedContact(data.token);\n } else {\n this.state.setPartial({ isErrorCreatingUnverifiedContact: true });\n }\n } finally {\n this.state.setPartial({ isCreatingUnverifiedContact: false });\n }\n };\n\n setUnverifiedContact = async (token: string) => {\n const persistedExternalId = await this.storageCtx?.getExternalContactId();\n /** Give priority to `externalId` from the config */\n const externalId: string =\n this.config.user?.externalId || persistedExternalId || v4();\n this.api.setAuthToken(token);\n // Set token in state after setting the token in the api handler\n await this.storageCtx?.setContactToken(token);\n await this.storageCtx?.setExternalContactId(externalId);\n this.state.setPartial({ contact: { token, externalId } });\n };\n}\n","import { v4 as uuidv4 } from \"uuid\";\n\nexport function genUuid() {\n return uuidv4();\n}\n","import type { ApiCaller } from \"../api/api-caller\";\nimport type { SessionDto } from \"../types/schemas\";\nimport { Poller } from \"../utils/Poller\";\nimport { PrimitiveState } from \"../utils/PrimitiveState\";\nimport type { ContactCtx } from \"./contact.ctx\";\n\ntype SessionState = {\n /**\n * The currently selected session.\n * Can be null if no session is selected, or if in chat screen and the session is not created yet.\n */\n session: SessionDto | null;\n isCreatingSession: boolean;\n};\ntype SessionsState = {\n /** List of all user sessions */\n data: SessionDto[];\n /** A cursor to get the next page of sessions */\n cursor: string | undefined;\n /** Indicates if no more pages are left */\n isLastPage: boolean;\n /** Did fetch for the first time */\n didStartInitialFetch: boolean;\n isInitialFetchLoading: boolean;\n};\n\nexport class SessionCtx {\n private api: ApiCaller;\n private contactCtx: ContactCtx;\n private sessionsPollingIntervalSeconds: number;\n private sessionsRefresher = new Poller();\n\n public sessionState = new PrimitiveState<SessionState>({\n session: null,\n isCreatingSession: false,\n });\n public sessionsState = new PrimitiveState<SessionsState>({\n data: [],\n cursor: undefined,\n isLastPage: false,\n didStartInitialFetch: false,\n /**\n * Initialize this as `true` so it always starts loading until the first fetch is done\n */\n isInitialFetchLoading: true,\n });\n\n constructor({\n api,\n contactCtx,\n sessionsPollingIntervalSeconds,\n }: {\n api: ApiCaller;\n contactCtx: ContactCtx;\n sessionsPollingIntervalSeconds: number;\n }) {\n this.api = api;\n this.contactCtx = contactCtx;\n this.sessionsPollingIntervalSeconds = sessionsPollingIntervalSeconds;\n\n this.registerSessionsRefresherWrapper();\n }\n\n /** Clears the session and stops polling */\n reset = async () => {\n // Reset the session only, leave sessions as-is\n this.sessionState.reset();\n };\n\n private registerSessionsRefresherWrapper = () => {\n if (\n // If the widget config was initially provided with a contact token, no state change would be triggered, so we just fetch\n this.contactCtx.state.get().contact?.token &&\n !this.sessionsState.get().didStartInitialFetch\n ) {\n this.registerSessionsRefresher();\n } else {\n // In other cases where auto authenticate is fired, the token would be eventually set in state, so we wait for it\n this.contactCtx.state.subscribe(({ contact }) => {\n if (contact?.token && !this.sessionsState.get().didStartInitialFetch) {\n this.registerSessionsRefresher();\n }\n });\n }\n };\n\n private registerSessionsRefresher = () => {\n this.sessionsRefresher.startPolling(async () => {\n if (this.sessionsState.get().didStartInitialFetch === false) {\n this.sessionsState.setPartial({ didStartInitialFetch: true });\n }\n\n await this.refreshSessions();\n\n if (this.sessionsState.get().isInitialFetchLoading === true) {\n this.sessionsState.setPartial({ isInitialFetchLoading: false });\n }\n }, this.sessionsPollingIntervalSeconds * 1000);\n };\n\n createSession = async () => {\n this.sessionState.setPartial({ session: null, isCreatingSession: true });\n\n const externalId = this.contactCtx.state.get().contact?.externalId;\n const { data: session, error } = await this.api.createSession({\n customData: externalId\n ? {\n external_id: externalId,\n }\n : undefined,\n });\n if (session) {\n this.sessionState.setPartial({ session, isCreatingSession: false });\n return session;\n }\n\n console.error(\"Failed to create session:\", error);\n return null;\n };\n\n loadMoreSessions = async () => {\n if (this.sessionsState.get().isLastPage) return;\n\n const { data } = await this.getSessions({\n cursor: this.sessionsState.get().cursor,\n });\n\n if (data) {\n const allSessions = [...this.sessionsState.get().data, ...data.items];\n // TODO sort by updated at\n const deduped = allSessions.filter(\n (s, i, self) => i === self.findIndex((_s) => s.id === _s.id),\n );\n\n this.sessionsState.setPartial({\n data: deduped,\n cursor: data.next || undefined,\n isLastPage: data.next === null,\n });\n }\n };\n\n private getSessions = async ({ cursor }: { cursor: string | undefined }) => {\n if (!this.contactCtx.state.get().contact?.token) return { data: null };\n\n const externalId = this.contactCtx.state.get().contact?.externalId;\n return await this.api.getSessions({\n cursor,\n filters: externalId\n ? {\n external_id: externalId,\n }\n : {},\n });\n };\n\n setSessions = (data: SessionDto[]) => {\n const sessions = [...data, ...this.sessionsState.get().data].filter(\n (s, i, self) => i === self.findIndex((_s) => s.id === _s.id),\n );\n this.sessionsState.setPartial({ data: sessions });\n }\n\n refreshSessions = async () => {\n // Get the first page only (pass no `cursor`)\n const { data } = await this.getSessions({ cursor: undefined });\n if (!data) return;\n this.setSessions(data.items);\n };\n}\n","import { ApiCaller } from \"../api/api-caller\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport type {\n BotMessageType,\n MessageType,\n UserMessageType,\n} from \"../types/messages\";\nimport type {\n MessageAttachmentType,\n SendMessageDto,\n SendMessageOutputDto,\n} from \"../types/schemas\";\nimport { PrimitiveState } from \"../utils/PrimitiveState\";\nimport { genUuid } from \"../utils/uuid\";\nimport { SessionCtx } from \"./session.ctx\";\nimport type { ContactCtx } from \"./contact.ctx\";\n\ntype MessageCtxState = {\n messages: MessageType[];\n isSendingMessage: boolean;\n lastAIResMightSolveUserIssue: boolean;\n isInitialFetchLoading: boolean;\n};\n\nexport class MessageCtx {\n private config: WidgetConfig;\n private api: ApiCaller;\n private contactCtx: ContactCtx;\n private sessionCtx: SessionCtx;\n\n public state = new PrimitiveState<MessageCtxState>({\n messages: [],\n isSendingMessage: false,\n lastAIResMightSolveUserIssue: false,\n isInitialFetchLoading: false,\n });\n\n private sendMessageAbortController = new AbortController();\n\n constructor({\n config,\n api,\n sessionCtx,\n contactCtx,\n }: {\n config: WidgetConfig;\n api: ApiCaller;\n sessionCtx: SessionCtx;\n contactCtx: ContactCtx;\n }) {\n this.config = config;\n this.api = api;\n this.sessionCtx = sessionCtx;\n this.contactCtx = contactCtx;\n }\n\n reset = () => {\n this.sendMessageAbortController.abort(\"Resetting chat\");\n this.state.reset();\n };\n\n sendMessage = async (input: {\n content: SendMessageDto[\"content\"];\n attachments?: SendMessageDto[\"attachments\"];\n }): Promise<void> => {\n /* ------------------------------------------------------ */\n /* Prevent sending if there is no content */\n /* ------------------------------------------------------ */\n if (\n !input.content.trim() &&\n (!input.attachments || input.attachments.length === 0)\n ) {\n console.warn(\"Cannot send an empty message of no content or attachments\");\n return;\n }\n /* ------------------------------------------------------ */\n /* Prevent sending while waiting for AI res */\n /* ------------------------------------------------------ */\n const isSending = this.state.get().isSendingMessage;\n const isAssignedToAI =\n this.sessionCtx.sessionState.get().session?.assignee.kind === \"ai\";\n const _messages = this.state.get().messages;\n const lastMessage =\n _messages.length > 0 ? _messages[_messages.length - 1] : undefined;\n if (\n (isAssignedToAI && isSending) ||\n // If last message is from user, then bot response did not arrive yet\n (isAssignedToAI && lastMessage?.type === \"FROM_USER\")\n ) {\n console.warn(\"Cannot send messages while awaiting AI response\");\n return;\n }\n\n this.sendMessageAbortController = new AbortController();\n\n /* ------------------------------------------------------ */\n /* Clear last AI response might solve user issue */\n /* ------------------------------------------------------ */\n this.state.setPartial({ lastAIResMightSolveUserIssue: false });\n\n try {\n this.state.setPartial({ isSendingMessage: true });\n /* ------------------------------------------------------ */\n /* Optimistically add message to rendered messages */\n /* ------------------------------------------------------ */\n const userMessage = this.toUserMessage(\n input.content.trim(),\n input.attachments || undefined,\n );\n const currentMessages = this.state.get().messages;\n this.state.setPartial({\n messages: [...currentMessages, userMessage],\n });\n\n /* ------------------------------------------------------ */\n /* Create session if not exists */\n /* ------------------------------------------------------ */\n if (!this.sessionCtx.sessionState.get().session?.id) {\n const createdSession = await this.sessionCtx.createSession();\n\n // TODO: apply some retry logic here\n if (!createdSession) {\n console.error(\"Failed to create session\");\n return;\n }\n\n // Refresh sessions list instantly to get the newly created session in the sessions list\n void this.sessionCtx.refreshSessions();\n }\n const sessionId = this.sessionCtx.sessionState.get().session?.id;\n if (!sessionId) return;\n /* ------------------------------------------------------ */\n /* Send and wait for bot response */\n /* ------------------------------------------------------ */\n const { data } = await this.api.sendMessage(\n {\n uuid: userMessage.id,\n bot_token: this.config.token,\n headers: this.config.headers,\n query_params: this.config.queryParams,\n session_id: sessionId,\n content: userMessage.content,\n attachments: input.attachments,\n clientContext: this.config.context,\n },\n this.sendMessageAbortController.signal,\n );\n\n if (data?.success) {\n /* ------------------------------------------------------ */\n /* Append bot reply if not fetched from polling */\n /* ------------------------------------------------------ */\n const botMessage = this.toBotMessage(data);\n if (botMessage) {\n const prevMessages = this.state.get().messages;\n const shouldAppend = !prevMessages.some(\n (m) => m.id === botMessage.id,\n );\n if (!shouldAppend) {\n this.state.setPartial({\n lastAIResMightSolveUserIssue:\n data.autopilotResponse?.mightSolveUserIssue ||\n data.uiResponse?.mightSolveUserIssue,\n });\n return;\n }\n this.state.setPartial({\n messages: [...prevMessages, botMessage],\n lastAIResMightSolveUserIssue:\n data.autopilotResponse?.mightSolveUserIssue ||\n data.uiResponse?.mightSolveUserIssue,\n });\n }\n } else {\n const errorMessage = this.toBotErrorMessage(\n data?.error?.message || \"Unknown error occurred\",\n );\n const currentMessages = this.state.get().messages;\n this.state.setPartial({\n messages: [...currentMessages, errorMessage],\n });\n }\n } catch (error) {\n if (!this.sendMessageAbortController.signal.aborted) {\n console.error(\"Failed to send message:\", error);\n }\n } finally {\n this.state.setPartial({ isSendingMessage: false });\n }\n };\n\n private toUserMessage = (\n content: string,\n attachments?: MessageAttachmentType[],\n ): UserMessageType => {\n const messageContent = (() => {\n const extraCollectedData = this.contactCtx.state.get().extraCollectedData;\n // Prepend extra collected data if this is the first message in the session\n if (\n this.state.get().messages.length === 0 &&\n extraCollectedData &&\n Object.keys(extraCollectedData).length > 0\n ) {\n const data = Object.entries(extraCollectedData)\n .filter(([_, value]) => !!value)\n .map(([key, value]) => `${key}: ${value}`)\n .join(\" \\n\");\n return `${data} \\n\\n${content}`;\n }\n\n return content;\n })();\n\n return {\n id: genUuid(),\n type: \"FROM_USER\",\n content: messageContent,\n deliveredAt: new Date().toISOString(),\n attachments,\n timestamp: new Date().toISOString(),\n };\n };\n\n private toBotMessage = (\n response: SendMessageOutputDto,\n ): BotMessageType | null => {\n if (response.success && response.autopilotResponse) {\n return {\n type: \"FROM_BOT\",\n id: response.autopilotResponse.id || genUuid(),\n timestamp: new Date().toISOString(),\n component: \"bot_message\",\n agent: this.config.bot\n ? {\n name: this.config.bot.name || \"\",\n isAi: true,\n avatar: this.config.bot.avatar || \"\",\n id: null,\n }\n : undefined,\n data: {\n message: response.autopilotResponse.value.content,\n action: response.uiResponse?.value.name\n ? {\n name: response.uiResponse.value.name,\n data: response.uiResponse.value.request_response,\n }\n : undefined,\n },\n };\n }\n\n return null;\n };\n\n private toBotErrorMessage = (message: string): BotMessageType => {\n return {\n type: \"FROM_BOT\",\n id: genUuid(),\n timestamp: new Date().toISOString(),\n component: \"TEXT\",\n data: {\n message,\n variant: \"error\",\n action: undefined,\n },\n };\n };\n}\n","import type { WidgetConfig } from \"../types/widget-config\";\nimport { PrimitiveState } from \"../utils/PrimitiveState\";\nimport type { ContactCtx } from \"./contact.ctx\";\nimport type { SessionCtx } from \"./session.ctx\";\nimport type { WidgetCtx } from \"./widget.ctx\";\n\ntype RouterState = {\n screen:\n | /** A welcome screen to collect user data. Useful in public non-logged-in environments */\n \"welcome\"\n /** Show a list of the user's previous sessions */\n | \"sessions\"\n /** Self-explanatory */\n | \"chat\";\n};\n\nexport class RouterCtx {\n state: PrimitiveState<RouterState>;\n\n private config: WidgetConfig;\n private contactCtx: ContactCtx;\n private sessionCtx: SessionCtx;\n private resetChat: WidgetCtx[\"resetChat\"];\n\n constructor({\n config,\n contactCtx,\n sessionCtx,\n resetChat,\n }: {\n config: WidgetConfig;\n contactCtx: ContactCtx;\n sessionCtx: SessionCtx;\n resetChat: WidgetCtx[\"resetChat\"];\n }) {\n this.state = new PrimitiveState<RouterState>({\n screen: contactCtx.shouldCollectData() ? \"welcome\" : \"sessions\",\n });\n this.config = config;\n this.contactCtx = contactCtx;\n this.sessionCtx = sessionCtx;\n this.resetChat = resetChat;\n\n this.registerRoutingListener();\n }\n\n private registerRoutingListener = () => {\n this.contactCtx.state.subscribe(({ contact }) => {\n // Auto navigate to sessions screen after collecting user data\n if (contact?.token && this.state.get().screen === \"welcome\") {\n this.state.setPartial({ screen: \"sessions\" });\n }\n });\n\n this.sessionCtx.sessionsState.subscribe(\n ({ isInitialFetchLoading, data }) => {\n if (data.length) return;\n if (this.config.router?.goToChatIfNoSessions === false) return;\n\n // Auto navigate to chat screen if contact has no previous sessions\n if (!isInitialFetchLoading && this.state.get().screen !== \"chat\") {\n this.toChatScreen();\n }\n },\n );\n };\n\n toSessionsScreen = () => {\n this.resetChat();\n this.state.setPartial({ screen: \"sessions\" });\n };\n\n /**\n * @param sessionId The ID of the session to open, or `undefined` if it is a new chat session\n */\n toChatScreen = (sessionId?: string) => {\n this.resetChat();\n\n if (sessionId) {\n const session = this.sessionCtx.sessionsState\n .get()\n .data.find((s) => s.id === sessionId);\n // Do not navigate if session is not found (this shouldn't happen, unless a wrong ID is passed)\n if (!session) return;\n this.sessionCtx.sessionState.setPartial({ session });\n }\n\n this.state.setPartial({ screen: \"chat\" });\n };\n}\n","import type { ExternalStorage } from \"../types/external-storage\";\n\nexport class StorageCtx {\n private storage: ExternalStorage;\n private KEYS = {\n contactToken: \"opencx__widget__contactToken\",\n externalContactId: \"opencx__widget__externalContactId\",\n };\n\n constructor({ storage }: { storage: ExternalStorage }) {\n this.storage = storage;\n }\n\n setContactToken = async (token: string) => {\n await this.storage.set(this.KEYS.contactToken, token);\n };\n getContactToken = async () => {\n return this.storage.get(this.KEYS.contactToken);\n };\n\n setExternalContactId = async (id: string) => {\n await this.storage.set(this.KEYS.externalContactId, id);\n };\n getExternalContactId = async () => {\n return this.storage.get(this.KEYS.externalContactId);\n };\n}\n","import { ApiCaller } from \"../api/api-caller\";\nimport type { ExternalStorage } from \"../types/external-storage\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport { ActiveSessionPollingCtx } from \"./active-session-polling.ctx\";\nimport { ContactCtx } from \"./contact.ctx\";\nimport { MessageCtx } from \"./message.ctx\";\nimport { RouterCtx } from \"./router.ctx\";\nimport { SessionCtx } from \"./session.ctx\";\nimport { StorageCtx } from \"./storage.ctx\";\n\nexport class WidgetCtx {\n public config: WidgetConfig;\n public api: ApiCaller;\n\n public contactCtx: ContactCtx;\n public sessionCtx: SessionCtx;\n public messageCtx: MessageCtx;\n public routerCtx: RouterCtx;\n public storageCtx?: StorageCtx;\n\n private static pollingIntervalsSeconds: {\n session: number;\n sessions: number;\n } | null = null;\n private activeSessionPollingCtx: ActiveSessionPollingCtx;\n\n private constructor({\n config,\n storage,\n }: { config: WidgetConfig; storage?: ExternalStorage }) {\n if (!WidgetCtx.pollingIntervalsSeconds) {\n throw Error(\n \"Widget polling values are not defined, did you call WidgetCtx.initialize()\",\n );\n }\n\n this.config = config;\n this.api = new ApiCaller({ config });\n this.storageCtx = storage ? new StorageCtx({ storage }) : undefined;\n\n this.contactCtx = new ContactCtx({\n api: this.api,\n config: this.config,\n storageCtx: this.storageCtx,\n });\n\n this.sessionCtx = new SessionCtx({\n api: this.api,\n contactCtx: this.contactCtx,\n sessionsPollingIntervalSeconds:\n WidgetCtx.pollingIntervalsSeconds.sessions,\n });\n\n this.messageCtx = new MessageCtx({\n config: this.config,\n api: this.api,\n sessionCtx: this.sessionCtx,\n contactCtx: this.contactCtx,\n });\n\n this.activeSessionPollingCtx = new ActiveSessionPollingCtx({\n api: this.api,\n config: this.config,\n sessionCtx: this.sessionCtx,\n messageCtx: this.messageCtx,\n sessionPollingIntervalSeconds: WidgetCtx.pollingIntervalsSeconds.session,\n });\n\n this.routerCtx = new RouterCtx({\n config: this.config,\n contactCtx: this.contactCtx,\n sessionCtx: this.sessionCtx,\n resetChat: this.resetChat,\n });\n }\n\n static initialize = async ({\n config,\n storage,\n }: { config: WidgetConfig; storage?: ExternalStorage }) => {\n const externalConfig = await new ApiCaller({\n config,\n }).getExternalWidgetConfig();\n\n this.pollingIntervalsSeconds = {\n session: externalConfig.data?.sessionPollingIntervalSeconds || 10,\n sessions: externalConfig.data?.sessionsPollingIntervalSeconds || 60,\n };\n\n return new WidgetCtx({\n config,\n storage,\n });\n };\n\n resetChat = () => {\n this.sessionCtx.reset();\n this.messageCtx.reset();\n };\n}\n"],"names":["defaultOnError","onErrorOptions","basicClient","options","client","createClient","middlewares","ApiCaller","config","token","baseUrl","headers","request","key","value","body","abortSignal","sessionId","lastMessageTimestamp","query","cursor","filters","file","onProgress","resolve","reject","formData","xhr","event","percentage","data","error","uploadUrl","_a","PrimitiveState","state","newState","isEqual","_s","callback","Poller","cb","intervalMs","timeouts","poll","runCatching","result","ActiveSessionPollingCtx","api","sessionCtx","messageCtx","sessionPollingIntervalSeconds","session","messages","prevMessages","newMessages","newMsg","existingMsg","history","commonFields","action","_b","responseBodyText","parsed","ContactCtx","storageCtx","_c","_d","persistedToken","_e","_g","_f","_h","_j","_i","_l","_k","_n","_m","payload","extraCollectedData","persistedExternalId","externalId","v4","genUuid","uuidv4","SessionCtx","contactCtx","sessionsPollingIntervalSeconds","contact","deduped","s","i","self","sessions","MessageCtx","input","isSending","isAssignedToAI","_messages","lastMessage","userMessage","currentMessages","botMessage","m","errorMessage","content","attachments","messageContent","_","response","message","RouterCtx","resetChat","isInitialFetchLoading","StorageCtx","storage","id","_WidgetCtx","externalConfig","WidgetCtx"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"widget.ctx-DJ72-NkO.js","sources":["../src/headless/core/api/client.ts","../src/headless/core/api/api-caller.ts","../src/headless/core/utils/PrimitiveState.ts","../src/headless/core/utils/Poller.ts","../src/headless/core/utils/run-catching.ts","../src/headless/core/context/active-session-polling.ctx.ts","../src/headless/core/context/contact.ctx.ts","../src/headless/core/utils/uuid.ts","../src/headless/core/context/session.ctx.ts","../src/headless/core/context/message.ctx.ts","../src/headless/core/context/router.ctx.ts","../src/headless/core/context/storage.ctx.ts","../src/headless/core/context/widget.ctx.ts"],"sourcesContent":["import createClient, { type Middleware } from \"openapi-fetch\";\nimport type { paths } from \"./schema\";\nimport type { components } from \"./schema\";\n\ntype Options = {\n baseUrl: string;\n onRequest?: Middleware[\"onRequest\"];\n onResponse?: Middleware[\"onResponse\"];\n onError?: Middleware[\"onError\"];\n};\n\nconst defaultOnError: Middleware[\"onError\"] = (onErrorOptions) => {\n console.log(onErrorOptions.error);\n};\n\nexport const basicClient = (options: Options) => {\n const client = createClient<paths>({\n baseUrl: options.baseUrl,\n });\n\n const middlewares: Middleware = {\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n onError: options.onError || defaultOnError,\n };\n\n client.use(middlewares);\n return client;\n};\n\nexport type Endpoint = keyof paths;\nexport type Dto = components[\"schemas\"];\n","import { type Dto, type Endpoint, basicClient } from \"./client\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport type { SendMessageDto, VoteInputDto } from \"../types/schemas\";\n\nexport class ApiCaller {\n private client: ReturnType<typeof basicClient>;\n private config: WidgetConfig;\n private userToken: string | null = null;\n\n constructor({\n config,\n }: {\n config: WidgetConfig;\n }) {\n this.config = config;\n const { baseUrl, headers } = this.constructClientOptions(\n config.user?.token,\n );\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n }\n\n private constructClientOptions = (token: string | null | undefined) => {\n const baseUrl =\n import.meta.env.MODE === \"test\"\n ? \"http://localhost:8080\"\n : this.config.apiUrl || \"https://api.open.cx\";\n const headers = {\n \"X-Bot-Token\": this.config.token,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: token ? `Bearer ${token}` : undefined,\n };\n\n return { baseUrl, headers };\n };\n\n private createOpenAPIClient = ({\n baseUrl,\n headers,\n }: ReturnType<typeof this.constructClientOptions>) => {\n return basicClient({\n baseUrl,\n onRequest: ({ request }) => {\n Object.entries(headers).forEach(([key, value]) => {\n if (value) {\n request.headers.set(key, value);\n }\n });\n },\n });\n };\n\n setAuthToken = (token: string) => {\n this.userToken = token;\n const { baseUrl, headers } = this.constructClientOptions(token);\n this.client = this.createOpenAPIClient({ baseUrl, headers });\n };\n\n getExternalWidgetConfig = async () => {\n return await this.client.GET(\"/backend/widget/v2/config\", {\n params: { header: { \"X-Bot-Token\": this.config.token } },\n });\n };\n\n widgetPrelude = async () => {\n return await this.client.GET(\"/backend/widget/v2/prelude\", {\n params: { header: { \"X-Bot-Token\": this.config.token } },\n });\n };\n\n sendMessage = async (body: SendMessageDto, abortSignal?: AbortSignal) => {\n return await this.client.POST(\"/backend/widget/v2/chat/send\", {\n body,\n signal: abortSignal,\n });\n };\n\n createUnverifiedContact = async (body: Dto[\"CreateUnverifiedContactDto\"]) => {\n return await this.client.POST(\n \"/backend/widget/v2/contact/create-unverified\",\n {\n params: { header: { \"x-bot-token\": this.config.token } },\n body,\n },\n );\n };\n\n createSession = async (body: Dto[\"CreateWidgetSessionDto\"]) => {\n return await this.client.POST(\"/backend/widget/v2/create-session\", {\n body,\n });\n };\n\n pollSessionAndHistory = async ({\n sessionId,\n lastMessageTimestamp,\n abortSignal,\n }: {\n sessionId: string;\n lastMessageTimestamp?: string;\n abortSignal: AbortSignal;\n }) => {\n const query = lastMessageTimestamp ? { lastMessageTimestamp } : undefined;\n return await this.client.GET(\"/backend/widget/v2/poll/{sessionId}\", {\n params: { path: { sessionId }, query },\n signal: abortSignal,\n });\n };\n\n getSessions = async ({\n cursor,\n filters,\n abortSignal,\n }: {\n cursor: string | undefined;\n filters: Record<string, string>;\n abortSignal?: AbortSignal;\n }) => {\n return await this.client.GET(\"/backend/widget/v2/sessions\", {\n params: { query: { cursor, filters: JSON.stringify(filters) } },\n signal: abortSignal,\n });\n };\n\n /**\n * openapi-fetch usually works fine for file uploads, but this time around it parses the payload in a weird way and results in 413 errors (payload too large)\n * Anyway, good old XHR even does it better with progress events\n */\n uploadFile = async ({\n file,\n abortSignal,\n onProgress,\n }: {\n file: File;\n abortSignal: AbortSignal;\n onProgress?: (percentage: number) => void;\n }): Promise<Dto[\"UploadWidgetFileResponseDto\"]> => {\n return new Promise((resolve, reject) => {\n const formData = new FormData();\n formData.append(\"file\", file);\n\n const xhr = new XMLHttpRequest();\n\n // Set up abort functionality\n if (abortSignal) {\n abortSignal.addEventListener(\"abort\", () => {\n xhr.abort();\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n });\n\n // If already aborted, reject immediately\n if (abortSignal.aborted) {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n }\n\n xhr.upload.addEventListener(\"progress\", (event) => {\n if (event.lengthComputable && onProgress) {\n const percentage = Math.round((event.loaded / event.total) * 100);\n onProgress(percentage);\n }\n });\n\n // Handle completion\n xhr.addEventListener(\"load\", () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n const data = JSON.parse(xhr.responseText);\n resolve(data);\n } catch (error) {\n reject(new Error(`Failed to parse response: ${error}`));\n }\n } else {\n reject(new Error(`Upload failed with status: ${xhr.status}`));\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n reject(new Error(\"Network error occurred\"));\n });\n\n xhr.addEventListener(\"timeout\", () => {\n reject(new Error(\"Upload timed out\"));\n });\n\n const { baseUrl } = this.constructClientOptions(this.userToken);\n\n const path = \"/backend/widget/v2/upload\" satisfies Endpoint\n const uploadUrl = `${baseUrl}${path}`;\n xhr.open(\"POST\", uploadUrl);\n\n xhr.setRequestHeader(\"X-Bot-Token\", this.config.token);\n if (this.userToken) {\n xhr.setRequestHeader(\"Authorization\", `Bearer ${this.userToken}`);\n }\n\n xhr.send(formData);\n });\n };\n\n vote = async (body: VoteInputDto) => {\n return await this.client.POST(\"/backend/widget/v2/chat/vote\", { body });\n };\n}\n","import isEqual from \"lodash.isequal\";\n\nexport type Subscriber<T> = (data: T) => void;\n\nexport class PrimitiveState<S> {\n private subscribers = new Set<Subscriber<S>>();\n private state: S;\n private initialState: S;\n\n constructor(state: S) {\n this.state = state;\n this.initialState = state;\n }\n\n get = (): S => this.state;\n\n set = (newState: S): void => {\n if (!isEqual(this.state, newState)) {\n this.state = newState;\n this.notifySubscribers(newState);\n }\n };\n\n setPartial = (_s: Partial<S>): void => {\n if (_s === undefined || _s === null) return;\n const newState = { ...this.state, ..._s };\n this.set(newState);\n };\n\n reset = (): void => {\n this.set(this.initialState);\n };\n\n private notifySubscribers = (state: S) => {\n const subscribersArray = Array.from(this.subscribers);\n subscribersArray.forEach((callback) => {\n try {\n callback(state);\n } catch (error) {\n if (import.meta.env.MODE !== \"test\") {\n console.error(error);\n }\n }\n });\n };\n\n subscribe = (callback: Subscriber<S>): (() => void) => {\n this.subscribers.add(callback);\n\n return () => {\n this.subscribers.delete(callback);\n };\n };\n}\n","import { PrimitiveState } from \"./PrimitiveState\";\n\nexport type PollingState = {\n isPolling: boolean;\n isError: boolean;\n};\n\nexport class Poller {\n state = new PrimitiveState<PollingState>({\n isPolling: false,\n isError: false,\n });\n private abortController = new AbortController();\n\n reset = () => {\n this.abortController.abort(\"Resetting poller\");\n this.stopPolling?.();\n this.stopPolling = null;\n };\n\n private stopPolling: (() => void) | null = null;\n\n startPolling = (\n cb: (abortSignal: AbortSignal) => Promise<void>,\n intervalMs: number,\n ) => {\n if (this.stopPolling) return;\n\n const timeouts: NodeJS.Timeout[] = [];\n\n const poll = async () => {\n this.abortController = new AbortController();\n this.state.setPartial({ isPolling: true });\n\n try {\n await cb(this.abortController.signal);\n } catch (error) {\n if (this.abortController.signal.aborted) {\n // If aborted, just return and do not schedule the nest poll\n return;\n }\n console.error(\"Failed to poll:\", error);\n this.state.setPartial({ isError: true });\n } finally {\n this.state.setPartial({ isPolling: false });\n }\n\n // Another check to stop scheduling polls in case someone removes the early return in the catch above\n if (this.abortController.signal.aborted) {\n console.log(\"Poller aborted, not scheduling anymore\");\n } else {\n timeouts.push(setTimeout(poll, intervalMs));\n }\n };\n\n poll();\n\n this.stopPolling = () => {\n timeouts.forEach(clearTimeout);\n this.state.reset();\n };\n };\n}\n","export type Result<T, E> =\n | { data: T; error?: undefined }\n | { data?: undefined; error: E };\n\n/**\n * Many thanks to @m-tabaza for this utility... Kotlin vibes\n */\nexport function runCatching<T, E = unknown>(\n callback: () => Promise<T>,\n): Promise<Result<T, E>>;\nexport function runCatching<T, E = unknown>(callback: () => T): Result<T, E>;\nexport function runCatching<T, E = unknown>(\n callback: () => T | Promise<T>,\n): Result<T, E> | Promise<Result<T, E>> {\n try {\n const result = callback();\n\n if (result instanceof Promise) {\n return result.then((data) => ({ data })).catch((error: E) => ({ error }));\n }\n\n return { data: result };\n } catch (error) {\n return { error: error as E };\n }\n}\n","import type { ApiCaller } from \"../api/api-caller\";\nimport type { MessageType } from \"../types/messages\";\nimport type { ActionCallDto, MessageDto } from \"../types/schemas\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport { Poller } from \"../utils/Poller\";\nimport { runCatching } from \"../utils/run-catching\";\nimport type { MessageCtx } from \"./message.ctx\";\nimport type { SessionCtx } from \"./session.ctx\";\n\nexport class ActiveSessionPollingCtx {\n private api: ApiCaller;\n private config: WidgetConfig;\n private sessionCtx: SessionCtx;\n private messageCtx: MessageCtx;\n private sessionPollingIntervalSeconds: number;\n\n private poller = new Poller();\n\n constructor({\n api,\n config,\n sessionCtx,\n messageCtx,\n sessionPollingIntervalSeconds,\n }: {\n api: ApiCaller;\n config: WidgetConfig;\n sessionCtx: SessionCtx;\n messageCtx: MessageCtx;\n sessionPollingIntervalSeconds: number;\n }) {\n this.api = api;\n this.config = config;\n this.sessionCtx = sessionCtx;\n this.messageCtx = messageCtx;\n this.sessionPollingIntervalSeconds = sessionPollingIntervalSeconds;\n\n this.registerPolling();\n }\n\n private registerPolling = () => {\n this.sessionCtx.sessionState.subscribe(({ session }) => {\n if (session?.id) {\n this.poller.startPolling(async (abortSignal) => {\n this.hackAndSlash(session.id, abortSignal);\n }, this.sessionPollingIntervalSeconds * 1000);\n } else {\n this.poller.reset();\n }\n });\n };\n\n private hackAndSlash = async (\n sessionId: string,\n abortSignal: AbortSignal,\n ): Promise<void> => {\n /**\n * This is a bit of an implicit contract... there are two cases here\n * 1. If there are no messages in state, it means the user selected a previous session from the sessions screen and got routed to the chat,\n * in this case, we want to show a loading indicator until the initial fetch is done\n * 2. There is a single message in state, which is the optimistically rendered user message,\n * in this case, we don't want to show a loading indicator\n */\n if (this.messageCtx.state.get().messages.length === 0) {\n this.messageCtx.state.setPartial({ isInitialFetchLoading: true });\n }\n\n const messages = this.messageCtx.state.get().messages;\n const lastMessageTimestamp =\n messages.length > 0\n ? messages[messages.length - 1]?.timestamp\n : undefined;\n\n const { data } = await this.api.pollSessionAndHistory({\n sessionId,\n abortSignal,\n lastMessageTimestamp,\n });\n\n if (data?.session) {\n this.sessionCtx.sessionState.setPartial({ session: data.session });\n this.sessionCtx.setSessions([data.session]);\n }\n\n if (data?.history && data.history.length > 0) {\n // Get a fresh reference to current messages after the poll is done\n const prevMessages = this.messageCtx.state.get().messages;\n const newMessages = data.history\n .map(this.mapHistoryToMessage)\n .filter(\n (newMsg) =>\n !prevMessages.some((existingMsg) => existingMsg.id === newMsg.id),\n );\n this.messageCtx.state.setPartial({\n messages: [...prevMessages, ...newMessages],\n });\n }\n\n if (this.messageCtx.state.get().isInitialFetchLoading) {\n this.messageCtx.state.setPartial({ isInitialFetchLoading: false });\n }\n };\n\n mapHistoryToMessage = (history: MessageDto): MessageType => {\n const commonFields = {\n id: history.publicId,\n timestamp: history.sentAt || \"\",\n attachments: history.attachments || undefined,\n };\n\n if (history.sender.kind === \"user\") {\n return {\n ...commonFields,\n type: \"FROM_USER\",\n content: history.content.text || \"\",\n deliveredAt: history.sentAt || \"\",\n };\n }\n\n if (history.sender.kind === \"agent\") {\n return {\n ...commonFields,\n type: \"FROM_AGENT\",\n component: \"agent_message\",\n data: {\n message: history.content.text || \"\",\n },\n agent: {\n name: history.sender.name || \"\",\n avatar: history.sender.avatar || \"\",\n id: null,\n isAi: false,\n },\n };\n }\n\n const action =\n history.actionCalls && history.actionCalls.length > 0\n ? history.actionCalls[history.actionCalls.length - 1]\n : undefined;\n\n return {\n ...commonFields,\n type: \"FROM_BOT\",\n component: \"bot_message\",\n agent: {\n id: null,\n name: this.config.bot?.name || \"\",\n isAi: true,\n avatar: this.config.bot?.avatar || \"\",\n },\n data: {\n message: history.content.text || \"\",\n action: action\n ? {\n name: action.actionName,\n data: this.extractActionResult(action),\n }\n : undefined,\n },\n };\n };\n\n extractActionResult = (action: ActionCallDto) => {\n const result = action.result;\n\n if (result === null) return result;\n if (typeof result !== \"object\") return result;\n\n if (\n \"responseBodyText\" in result &&\n typeof result.responseBodyText === \"string\"\n ) {\n const responseBodyText = result.responseBodyText;\n const parsed = runCatching(() => JSON.parse(responseBodyText)).data;\n if (parsed) return parsed;\n }\n\n return action.result;\n };\n}\n","import { PrimitiveState } from \"../utils/PrimitiveState\";\nimport { ApiCaller } from \"../api/api-caller\";\nimport { type WidgetConfig } from \"../types/widget-config\";\nimport { type Dto } from \"../api/client\";\nimport type { StorageCtx } from \"./storage.ctx\";\nimport { v4 } from \"uuid\";\n\ntype ContactState = {\n contact: {\n token: string;\n externalId: string | undefined;\n } | null;\n extraCollectedData: Record<string, string> | undefined;\n isCreatingUnverifiedContact: boolean;\n isErrorCreatingUnverifiedContact: boolean;\n};\n\nexport class ContactCtx {\n private config: WidgetConfig;\n private storageCtx?: StorageCtx;\n private api: ApiCaller;\n state: PrimitiveState<ContactState>;\n\n constructor({\n config,\n api,\n storageCtx,\n }: {\n api: ApiCaller;\n config: WidgetConfig;\n storageCtx?: StorageCtx;\n }) {\n this.config = config;\n this.storageCtx = storageCtx;\n this.api = api;\n\n this.state = new PrimitiveState<ContactState>({\n contact: config.user?.token\n ? {\n token: config.user.token,\n // Set optional externalId from config... not local storage\n externalId: config.user.externalId,\n }\n : null,\n extraCollectedData: undefined,\n isCreatingUnverifiedContact: false,\n isErrorCreatingUnverifiedContact: false,\n });\n\n this.autoCreateUnverifiedUserIfNotExists();\n }\n\n shouldCollectData = (): boolean => {\n if (!this.state.get().contact?.token && this.config.collectUserData) {\n return true;\n }\n return false;\n };\n\n private autoCreateUnverifiedUserIfNotExists = async () => {\n /**\n * If token is passed in config... we consider it as a verified user and do nothing (we don't force generate an externalId)\n * If a non-verified user take their token and place it in the config... the backend will refuse their requests saying that a non-verified token must have an externalId to create and get sessions\n */\n if (this.config.user?.token) return;\n\n /**\n * If collectUserData is true... we check if the user entered their credentials before, otherwise, show them the welcome screen so they can enter their credentials\n */\n if (this.config.collectUserData && !this.config.user?.data?.email) {\n /**\n * If extra data collection fields are passed,\n * we do not check for a persisted token.\n * This will force the contact to enter the extra data fields every time they visit the page.\n */\n if (this.config.extraDataCollectionFields?.length) {\n return;\n }\n\n const persistedToken = await this.storageCtx?.getContactToken();\n if (persistedToken) {\n await this.setUnverifiedContact(persistedToken);\n }\n // return early whether there is a persisted token or not\n return;\n }\n\n /**\n * If there is no email, then it is an anonymous contact, we check if the contact is persisted or we create a new one\n */\n if (!this.config.user?.data?.email) {\n const persistedToken = await this.storageCtx?.getContactToken();\n if (persistedToken) {\n await this.setUnverifiedContact(persistedToken);\n // return early only if there is a persisted token\n return;\n }\n }\n\n /**\n * If we reach here... then it is one of two\n * 1. There is an email passed in the config, let's just upsert the unverified contact without checking for persistence; maybe the email in the config did change.\n * 2. It is an anonymous contact (without an email) using this device for the first time.\n *\n * This is still safe even if the email in the config is tampered with by the contact, because there is a client-side externalId that will be generated for the current device...\n * So, only sessions created on this device will be accessible.\n */\n await this.createUnverifiedContact({\n email: this.config.user?.data?.email,\n non_verified_name: this.config.user?.data?.name || \"Anonymous\",\n non_verified_custom_data: this.config.user?.data?.customData,\n });\n };\n\n createUnverifiedContact = async (\n payload: Dto[\"CreateUnverifiedContactDto\"],\n extraCollectedData?: Record<string, string>,\n ): Promise<void> => {\n this.state.setPartial({ extraCollectedData });\n\n try {\n this.state.setPartial({\n isCreatingUnverifiedContact: true,\n isErrorCreatingUnverifiedContact: false,\n });\n\n const { data } = await this.api.createUnverifiedContact(payload);\n if (data?.token) {\n await this.setUnverifiedContact(data.token);\n } else {\n this.state.setPartial({ isErrorCreatingUnverifiedContact: true });\n }\n } finally {\n this.state.setPartial({ isCreatingUnverifiedContact: false });\n }\n };\n\n setUnverifiedContact = async (token: string) => {\n const persistedExternalId = await this.storageCtx?.getExternalContactId();\n /** Give priority to `externalId` from the config */\n const externalId: string =\n this.config.user?.externalId || persistedExternalId || v4();\n this.api.setAuthToken(token);\n // Set token in state after setting the token in the api handler\n await this.storageCtx?.setContactToken(token);\n await this.storageCtx?.setExternalContactId(externalId);\n this.state.setPartial({ contact: { token, externalId } });\n };\n}\n","import { v4 as uuidv4 } from \"uuid\";\n\nexport function genUuid() {\n return uuidv4();\n}\n","import type { ApiCaller } from \"../api/api-caller\";\nimport type { SessionDto } from \"../types/schemas\";\nimport { Poller } from \"../utils/Poller\";\nimport { PrimitiveState } from \"../utils/PrimitiveState\";\nimport type { ContactCtx } from \"./contact.ctx\";\n\ntype SessionState = {\n /**\n * The currently selected session.\n * Can be null if no session is selected, or if in chat screen and the session is not created yet.\n */\n session: SessionDto | null;\n isCreatingSession: boolean;\n};\ntype SessionsState = {\n /** List of all user sessions */\n data: SessionDto[];\n /** A cursor to get the next page of sessions */\n cursor: string | undefined;\n /** Indicates if no more pages are left */\n isLastPage: boolean;\n /** Did fetch for the first time */\n didStartInitialFetch: boolean;\n isInitialFetchLoading: boolean;\n};\n\nexport class SessionCtx {\n private api: ApiCaller;\n private contactCtx: ContactCtx;\n private sessionsPollingIntervalSeconds: number;\n private sessionsRefresher = new Poller();\n\n public sessionState = new PrimitiveState<SessionState>({\n session: null,\n isCreatingSession: false,\n });\n public sessionsState = new PrimitiveState<SessionsState>({\n data: [],\n cursor: undefined,\n isLastPage: false,\n didStartInitialFetch: false,\n /**\n * Initialize this as `true` so it always starts loading until the first fetch is done\n */\n isInitialFetchLoading: true,\n });\n\n constructor({\n api,\n contactCtx,\n sessionsPollingIntervalSeconds,\n }: {\n api: ApiCaller;\n contactCtx: ContactCtx;\n sessionsPollingIntervalSeconds: number;\n }) {\n this.api = api;\n this.contactCtx = contactCtx;\n this.sessionsPollingIntervalSeconds = sessionsPollingIntervalSeconds;\n\n this.registerSessionsRefresherWrapper();\n }\n\n /** Clears the session and stops polling */\n reset = async () => {\n // Reset the session only, leave sessions as-is\n this.sessionState.reset();\n };\n\n private registerSessionsRefresherWrapper = () => {\n if (\n // If the widget config was initially provided with a contact token, no state change would be triggered, so we just fetch\n this.contactCtx.state.get().contact?.token &&\n !this.sessionsState.get().didStartInitialFetch\n ) {\n this.registerSessionsRefresher();\n } else {\n // In other cases where auto authenticate is fired, the token would be eventually set in state, so we wait for it\n this.contactCtx.state.subscribe(({ contact }) => {\n if (contact?.token && !this.sessionsState.get().didStartInitialFetch) {\n this.registerSessionsRefresher();\n }\n });\n }\n };\n\n private registerSessionsRefresher = () => {\n this.sessionsRefresher.startPolling(async () => {\n if (this.sessionsState.get().didStartInitialFetch === false) {\n this.sessionsState.setPartial({ didStartInitialFetch: true });\n }\n\n await this.refreshSessions();\n\n if (this.sessionsState.get().isInitialFetchLoading === true) {\n this.sessionsState.setPartial({ isInitialFetchLoading: false });\n }\n }, this.sessionsPollingIntervalSeconds * 1000);\n };\n\n createSession = async () => {\n this.sessionState.setPartial({ session: null, isCreatingSession: true });\n\n const externalId = this.contactCtx.state.get().contact?.externalId;\n const { data: session, error } = await this.api.createSession({\n customData: externalId\n ? {\n external_id: externalId,\n }\n : undefined,\n });\n if (session) {\n this.sessionState.setPartial({ session, isCreatingSession: false });\n return session;\n }\n\n console.error(\"Failed to create session:\", error);\n return null;\n };\n\n loadMoreSessions = async () => {\n if (this.sessionsState.get().isLastPage) return;\n\n const { data } = await this.getSessions({\n cursor: this.sessionsState.get().cursor,\n });\n\n if (data) {\n const allSessions = [...this.sessionsState.get().data, ...data.items];\n // TODO sort by updated at\n const deduped = allSessions.filter(\n (s, i, self) => i === self.findIndex((_s) => s.id === _s.id),\n );\n\n this.sessionsState.setPartial({\n data: deduped,\n cursor: data.next || undefined,\n isLastPage: data.next === null,\n });\n }\n };\n\n private getSessions = async ({ cursor }: { cursor: string | undefined }) => {\n if (!this.contactCtx.state.get().contact?.token) return { data: null };\n\n const externalId = this.contactCtx.state.get().contact?.externalId;\n return await this.api.getSessions({\n cursor,\n filters: externalId\n ? {\n external_id: externalId,\n }\n : {},\n });\n };\n\n setSessions = (data: SessionDto[]) => {\n const sessions = [...data, ...this.sessionsState.get().data].filter(\n (s, i, self) => i === self.findIndex((_s) => s.id === _s.id),\n );\n this.sessionsState.setPartial({ data: sessions });\n }\n\n refreshSessions = async () => {\n // Get the first page only (pass no `cursor`)\n const { data } = await this.getSessions({ cursor: undefined });\n if (!data) return;\n this.setSessions(data.items);\n };\n}\n","import { ApiCaller } from \"../api/api-caller\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport type {\n BotMessageType,\n MessageType,\n UserMessageType,\n} from \"../types/messages\";\nimport type {\n MessageAttachmentType,\n SendMessageDto,\n SendMessageOutputDto,\n} from \"../types/schemas\";\nimport { PrimitiveState } from \"../utils/PrimitiveState\";\nimport { genUuid } from \"../utils/uuid\";\nimport { SessionCtx } from \"./session.ctx\";\nimport type { ContactCtx } from \"./contact.ctx\";\n\ntype MessageCtxState = {\n messages: MessageType[];\n isSendingMessage: boolean;\n lastAIResMightSolveUserIssue: boolean;\n isInitialFetchLoading: boolean;\n};\n\nexport class MessageCtx {\n private config: WidgetConfig;\n private api: ApiCaller;\n private contactCtx: ContactCtx;\n private sessionCtx: SessionCtx;\n\n public state = new PrimitiveState<MessageCtxState>({\n messages: [],\n isSendingMessage: false,\n lastAIResMightSolveUserIssue: false,\n isInitialFetchLoading: false,\n });\n\n private sendMessageAbortController = new AbortController();\n\n constructor({\n config,\n api,\n sessionCtx,\n contactCtx,\n }: {\n config: WidgetConfig;\n api: ApiCaller;\n sessionCtx: SessionCtx;\n contactCtx: ContactCtx;\n }) {\n this.config = config;\n this.api = api;\n this.sessionCtx = sessionCtx;\n this.contactCtx = contactCtx;\n }\n\n reset = () => {\n this.sendMessageAbortController.abort(\"Resetting chat\");\n this.state.reset();\n };\n\n sendMessage = async (input: {\n content: SendMessageDto[\"content\"];\n attachments?: SendMessageDto[\"attachments\"];\n }): Promise<void> => {\n /* ------------------------------------------------------ */\n /* Prevent sending if there is no content */\n /* ------------------------------------------------------ */\n if (\n !input.content.trim() &&\n (!input.attachments || input.attachments.length === 0)\n ) {\n console.warn(\"Cannot send an empty message of no content or attachments\");\n return;\n }\n /* ------------------------------------------------------ */\n /* Prevent sending while waiting for AI res */\n /* ------------------------------------------------------ */\n const isSending = this.state.get().isSendingMessage;\n const isAssignedToAI =\n this.sessionCtx.sessionState.get().session?.assignee.kind === \"ai\";\n const _messages = this.state.get().messages;\n const lastMessage =\n _messages.length > 0 ? _messages[_messages.length - 1] : undefined;\n if (\n (isAssignedToAI && isSending) ||\n // If last message is from user, then bot response did not arrive yet\n (isAssignedToAI && lastMessage?.type === \"FROM_USER\")\n ) {\n console.warn(\"Cannot send messages while awaiting AI response\");\n return;\n }\n\n this.sendMessageAbortController = new AbortController();\n\n /* ------------------------------------------------------ */\n /* Clear last AI response might solve user issue */\n /* ------------------------------------------------------ */\n this.state.setPartial({ lastAIResMightSolveUserIssue: false });\n\n try {\n this.state.setPartial({ isSendingMessage: true });\n /* ------------------------------------------------------ */\n /* Optimistically add message to rendered messages */\n /* ------------------------------------------------------ */\n const userMessage = this.toUserMessage(\n input.content.trim(),\n input.attachments || undefined,\n );\n const currentMessages = this.state.get().messages;\n this.state.setPartial({\n messages: [...currentMessages, userMessage],\n });\n\n /* ------------------------------------------------------ */\n /* Create session if not exists */\n /* ------------------------------------------------------ */\n if (!this.sessionCtx.sessionState.get().session?.id) {\n const createdSession = await this.sessionCtx.createSession();\n\n // TODO: apply some retry logic here\n if (!createdSession) {\n console.error(\"Failed to create session\");\n return;\n }\n\n // Refresh sessions list instantly to get the newly created session in the sessions list\n void this.sessionCtx.refreshSessions();\n }\n const sessionId = this.sessionCtx.sessionState.get().session?.id;\n if (!sessionId) return;\n /* ------------------------------------------------------ */\n /* Send and wait for bot response */\n /* ------------------------------------------------------ */\n const { data } = await this.api.sendMessage(\n {\n uuid: userMessage.id,\n bot_token: this.config.token,\n headers: this.config.headers,\n query_params: this.config.queryParams,\n session_id: sessionId,\n content: userMessage.content,\n attachments: input.attachments,\n clientContext: this.config.context,\n },\n this.sendMessageAbortController.signal,\n );\n\n if (data?.success) {\n /* ------------------------------------------------------ */\n /* Append bot reply if not fetched from polling */\n /* ------------------------------------------------------ */\n const botMessage = this.toBotMessage(data);\n if (botMessage) {\n const prevMessages = this.state.get().messages;\n const shouldAppend = !prevMessages.some(\n (m) => m.id === botMessage.id,\n );\n if (!shouldAppend) {\n this.state.setPartial({\n lastAIResMightSolveUserIssue:\n data.autopilotResponse?.mightSolveUserIssue ||\n data.uiResponse?.mightSolveUserIssue,\n });\n return;\n }\n this.state.setPartial({\n messages: [...prevMessages, botMessage],\n lastAIResMightSolveUserIssue:\n data.autopilotResponse?.mightSolveUserIssue ||\n data.uiResponse?.mightSolveUserIssue,\n });\n }\n } else {\n const errorMessage = this.toBotErrorMessage(\n data?.error?.message || \"Unknown error occurred\",\n );\n const currentMessages = this.state.get().messages;\n this.state.setPartial({\n messages: [...currentMessages, errorMessage],\n });\n }\n } catch (error) {\n if (!this.sendMessageAbortController.signal.aborted) {\n console.error(\"Failed to send message:\", error);\n }\n } finally {\n this.state.setPartial({ isSendingMessage: false });\n }\n };\n\n private toUserMessage = (\n content: string,\n attachments?: MessageAttachmentType[],\n ): UserMessageType => {\n const messageContent = (() => {\n const extraCollectedData = this.contactCtx.state.get().extraCollectedData;\n // Prepend extra collected data if this is the first message in the session\n if (\n this.state.get().messages.length === 0 &&\n extraCollectedData &&\n Object.keys(extraCollectedData).length > 0\n ) {\n const data = Object.entries(extraCollectedData)\n .filter(([_, value]) => !!value)\n .map(([key, value]) => `${key}: ${value}`)\n .join(\" \\n\");\n return `${data} \\n\\n${content}`;\n }\n\n return content;\n })();\n\n return {\n id: genUuid(),\n type: \"FROM_USER\",\n content: messageContent,\n deliveredAt: new Date().toISOString(),\n attachments,\n timestamp: new Date().toISOString(),\n };\n };\n\n private toBotMessage = (\n response: SendMessageOutputDto,\n ): BotMessageType | null => {\n if (response.success && response.autopilotResponse) {\n return {\n type: \"FROM_BOT\",\n id: response.autopilotResponse.id || genUuid(),\n timestamp: new Date().toISOString(),\n component: \"bot_message\",\n agent: this.config.bot\n ? {\n name: this.config.bot.name || \"\",\n isAi: true,\n avatar: this.config.bot.avatar || \"\",\n id: null,\n }\n : undefined,\n data: {\n message: response.autopilotResponse.value.content,\n action: response.uiResponse?.value.name\n ? {\n name: response.uiResponse.value.name,\n data: response.uiResponse.value.request_response,\n }\n : undefined,\n },\n };\n }\n\n return null;\n };\n\n private toBotErrorMessage = (message: string): BotMessageType => {\n return {\n type: \"FROM_BOT\",\n id: genUuid(),\n timestamp: new Date().toISOString(),\n component: \"TEXT\",\n data: {\n message,\n variant: \"error\",\n action: undefined,\n },\n };\n };\n}\n","import type { WidgetConfig } from \"../types/widget-config\";\nimport { PrimitiveState } from \"../utils/PrimitiveState\";\nimport type { ContactCtx } from \"./contact.ctx\";\nimport type { SessionCtx } from \"./session.ctx\";\nimport type { WidgetCtx } from \"./widget.ctx\";\n\ntype RouterState = {\n screen:\n | /** A welcome screen to collect user data. Useful in public non-logged-in environments */\n \"welcome\"\n /** Show a list of the user's previous sessions */\n | \"sessions\"\n /** Self-explanatory */\n | \"chat\";\n};\n\nexport class RouterCtx {\n state: PrimitiveState<RouterState>;\n\n private config: WidgetConfig;\n private contactCtx: ContactCtx;\n private sessionCtx: SessionCtx;\n private resetChat: WidgetCtx[\"resetChat\"];\n\n constructor({\n config,\n contactCtx,\n sessionCtx,\n resetChat,\n }: {\n config: WidgetConfig;\n contactCtx: ContactCtx;\n sessionCtx: SessionCtx;\n resetChat: WidgetCtx[\"resetChat\"];\n }) {\n this.state = new PrimitiveState<RouterState>({\n screen: contactCtx.shouldCollectData() ? \"welcome\" : \"sessions\",\n });\n this.config = config;\n this.contactCtx = contactCtx;\n this.sessionCtx = sessionCtx;\n this.resetChat = resetChat;\n\n this.registerRoutingListener();\n }\n\n private registerRoutingListener = () => {\n this.contactCtx.state.subscribe(({ contact }) => {\n // Auto navigate to sessions screen after collecting user data\n if (contact?.token && this.state.get().screen === \"welcome\") {\n this.state.setPartial({ screen: \"sessions\" });\n }\n });\n\n this.sessionCtx.sessionsState.subscribe(\n ({ isInitialFetchLoading, data }) => {\n if (data.length) return;\n if (this.config.router?.goToChatIfNoSessions === false) return;\n\n // Auto navigate to chat screen if contact has no previous sessions\n if (!isInitialFetchLoading && this.state.get().screen !== \"chat\") {\n this.toChatScreen();\n }\n },\n );\n };\n\n toSessionsScreen = () => {\n this.resetChat();\n this.state.setPartial({ screen: \"sessions\" });\n };\n\n /**\n * @param sessionId The ID of the session to open, or `undefined` if it is a new chat session\n */\n toChatScreen = (sessionId?: string) => {\n this.resetChat();\n\n if (sessionId) {\n const session = this.sessionCtx.sessionsState\n .get()\n .data.find((s) => s.id === sessionId);\n // Do not navigate if session is not found (this shouldn't happen, unless a wrong ID is passed)\n if (!session) return;\n this.sessionCtx.sessionState.setPartial({ session });\n }\n\n this.state.setPartial({ screen: \"chat\" });\n };\n}\n","import type { ExternalStorage } from \"../types/external-storage\";\n\nexport class StorageCtx {\n private storage: ExternalStorage;\n private KEYS = {\n contactToken: \"opencx__widget__contactToken\",\n externalContactId: \"opencx__widget__externalContactId\",\n };\n\n constructor({ storage }: { storage: ExternalStorage }) {\n this.storage = storage;\n }\n\n setContactToken = async (token: string) => {\n await this.storage.set(this.KEYS.contactToken, token);\n };\n getContactToken = async () => {\n return this.storage.get(this.KEYS.contactToken);\n };\n\n setExternalContactId = async (id: string) => {\n await this.storage.set(this.KEYS.externalContactId, id);\n };\n getExternalContactId = async () => {\n return this.storage.get(this.KEYS.externalContactId);\n };\n}\n","import { ApiCaller } from \"../api/api-caller\";\nimport type { ExternalStorage } from \"../types/external-storage\";\nimport type { WidgetConfig } from \"../types/widget-config\";\nimport { ActiveSessionPollingCtx } from \"./active-session-polling.ctx\";\nimport { ContactCtx } from \"./contact.ctx\";\nimport { MessageCtx } from \"./message.ctx\";\nimport { RouterCtx } from \"./router.ctx\";\nimport { SessionCtx } from \"./session.ctx\";\nimport { StorageCtx } from \"./storage.ctx\";\n\nexport class WidgetCtx {\n public config: WidgetConfig;\n public api: ApiCaller;\n\n public contactCtx: ContactCtx;\n public sessionCtx: SessionCtx;\n public messageCtx: MessageCtx;\n public routerCtx: RouterCtx;\n public storageCtx?: StorageCtx;\n\n private static pollingIntervalsSeconds: {\n session: number;\n sessions: number;\n } | null = null;\n private activeSessionPollingCtx: ActiveSessionPollingCtx;\n\n private constructor({\n config,\n storage,\n }: { config: WidgetConfig; storage?: ExternalStorage }) {\n if (!WidgetCtx.pollingIntervalsSeconds) {\n throw Error(\n \"Widget polling values are not defined, did you call WidgetCtx.initialize()\",\n );\n }\n\n this.config = config;\n this.api = new ApiCaller({ config });\n this.storageCtx = storage ? new StorageCtx({ storage }) : undefined;\n\n this.contactCtx = new ContactCtx({\n api: this.api,\n config: this.config,\n storageCtx: this.storageCtx,\n });\n\n this.sessionCtx = new SessionCtx({\n api: this.api,\n contactCtx: this.contactCtx,\n sessionsPollingIntervalSeconds:\n WidgetCtx.pollingIntervalsSeconds.sessions,\n });\n\n this.messageCtx = new MessageCtx({\n config: this.config,\n api: this.api,\n sessionCtx: this.sessionCtx,\n contactCtx: this.contactCtx,\n });\n\n this.activeSessionPollingCtx = new ActiveSessionPollingCtx({\n api: this.api,\n config: this.config,\n sessionCtx: this.sessionCtx,\n messageCtx: this.messageCtx,\n sessionPollingIntervalSeconds: WidgetCtx.pollingIntervalsSeconds.session,\n });\n\n this.routerCtx = new RouterCtx({\n config: this.config,\n contactCtx: this.contactCtx,\n sessionCtx: this.sessionCtx,\n resetChat: this.resetChat,\n });\n }\n\n static initialize = async ({\n config,\n storage,\n }: { config: WidgetConfig; storage?: ExternalStorage }) => {\n const externalConfig = await new ApiCaller({\n config,\n }).getExternalWidgetConfig();\n\n this.pollingIntervalsSeconds = {\n session: externalConfig.data?.sessionPollingIntervalSeconds || 10,\n sessions: externalConfig.data?.sessionsPollingIntervalSeconds || 60,\n };\n\n return new WidgetCtx({\n config,\n storage,\n });\n };\n\n resetChat = () => {\n this.sessionCtx.reset();\n this.messageCtx.reset();\n };\n}\n"],"names":["defaultOnError","onErrorOptions","basicClient","options","client","createClient","middlewares","ApiCaller","config","token","baseUrl","headers","request","key","value","body","abortSignal","sessionId","lastMessageTimestamp","query","cursor","filters","file","onProgress","resolve","reject","formData","xhr","event","percentage","data","error","uploadUrl","_a","PrimitiveState","state","newState","isEqual","_s","callback","Poller","cb","intervalMs","timeouts","poll","runCatching","result","ActiveSessionPollingCtx","api","sessionCtx","messageCtx","sessionPollingIntervalSeconds","session","messages","prevMessages","newMessages","newMsg","existingMsg","history","commonFields","action","_b","responseBodyText","parsed","ContactCtx","storageCtx","_c","_d","persistedToken","_e","_g","_f","_h","_j","_i","_l","_k","_n","_m","payload","extraCollectedData","persistedExternalId","externalId","v4","genUuid","uuidv4","SessionCtx","contactCtx","sessionsPollingIntervalSeconds","contact","deduped","s","i","self","sessions","MessageCtx","input","isSending","isAssignedToAI","_messages","lastMessage","userMessage","currentMessages","botMessage","m","errorMessage","content","attachments","messageContent","_","response","message","RouterCtx","resetChat","isInitialFetchLoading","StorageCtx","storage","id","_WidgetCtx","externalConfig","WidgetCtx"],"mappings":"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"}