@opencx/widget 3.0.89 → 3.0.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./widget.ctx-RfaE5VPy.cjs");function r(e,i){console.error(`Missing case for ${e} in ${i}`)}exports.PrimitiveState=t.PrimitiveState;exports.WidgetCtx=t.WidgetCtx;exports.isExhaustive=r;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./widget.ctx-6xcbtF7q.cjs"),e=require("./is-exhaustive-9o43S91P.cjs");exports.PrimitiveState=t.PrimitiveState;exports.WidgetCtx=t.WidgetCtx;exports.isExhaustive=e.isExhaustive;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/headless/core/utils/is-exhaustive.ts"],"sourcesContent":["export function isExhaustive(value: never, funcName: string) {\n console.error(`Missing case for ${value} in ${funcName}`);\n}\n"],"names":["isExhaustive","value","funcName"],"mappings":"6HAAgB,SAAAA,EAAaC,EAAcC,EAAkB,CAC3D,QAAQ,MAAM,oBAAoBD,CAAK,OAAOC,CAAQ,EAAE,CAC1D"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/dist/index.js CHANGED
@@ -1,10 +1,8 @@
1
- import { P as s, W as a } from "./widget.ctx-Db3DyLM5.js";
2
- function t(i, e) {
3
- console.error(`Missing case for ${i} in ${e}`);
4
- }
1
+ import { P as e, W as a } from "./widget.ctx-uAWzif3-.js";
2
+ import { i as s } from "./is-exhaustive-DGJzQK69.js";
5
3
  export {
6
- s as PrimitiveState,
4
+ e as PrimitiveState,
7
5
  a as WidgetCtx,
8
- t as isExhaustive
6
+ s as isExhaustive
9
7
  };
10
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/headless/core/utils/is-exhaustive.ts"],"sourcesContent":["export function isExhaustive(value: never, funcName: string) {\n console.error(`Missing case for ${value} in ${funcName}`);\n}\n"],"names":["isExhaustive","value","funcName"],"mappings":";AAAgB,SAAAA,EAAaC,GAAcC,GAAkB;AAC3D,UAAQ,MAAM,oBAAoBD,CAAK,OAAOC,CAAQ,EAAE;AAC1D;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -0,0 +1,2 @@
1
+ "use strict";function e(s,i){console.error(`Missing case for ${s} in ${i}`)}exports.isExhaustive=e;
2
+ //# sourceMappingURL=is-exhaustive-9o43S91P.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-exhaustive-9o43S91P.cjs","sources":["../src/headless/core/utils/is-exhaustive.ts"],"sourcesContent":["export function isExhaustive(value: never, funcName: string) {\n console.error(`Missing case for ${value} in ${funcName}`);\n}\n"],"names":["isExhaustive","value","funcName"],"mappings":"aAAgB,SAAAA,EAAaC,EAAcC,EAAkB,CAC3D,QAAQ,MAAM,oBAAoBD,CAAK,OAAOC,CAAQ,EAAE,CAC1D"}
@@ -0,0 +1,7 @@
1
+ function o(i, s) {
2
+ console.error(`Missing case for ${i} in ${s}`);
3
+ }
4
+ export {
5
+ o as i
6
+ };
7
+ //# sourceMappingURL=is-exhaustive-DGJzQK69.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-exhaustive-DGJzQK69.js","sources":["../src/headless/core/utils/is-exhaustive.ts"],"sourcesContent":["export function isExhaustive(value: never, funcName: string) {\n console.error(`Missing case for ${value} in ${funcName}`);\n}\n"],"names":["isExhaustive","value","funcName"],"mappings":"AAAgB,SAAAA,EAAaC,GAAcC,GAAkB;AAC3D,UAAQ,MAAM,oBAAoBD,CAAK,OAAOC,CAAQ,EAAE;AAC1D;"}
package/dist/react.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useModes-C4Sdixy0.cjs");function o(t,s,i){const{widgetCtx:{api:u}}=e.useWidget();return e._default(async r=>u.vote({action:r==="up"?"upvote":"downvote",messagePublicId:t,sessionId:s}).then(i),[u,t,s,i])}exports.WidgetProvider=e.WidgetProvider;exports.WidgetTriggerProvider=e.WidgetTriggerProvider;exports.useConfig=e.useConfig;exports.useContact=e.useContact;exports.useIsAwaitingBotReply=e.useIsAwaitingBotReply;exports.useMessages=e.useMessages;exports.useModes=e.useModes;exports.usePreludeData=e.usePreludeData;exports.usePrimitiveState=e.usePrimitiveState;exports.useSessions=e.useSessions;exports.useUploadFiles=e.useUploadFiles;exports.useWidget=e.useWidget;exports.useWidgetRouter=e.useWidgetRouter;exports.useWidgetTrigger=e.useWidgetTrigger;exports.useVote=o;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useModes-ZmjqOTMd.cjs"),o=require("react-use/lib/useAsyncFn");function g(s,t,i){const{widgetCtx:{api:u}}=e.useWidget();return o(async r=>u.vote({action:r==="up"?"upvote":"downvote",messagePublicId:s,sessionId:t}).then(i),[u,s,t,i])}exports.WidgetProvider=e.WidgetProvider;exports.WidgetTriggerProvider=e.WidgetTriggerProvider;exports.useConfig=e.useConfig;exports.useContact=e.useContact;exports.useIsAwaitingBotReply=e.useIsAwaitingBotReply;exports.useMessages=e.useMessages;exports.useModes=e.useModes;exports.usePreludeData=e.usePreludeData;exports.usePrimitiveState=e.usePrimitiveState;exports.useSessions=e.useSessions;exports.useUploadFiles=e.useUploadFiles;exports.useWidget=e.useWidget;exports.useWidgetRouter=e.useWidgetRouter;exports.useWidgetTrigger=e.useWidgetTrigger;exports.useVote=g;
2
2
  //# sourceMappingURL=react.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.cjs","sources":["../src/headless/react/hooks/useVote.ts"],"sourcesContent":["import useAsyncFn from 'react-use/lib/useAsyncFn';\nimport { useWidget } from '../WidgetProvider';\n\n/**\n * @param id\n * @param onSuccess\n * @returns\n */\nexport function useVote(id: string, sessionId: string, onSuccess?: () => void) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async (action: 'up' | 'down') => {\n return api\n .vote({\n action: action === 'up' ? 'upvote' : 'downvote',\n messagePublicId: id,\n sessionId,\n })\n .then(onSuccess);\n },\n [api, id, sessionId, onSuccess],\n );\n}\n\n/**\n * @param id\n * @param onSuccess\n * @deprecated use useVote instead\n */\nexport function useUpvote(\n id: string,\n sessionId: string,\n onSuccess?: () => void,\n) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async () =>\n api\n .vote({ action: 'upvote', messagePublicId: id, sessionId })\n .then(onSuccess),\n [api, id, sessionId, onSuccess],\n );\n}\n\n/**\n * @param id\n * @param onSuccess\n * @deprecated use useVote instead\n */\nexport function useDownvote(\n id: string,\n sessionId: string,\n onSuccess?: () => void,\n) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async () =>\n api\n .vote({ action: 'downvote', messagePublicId: id, sessionId })\n .then(onSuccess),\n [api, id, sessionId, onSuccess],\n );\n}\n"],"names":["useVote","id","sessionId","onSuccess","api","useWidget","useAsyncFn","action"],"mappings":"2HAQgB,SAAAA,EAAQC,EAAYC,EAAmBC,EAAwB,CACvE,KAAA,CACJ,UAAW,CAAE,IAAAC,CAAI,GACfC,EAAU,UAAA,EACP,OAAAC,EAAA,SACL,MAAOC,GACEH,EACJ,KAAK,CACJ,OAAQG,IAAW,KAAO,SAAW,WACrC,gBAAiBN,EACjB,UAAAC,CAAA,CACD,EACA,KAAKC,CAAS,EAEnB,CAACC,EAAKH,EAAIC,EAAWC,CAAS,CAAA,CAElC"}
1
+ {"version":3,"file":"react.cjs","sources":["../src/headless/react/hooks/useVote.ts"],"sourcesContent":["import useAsyncFn from 'react-use/lib/useAsyncFn';\nimport { useWidget } from '../WidgetProvider';\n\n/**\n * @param id\n * @param onSuccess\n * @returns\n */\nexport function useVote(id: string, sessionId: string, onSuccess?: () => void) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async (action: 'up' | 'down') => {\n return api\n .vote({\n action: action === 'up' ? 'upvote' : 'downvote',\n messagePublicId: id,\n sessionId,\n })\n .then(onSuccess);\n },\n [api, id, sessionId, onSuccess],\n );\n}\n\n/**\n * @param id\n * @param onSuccess\n * @deprecated use useVote instead\n */\nexport function useUpvote(\n id: string,\n sessionId: string,\n onSuccess?: () => void,\n) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async () =>\n api\n .vote({ action: 'upvote', messagePublicId: id, sessionId })\n .then(onSuccess),\n [api, id, sessionId, onSuccess],\n );\n}\n\n/**\n * @param id\n * @param onSuccess\n * @deprecated use useVote instead\n */\nexport function useDownvote(\n id: string,\n sessionId: string,\n onSuccess?: () => void,\n) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async () =>\n api\n .vote({ action: 'downvote', messagePublicId: id, sessionId })\n .then(onSuccess),\n [api, id, sessionId, onSuccess],\n );\n}\n"],"names":["useVote","id","sessionId","onSuccess","api","useWidget","useAsyncFn","action"],"mappings":"iKAQgB,SAAAA,EAAQC,EAAYC,EAAmBC,EAAwB,CACvE,KAAA,CACJ,UAAW,CAAE,IAAAC,CAAI,GACfC,EAAU,UAAA,EACP,OAAAC,EACL,MAAOC,GACEH,EACJ,KAAK,CACJ,OAAQG,IAAW,KAAO,SAAW,WACrC,gBAAiBN,EACjB,UAAAC,CAAA,CACD,EACA,KAAKC,CAAS,EAEnB,CAACC,EAAKH,EAAIC,EAAWC,CAAS,CAAA,CAElC"}
package/dist/react.js CHANGED
@@ -1,10 +1,11 @@
1
- import { u, _ as o } from "./useModes-BAr0RJcP.js";
2
- import { W as p, k as l, a as f, b as v, c as W, d as c, l as m, e as P, f as w, g as x, i as C, h as b, j as h } from "./useModes-BAr0RJcP.js";
3
- function g(e, s, t) {
1
+ import { u as o } from "./useModes-B3IdrBWZ.js";
2
+ import { W as m, k as c, a as f, b as l, c as v, d as W, l as P, e as w, f as x, g as y, i as C, h as b, j as h } from "./useModes-B3IdrBWZ.js";
3
+ import r from "react-use/lib/useAsyncFn";
4
+ function n(e, s, t) {
4
5
  const {
5
6
  widgetCtx: { api: a }
6
- } = u();
7
- return o(
7
+ } = o();
8
+ return r(
8
9
  async (i) => a.vote({
9
10
  action: i === "up" ? "upvote" : "downvote",
10
11
  messagePublicId: e,
@@ -14,19 +15,19 @@ function g(e, s, t) {
14
15
  );
15
16
  }
16
17
  export {
17
- p as WidgetProvider,
18
- l as WidgetTriggerProvider,
18
+ m as WidgetProvider,
19
+ c as WidgetTriggerProvider,
19
20
  f as useConfig,
20
- v as useContact,
21
- W as useIsAwaitingBotReply,
22
- c as useMessages,
23
- m as useModes,
24
- P as usePreludeData,
25
- w as usePrimitiveState,
26
- x as useSessions,
21
+ l as useContact,
22
+ v as useIsAwaitingBotReply,
23
+ W as useMessages,
24
+ P as useModes,
25
+ w as usePreludeData,
26
+ x as usePrimitiveState,
27
+ y as useSessions,
27
28
  C as useUploadFiles,
28
- g as useVote,
29
- u as useWidget,
29
+ n as useVote,
30
+ o as useWidget,
30
31
  b as useWidgetRouter,
31
32
  h as useWidgetTrigger
32
33
  };
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","sources":["../src/headless/react/hooks/useVote.ts"],"sourcesContent":["import useAsyncFn from 'react-use/lib/useAsyncFn';\nimport { useWidget } from '../WidgetProvider';\n\n/**\n * @param id\n * @param onSuccess\n * @returns\n */\nexport function useVote(id: string, sessionId: string, onSuccess?: () => void) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async (action: 'up' | 'down') => {\n return api\n .vote({\n action: action === 'up' ? 'upvote' : 'downvote',\n messagePublicId: id,\n sessionId,\n })\n .then(onSuccess);\n },\n [api, id, sessionId, onSuccess],\n );\n}\n\n/**\n * @param id\n * @param onSuccess\n * @deprecated use useVote instead\n */\nexport function useUpvote(\n id: string,\n sessionId: string,\n onSuccess?: () => void,\n) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async () =>\n api\n .vote({ action: 'upvote', messagePublicId: id, sessionId })\n .then(onSuccess),\n [api, id, sessionId, onSuccess],\n );\n}\n\n/**\n * @param id\n * @param onSuccess\n * @deprecated use useVote instead\n */\nexport function useDownvote(\n id: string,\n sessionId: string,\n onSuccess?: () => void,\n) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async () =>\n api\n .vote({ action: 'downvote', messagePublicId: id, sessionId })\n .then(onSuccess),\n [api, id, sessionId, onSuccess],\n );\n}\n"],"names":["useVote","id","sessionId","onSuccess","api","useWidget","useAsyncFn","action"],"mappings":";;AAQgB,SAAAA,EAAQC,GAAYC,GAAmBC,GAAwB;AACvE,QAAA;AAAA,IACJ,WAAW,EAAE,KAAAC,EAAI;AAAA,MACfC,EAAU;AACP,SAAAC;AAAAA,IACL,OAAOC,MACEH,EACJ,KAAK;AAAA,MACJ,QAAQG,MAAW,OAAO,WAAW;AAAA,MACrC,iBAAiBN;AAAA,MACjB,WAAAC;AAAA,IAAA,CACD,EACA,KAAKC,CAAS;AAAA,IAEnB,CAACC,GAAKH,GAAIC,GAAWC,CAAS;AAAA,EAAA;AAElC;"}
1
+ {"version":3,"file":"react.js","sources":["../src/headless/react/hooks/useVote.ts"],"sourcesContent":["import useAsyncFn from 'react-use/lib/useAsyncFn';\nimport { useWidget } from '../WidgetProvider';\n\n/**\n * @param id\n * @param onSuccess\n * @returns\n */\nexport function useVote(id: string, sessionId: string, onSuccess?: () => void) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async (action: 'up' | 'down') => {\n return api\n .vote({\n action: action === 'up' ? 'upvote' : 'downvote',\n messagePublicId: id,\n sessionId,\n })\n .then(onSuccess);\n },\n [api, id, sessionId, onSuccess],\n );\n}\n\n/**\n * @param id\n * @param onSuccess\n * @deprecated use useVote instead\n */\nexport function useUpvote(\n id: string,\n sessionId: string,\n onSuccess?: () => void,\n) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async () =>\n api\n .vote({ action: 'upvote', messagePublicId: id, sessionId })\n .then(onSuccess),\n [api, id, sessionId, onSuccess],\n );\n}\n\n/**\n * @param id\n * @param onSuccess\n * @deprecated use useVote instead\n */\nexport function useDownvote(\n id: string,\n sessionId: string,\n onSuccess?: () => void,\n) {\n const {\n widgetCtx: { api },\n } = useWidget();\n return useAsyncFn(\n async () =>\n api\n .vote({ action: 'downvote', messagePublicId: id, sessionId })\n .then(onSuccess),\n [api, id, sessionId, onSuccess],\n );\n}\n"],"names":["useVote","id","sessionId","onSuccess","api","useWidget","useAsyncFn","action"],"mappings":";;;AAQgB,SAAAA,EAAQC,GAAYC,GAAmBC,GAAwB;AACvE,QAAA;AAAA,IACJ,WAAW,EAAE,KAAAC,EAAI;AAAA,MACfC,EAAU;AACP,SAAAC;AAAA,IACL,OAAOC,MACEH,EACJ,KAAK;AAAA,MACJ,QAAQG,MAAW,OAAO,WAAW;AAAA,MACrC,iBAAiBN;AAAA,MACjB,WAAAC;AAAA,IAAA,CACD,EACA,KAAKC,CAAS;AAAA,IAEnB,CAACC,GAAKH,GAAIC,GAAWC,CAAS;AAAA,EAAA;AAElC;"}
@@ -0,0 +1,261 @@
1
+ import k from "swr";
2
+ import { createContext as b, useRef as y, useState as w, useMemo as m, useEffect as h, useContext as U, useSyncExternalStore as P } from "react";
3
+ import { v4 as O } from "uuid";
4
+ import { jsx as F } from "react/jsx-runtime";
5
+ import { W as R } from "./widget.ctx-uAWzif3-.js";
6
+ const N = "3.0.90";
7
+ class T {
8
+ constructor(t) {
9
+ this.components = [];
10
+ const { components: n } = t;
11
+ if (n && n.forEach((o) => this.register(o)), this.components.length === 0)
12
+ throw new Error("No components registered");
13
+ if (!this.get("fallback"))
14
+ throw new Error("No fallback component registered");
15
+ }
16
+ // TODO test that this registers or replaces the component
17
+ register(t) {
18
+ const n = this.components.findIndex((o) => o.key === t.key);
19
+ return n !== -1 ? this.components[n] = t : this.components.push(t), this;
20
+ }
21
+ get(t) {
22
+ const n = this.components.find(
23
+ (o) => o.key.toUpperCase() === t.toUpperCase()
24
+ );
25
+ return n || null;
26
+ }
27
+ getComponent(t) {
28
+ var n;
29
+ return (n = this.get(t)) == null ? void 0 : n.component;
30
+ }
31
+ }
32
+ const W = b(null);
33
+ function D({
34
+ options: e,
35
+ children: t,
36
+ components: n,
37
+ modesComponents: o,
38
+ storage: i,
39
+ loadingComponent: a
40
+ }) {
41
+ const d = y(null), u = y(!1), [p, f] = w(null), s = m(
42
+ () => new T({
43
+ components: n
44
+ }),
45
+ [n]
46
+ );
47
+ return h(() => {
48
+ u.current || (u.current = !0, R.initialize({ config: e, storage: i }).then(f));
49
+ }, []), p ? /* @__PURE__ */ F(
50
+ W.Provider,
51
+ {
52
+ value: {
53
+ widgetCtx: p,
54
+ config: e,
55
+ components: n,
56
+ componentStore: s,
57
+ modesComponents: o,
58
+ version: N,
59
+ contentIframeRef: d
60
+ },
61
+ children: t
62
+ }
63
+ ) : a || null;
64
+ }
65
+ function g() {
66
+ const e = U(W);
67
+ if (!e)
68
+ throw new Error("useWidget must be used within a WidgetProvider");
69
+ return e;
70
+ }
71
+ function v() {
72
+ const { config: e } = g();
73
+ return e;
74
+ }
75
+ function C(e) {
76
+ return P(e.subscribe, e.get, e.get);
77
+ }
78
+ function _() {
79
+ const { widgetCtx: e } = g();
80
+ return {
81
+ contactState: C(e.contactCtx.state),
82
+ createUnverifiedContact: e.contactCtx.createUnverifiedContact
83
+ };
84
+ }
85
+ function M() {
86
+ const { widgetCtx: e } = g();
87
+ return { messagesState: C(e.messageCtx.state), sendMessage: e.messageCtx.sendMessage };
88
+ }
89
+ function E() {
90
+ const { widgetCtx: e } = g(), { oneOpenSessionAllowed: t } = v(), n = C(e.sessionCtx.sessionState), o = C(e.sessionCtx.sessionsState), { openSessions: i, closedSessions: a } = m(() => ({
91
+ openSessions: o.data.filter((u) => u.isOpened === !0),
92
+ closedSessions: o.data.filter((u) => u.isOpened === !1)
93
+ }), [o.data]), d = m(() => t ? i.length === 0 : !0, [t, i.length]);
94
+ return {
95
+ sessionState: n,
96
+ sessionsState: o,
97
+ loadMoreSessions: e.sessionCtx.loadMoreSessions,
98
+ resolveSession: e.sessionCtx.resolveSession,
99
+ createStateCheckpoint: e.sessionCtx.createStateCheckpoint,
100
+ openSessions: i,
101
+ closedSessions: a,
102
+ canCreateNewSession: d
103
+ };
104
+ }
105
+ function $() {
106
+ var d;
107
+ const { sessionState: e } = E(), { messagesState: t } = M(), n = ((d = e.session) == null ? void 0 : d.assignee.kind) === "ai", o = t.messages.length > 0 ? t.messages[t.messages.length - 1] : null, i = (o == null ? void 0 : o.type) === "FROM_USER";
108
+ return { isAwaitingBotReply: (n || e.isCreatingSession) && (t.isSendingMessage || i) };
109
+ }
110
+ function q() {
111
+ const { widgetCtx: e } = g();
112
+ return k([e.config.token], e.api.widgetPrelude, {
113
+ revalidateOnFocus: !1
114
+ });
115
+ }
116
+ function G() {
117
+ const { widgetCtx: e } = g();
118
+ return {
119
+ routerState: C(e.routerCtx.state),
120
+ toSessionsScreen: e.routerCtx.toSessionsScreen,
121
+ toChatScreen: e.routerCtx.toChatScreen
122
+ };
123
+ }
124
+ const l = /* @__PURE__ */ new Map();
125
+ function H() {
126
+ const [e, t] = w([]), {
127
+ widgetCtx: { api: n }
128
+ } = g();
129
+ function o(s) {
130
+ const r = s.map((c) => ({
131
+ file: c,
132
+ id: O(),
133
+ status: "pending",
134
+ progress: 0
135
+ }));
136
+ t((c) => [...c, ...r]), r.forEach(d);
137
+ }
138
+ function i(s, r) {
139
+ t(
140
+ (c) => c.map((S) => S.id === s ? { ...S, ...r } : S)
141
+ );
142
+ }
143
+ function a(s) {
144
+ t((r) => r.filter((c) => c.id !== s));
145
+ }
146
+ const d = async (s) => {
147
+ const r = new AbortController();
148
+ l.set(s.id, r);
149
+ try {
150
+ t(
151
+ (S) => S.map(
152
+ (x) => x.id === s.id ? { ...x, status: "uploading", progress: 0 } : x
153
+ )
154
+ );
155
+ const c = await n.uploadFile({
156
+ file: s.file,
157
+ abortSignal: r.signal,
158
+ onProgress: (S) => {
159
+ i(s.id, { progress: S });
160
+ }
161
+ });
162
+ i(s.id, {
163
+ status: "success",
164
+ fileUrl: c.fileUrl,
165
+ progress: 100
166
+ });
167
+ } catch (c) {
168
+ r.signal.aborted || i(s.id, {
169
+ status: "error",
170
+ error: c instanceof Error ? c.message : "Upload failed",
171
+ progress: 0
172
+ });
173
+ } finally {
174
+ l.delete(s.id);
175
+ }
176
+ }, u = (s) => {
177
+ const r = l.get(s);
178
+ r && (r.abort(), l.delete(s)), a(s);
179
+ }, p = m(() => e.filter((s) => s.status === "success" && s.fileUrl), [e]);
180
+ function f() {
181
+ l.forEach((s) => s.abort()), l.clear(), t([]);
182
+ }
183
+ return h(() => () => {
184
+ l.forEach((s) => s.abort()), l.clear();
185
+ }, []), {
186
+ allFiles: e,
187
+ appendFiles: o,
188
+ handleCancelUpload: u,
189
+ successFiles: p,
190
+ emptyTheFiles: f,
191
+ getFileById: (s) => e.find((r) => r.id === s),
192
+ getUploadProgress: (s) => {
193
+ var r;
194
+ return ((r = e.find((c) => c.id === s)) == null ? void 0 : r.progress) ?? 0;
195
+ },
196
+ getUploadStatus: (s) => {
197
+ var r;
198
+ return (r = e.find((c) => c.id === s)) == null ? void 0 : r.status;
199
+ },
200
+ hasErrors: e.some((s) => s.status === "error"),
201
+ isUploading: e.some((s) => s.status === "uploading")
202
+ };
203
+ }
204
+ const A = b(null);
205
+ function J({ children: e }) {
206
+ const t = v(), [n, o] = w(t.isOpen ?? !1);
207
+ return h(() => {
208
+ o((i) => t.isOpen ?? i);
209
+ }, [t.isOpen]), h(() => {
210
+ const i = t.openAfterNSeconds;
211
+ if (typeof i != "number" || isNaN(i))
212
+ return;
213
+ const a = setTimeout(() => o(!0), i * 1e3);
214
+ return () => clearTimeout(a);
215
+ }, [t.openAfterNSeconds]), /* @__PURE__ */ F(A.Provider, { value: { isOpen: n, setIsOpen: o }, children: e });
216
+ }
217
+ function K() {
218
+ const e = U(A);
219
+ if (!e)
220
+ throw new Error(
221
+ "useWidgetTrigger must be used within a WidgetTriggerProvider"
222
+ );
223
+ return e;
224
+ }
225
+ function Q() {
226
+ var u, p;
227
+ const { widgetCtx: e, modesComponents: t } = g(), { sessionState: n } = E(), o = e.modes, i = (u = n.session) == null ? void 0 : u.modeId, a = o.find((f) => f.id === i), d = (p = t == null ? void 0 : t.find(
228
+ (f) => {
229
+ var s, r;
230
+ return [
231
+ (a == null ? void 0 : a.id) || "",
232
+ ((s = a == null ? void 0 : a.name) == null ? void 0 : s.toLowerCase()) || "",
233
+ ((r = a == null ? void 0 : a.slug) == null ? void 0 : r.toLowerCase()) || ""
234
+ ].includes(f.key.toLowerCase());
235
+ }
236
+ )) == null ? void 0 : p.component;
237
+ return {
238
+ modes: o,
239
+ modesComponents: t,
240
+ activeModeId: i,
241
+ activeMode: a,
242
+ Component: d
243
+ };
244
+ }
245
+ export {
246
+ D as W,
247
+ v as a,
248
+ _ as b,
249
+ $ as c,
250
+ M as d,
251
+ q as e,
252
+ C as f,
253
+ E as g,
254
+ G as h,
255
+ H as i,
256
+ K as j,
257
+ J as k,
258
+ Q as l,
259
+ g as u
260
+ };
261
+ //# sourceMappingURL=useModes-B3IdrBWZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useModes-B3IdrBWZ.js","sources":["../src/headless/react/ComponentRegistry.ts","../src/headless/react/WidgetProvider.tsx","../src/headless/react/hooks/useConfig.ts","../src/headless/react/hooks/usePrimitiveState.ts","../src/headless/react/hooks/useContact.ts","../src/headless/react/hooks/useMessages.ts","../src/headless/react/hooks/useSessions.ts","../src/headless/react/hooks/useIsAwaitingBotReply.ts","../src/headless/react/hooks/usePreludeData.ts","../src/headless/react/hooks/useWidgetRouter.ts","../src/headless/react/hooks/useUploadFiles.ts","../src/headless/react/hooks/useWidgetTrigger.tsx","../src/headless/react/hooks/useModes.ts"],"sourcesContent":["import type { WidgetComponentKey } from '../core';\nimport type { WidgetComponentType } from './types/components';\n\nexport class ComponentRegistry {\n components: WidgetComponentType[] = [];\n\n constructor(opts: { components?: WidgetComponentType[] }) {\n const { components } = opts;\n\n if (components) {\n components.forEach((c) => this.register(c));\n }\n\n if (this.components.length === 0) {\n throw new Error('No components registered');\n }\n if (!this.get('fallback')) {\n throw new Error('No fallback component registered');\n }\n }\n\n // TODO test that this registers or replaces the component\n register(component: WidgetComponentType) {\n // Replace the key if it already exists\n const index = this.components.findIndex((c) => c.key === component.key);\n if (index !== -1) {\n this.components[index] = component;\n } else {\n this.components.push(component);\n }\n return this;\n }\n\n private get(key: WidgetComponentKey) {\n const c = this.components.find(\n (c) => c.key.toUpperCase() === key.toUpperCase(),\n );\n if (c) return c;\n return null;\n }\n\n public getComponent(key: string) {\n return this.get(key)?.component;\n }\n}\n","import React, {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { version } from '../../../package.json';\nimport { type ExternalStorage, type WidgetConfig, WidgetCtx } from '../core';\nimport { ComponentRegistry } from './ComponentRegistry';\nimport type { WidgetComponentType } from './types/components';\nimport type { WidgetModeComponentType } from './types/modes.components';\n\ninterface WidgetProviderValue {\n widgetCtx: WidgetCtx;\n config: WidgetConfig;\n components?: WidgetComponentType[];\n modesComponents?: WidgetModeComponentType[];\n componentStore: ComponentRegistry;\n version: string;\n contentIframeRef?: React.MutableRefObject<HTMLIFrameElement | null>;\n}\n\nconst context = createContext<WidgetProviderValue | null>(null);\n\nexport function WidgetProvider({\n options: config,\n children,\n components,\n modesComponents,\n storage,\n loadingComponent,\n}: {\n options: WidgetConfig;\n children: React.ReactNode;\n components?: WidgetComponentType[];\n modesComponents?: WidgetModeComponentType[];\n storage?: ExternalStorage;\n /**\n * Custom loading component while the widget is initializing\n * Not to be confused with the `loading` custom component which renders when the bot's reply is pending\n */\n loadingComponent?: React.ReactNode;\n}) {\n const contentIframeRef = useRef<HTMLIFrameElement | null>(null);\n\n const didInitialize = useRef(false);\n const [widgetCtx, setWidgetCtx] = useState<WidgetCtx | null>(null);\n\n const componentStore = useMemo(\n () =>\n new ComponentRegistry({\n components: components,\n }),\n [components],\n );\n\n useEffect(() => {\n if (didInitialize.current) return;\n didInitialize.current = true;\n\n WidgetCtx.initialize({ config, storage }).then(setWidgetCtx);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n if (!widgetCtx) {\n return loadingComponent || null;\n }\n\n return (\n <context.Provider\n value={{\n widgetCtx,\n config,\n components,\n componentStore,\n modesComponents,\n version,\n contentIframeRef,\n }}\n >\n {children}\n </context.Provider>\n );\n}\n\nexport function useWidget() {\n const ctx = useContext(context);\n if (!ctx) {\n throw new Error('useWidget must be used within a WidgetProvider');\n }\n return ctx;\n}\n","import { useWidget } from '../WidgetProvider';\n\nexport function useConfig() {\n const { config } = useWidget();\n\n return config;\n}\n","import { useSyncExternalStore } from 'react';\nimport type { PrimitiveState } from '../../core';\n\nexport function usePrimitiveState<T>(p: PrimitiveState<T>) {\n return useSyncExternalStore(p.subscribe, p.get, p.get);\n}\n","import { useWidget } from '../WidgetProvider';\nimport { usePrimitiveState } from './usePrimitiveState';\n\nexport function useContact() {\n const { widgetCtx } = useWidget();\n const contactState = usePrimitiveState(widgetCtx.contactCtx.state);\n\n return {\n contactState,\n createUnverifiedContact: widgetCtx.contactCtx.createUnverifiedContact,\n };\n}\n","import { usePrimitiveState } from './usePrimitiveState';\nimport { useWidget } from '../WidgetProvider';\n\nexport function useMessages() {\n const { widgetCtx } = useWidget();\n const messagesState = usePrimitiveState(widgetCtx.messageCtx.state);\n\n return { messagesState, sendMessage: widgetCtx.messageCtx.sendMessage };\n}\n","import { useMemo } from 'react';\nimport { useWidget } from '../WidgetProvider';\nimport { usePrimitiveState } from './usePrimitiveState';\nimport { useConfig } from './useConfig';\n\nexport function useSessions() {\n const { widgetCtx } = useWidget();\n const { oneOpenSessionAllowed } = useConfig();\n const sessionState = usePrimitiveState(widgetCtx.sessionCtx.sessionState);\n const sessionsState = usePrimitiveState(widgetCtx.sessionCtx.sessionsState);\n\n const { openSessions, closedSessions } = useMemo(() => {\n return {\n openSessions: sessionsState.data.filter((s) => s.isOpened === true),\n closedSessions: sessionsState.data.filter((s) => s.isOpened === false),\n };\n }, [sessionsState.data]);\n\n const canCreateNewSession = useMemo(() => {\n if (oneOpenSessionAllowed) {\n return openSessions.length === 0;\n }\n return true;\n }, [oneOpenSessionAllowed, openSessions.length]);\n\n return {\n sessionState,\n sessionsState,\n loadMoreSessions: widgetCtx.sessionCtx.loadMoreSessions,\n resolveSession: widgetCtx.sessionCtx.resolveSession,\n createStateCheckpoint: widgetCtx.sessionCtx.createStateCheckpoint,\n openSessions,\n closedSessions,\n canCreateNewSession,\n };\n}\n","import { useMessages } from './useMessages';\nimport { useSessions } from './useSessions';\n\nexport function useIsAwaitingBotReply() {\n const { sessionState } = useSessions();\n const { messagesState } = useMessages();\n\n const isSessionAssignedToAI = sessionState.session?.assignee.kind === 'ai';\n // This check is useful in cases where the user might navigate in and out of a chat, and `isSendingMessage` is reset back to its default value\n const lastMessage =\n messagesState.messages.length > 0\n ? messagesState.messages[messagesState.messages.length - 1]\n : null;\n const isLastMessageAUserMessage = lastMessage?.type === 'FROM_USER';\n\n const isAwaitingBotReply =\n (isSessionAssignedToAI || sessionState.isCreatingSession) &&\n (messagesState.isSendingMessage || isLastMessageAUserMessage);\n\n return { isAwaitingBotReply };\n}\n","import useSWR from 'swr';\nimport { useWidget } from '../WidgetProvider';\n\nfunction usePreludeData() {\n const { widgetCtx } = useWidget();\n\n // TODO remove swr dependency\n return useSWR([widgetCtx.config.token], widgetCtx.api.widgetPrelude, {\n revalidateOnFocus: false,\n });\n}\n\nexport { usePreludeData };\n","import { useWidget } from '../WidgetProvider';\nimport { usePrimitiveState } from './usePrimitiveState';\n\nexport function useWidgetRouter() {\n const { widgetCtx } = useWidget();\n\n const routerState = usePrimitiveState(widgetCtx.routerCtx.state);\n\n return {\n routerState,\n toSessionsScreen: widgetCtx.routerCtx.toSessionsScreen,\n toChatScreen: widgetCtx.routerCtx.toChatScreen,\n };\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { useWidget } from '../WidgetProvider';\nimport { v4 } from 'uuid';\n\nconst uploadAbortControllers: Map<string, AbortController> = new Map();\n\ninterface FileWithProgress {\n status: 'pending' | 'uploading' | 'success' | 'error';\n id: string;\n file: File;\n fileUrl?: string;\n progress: number;\n error?: string;\n}\n\nfunction useUploadFiles() {\n const [files, setFiles] = useState<FileWithProgress[]>([]);\n const {\n widgetCtx: { api },\n } = useWidget();\n function appendFiles(files: File[]) {\n const newFiles = files.map((file) => ({\n file,\n id: v4(),\n status: 'pending' as const,\n progress: 0,\n }));\n\n setFiles((prev) => [...prev, ...newFiles]);\n newFiles.forEach(uploadFile);\n }\n\n function updateFileById(id: string, update: Partial<FileWithProgress>) {\n setFiles((prev) =>\n prev.map((f) => (f.id === id ? { ...f, ...update } : f)),\n );\n }\n\n function removeFileById(id: string) {\n setFiles((prev) => prev.filter((f) => f.id !== id));\n }\n\n const uploadFile = async (fileItem: FileWithProgress) => {\n const controller = new AbortController();\n uploadAbortControllers.set(fileItem.id, controller);\n\n try {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === fileItem.id ? { ...f, status: 'uploading', progress: 0 } : f,\n ),\n );\n\n const response = await api.uploadFile({\n file: fileItem.file,\n abortSignal: controller.signal,\n onProgress: (percentage) => {\n updateFileById(fileItem.id, { progress: percentage });\n },\n });\n\n updateFileById(fileItem.id, {\n status: 'success',\n fileUrl: response.fileUrl,\n progress: 100,\n });\n } catch (error) {\n if (!controller.signal.aborted) {\n updateFileById(fileItem.id, {\n status: 'error',\n error: error instanceof Error ? error.message : 'Upload failed',\n progress: 0,\n });\n }\n } finally {\n uploadAbortControllers.delete(fileItem.id);\n }\n };\n\n const handleCancelUpload = (fileId: string) => {\n const controller = uploadAbortControllers.get(fileId);\n if (controller) {\n controller.abort();\n uploadAbortControllers.delete(fileId);\n }\n removeFileById(fileId);\n };\n\n const successFiles = useMemo(() => {\n return files.filter((f) => f.status === 'success' && f.fileUrl);\n }, [files]);\n\n function emptyTheFiles() {\n uploadAbortControllers.forEach((controller) => controller.abort());\n uploadAbortControllers.clear();\n setFiles([]);\n }\n\n useEffect(() => {\n return () => {\n uploadAbortControllers.forEach((controller) => controller.abort());\n uploadAbortControllers.clear();\n };\n }, []);\n\n return {\n allFiles: files,\n appendFiles,\n handleCancelUpload,\n successFiles,\n emptyTheFiles,\n getFileById: (id: string) => files.find((f) => f.id === id),\n getUploadProgress: (id: string) =>\n files.find((f) => f.id === id)?.progress ?? 0,\n getUploadStatus: (id: string) => files.find((f) => f.id === id)?.status,\n hasErrors: files.some((f) => f.status === 'error'),\n isUploading: files.some((f) => f.status === 'uploading'),\n };\n}\n\nexport { useUploadFiles, type FileWithProgress };\n","import React, {\n createContext,\n useContext,\n useEffect,\n useState,\n type Dispatch,\n type ReactNode,\n type SetStateAction,\n} from 'react';\nimport { useConfig } from './useConfig';\n\ntype WidgetTriggerCtx = {\n isOpen: boolean;\n setIsOpen: Dispatch<SetStateAction<boolean>>;\n};\n\nconst context = createContext<WidgetTriggerCtx | null>(null);\n\nexport function WidgetTriggerProvider({ children }: { children: ReactNode }) {\n const config = useConfig();\n const [isOpen, setIsOpen] = useState(config.isOpen ?? false);\n\n useEffect(() => {\n setIsOpen((prev) => config.isOpen ?? prev);\n }, [config.isOpen]);\n\n useEffect(() => {\n const openAfterNSeconds = config.openAfterNSeconds;\n if (typeof openAfterNSeconds !== 'number' || isNaN(openAfterNSeconds))\n return;\n\n const timeout = setTimeout(() => setIsOpen(true), openAfterNSeconds * 1000);\n\n return () => clearTimeout(timeout);\n }, [config.openAfterNSeconds]);\n\n return (\n <context.Provider value={{ isOpen, setIsOpen }}>\n {children}\n </context.Provider>\n );\n}\n\nexport function useWidgetTrigger() {\n const ctx = useContext(context);\n if (!ctx) {\n throw new Error(\n 'useWidgetTrigger must be used within a WidgetTriggerProvider',\n );\n }\n return ctx;\n}\n","import { useWidget } from '../WidgetProvider';\nimport { useSessions } from './useSessions';\n\nexport function useModes() {\n const { widgetCtx, modesComponents } = useWidget();\n const { sessionState } = useSessions();\n\n const modes = widgetCtx.modes;\n const activeModeId = sessionState.session?.modeId;\n const activeMode = modes.find((mode) => mode.id === activeModeId);\n\n const Component = modesComponents?.find((modeComponent) =>\n [\n activeMode?.id || '',\n activeMode?.name?.toLowerCase() || '',\n activeMode?.slug?.toLowerCase() || '',\n ].includes(modeComponent.key.toLowerCase()),\n )?.component;\n\n return {\n modes,\n modesComponents,\n activeModeId,\n activeMode,\n Component,\n };\n}\n"],"names":["ComponentRegistry","opts","components","c","component","index","key","_a","context","createContext","WidgetProvider","config","children","modesComponents","storage","loadingComponent","contentIframeRef","useRef","didInitialize","widgetCtx","setWidgetCtx","useState","componentStore","useMemo","useEffect","WidgetCtx","jsx","version","useWidget","ctx","useContext","useConfig","usePrimitiveState","p","useSyncExternalStore","useContact","useMessages","useSessions","oneOpenSessionAllowed","sessionState","sessionsState","openSessions","closedSessions","s","canCreateNewSession","useIsAwaitingBotReply","messagesState","isSessionAssignedToAI","lastMessage","isLastMessageAUserMessage","usePreludeData","useSWR","useWidgetRouter","uploadAbortControllers","useUploadFiles","files","setFiles","api","appendFiles","newFiles","file","v4","prev","uploadFile","updateFileById","id","update","f","removeFileById","fileItem","controller","response","percentage","error","handleCancelUpload","fileId","successFiles","emptyTheFiles","WidgetTriggerProvider","isOpen","setIsOpen","openAfterNSeconds","timeout","useWidgetTrigger","useModes","modes","activeModeId","activeMode","mode","Component","_b","modeComponent"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";const U=require("swr"),u=require("react"),F=require("uuid"),y=require("react/jsx-runtime"),P=require("./widget.ctx-6xcbtF7q.cjs"),R="3.0.90";class b{constructor(t){this.components=[];const{components:n}=t;if(n&&n.forEach(o=>this.register(o)),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(o=>o.key===t.key);return n!==-1?this.components[n]=t:this.components.push(t),this}get(t){const n=this.components.find(o=>o.key.toUpperCase()===t.toUpperCase());return n||null}getComponent(t){var n;return(n=this.get(t))==null?void 0:n.component}}const W=u.createContext(null);function A({options:e,children:t,components:n,modesComponents:o,storage:i,loadingComponent:c}){const l=u.useRef(null),d=u.useRef(!1),[p,S]=u.useState(null),s=u.useMemo(()=>new b({components:n}),[n]);return u.useEffect(()=>{d.current||(d.current=!0,P.WidgetCtx.initialize({config:e,storage:i}).then(S))},[]),p?y.jsx(W.Provider,{value:{widgetCtx:p,config:e,components:n,componentStore:s,modesComponents:o,version:R,contentIframeRef:l},children:t}):c||null}function g(){const e=u.useContext(W);if(!e)throw new Error("useWidget must be used within a WidgetProvider");return e}function h(){const{config:e}=g();return e}function m(e){return u.useSyncExternalStore(e.subscribe,e.get,e.get)}function M(){const{widgetCtx:e}=g();return{contactState:m(e.contactCtx.state),createUnverifiedContact:e.contactCtx.createUnverifiedContact}}function v(){const{widgetCtx:e}=g();return{messagesState:m(e.messageCtx.state),sendMessage:e.messageCtx.sendMessage}}function w(){const{widgetCtx:e}=g(),{oneOpenSessionAllowed:t}=h(),n=m(e.sessionCtx.sessionState),o=m(e.sessionCtx.sessionsState),{openSessions:i,closedSessions:c}=u.useMemo(()=>({openSessions:o.data.filter(d=>d.isOpened===!0),closedSessions:o.data.filter(d=>d.isOpened===!1)}),[o.data]),l=u.useMemo(()=>t?i.length===0:!0,[t,i.length]);return{sessionState:n,sessionsState:o,loadMoreSessions:e.sessionCtx.loadMoreSessions,resolveSession:e.sessionCtx.resolveSession,createStateCheckpoint:e.sessionCtx.createStateCheckpoint,openSessions:i,closedSessions:c,canCreateNewSession:l}}function k(){var l;const{sessionState:e}=w(),{messagesState:t}=v(),n=((l=e.session)==null?void 0:l.assignee.kind)==="ai",o=t.messages.length>0?t.messages[t.messages.length-1]:null,i=(o==null?void 0:o.type)==="FROM_USER";return{isAwaitingBotReply:(n||e.isCreatingSession)&&(t.isSendingMessage||i)}}function O(){const{widgetCtx:e}=g();return U([e.config.token],e.api.widgetPrelude,{revalidateOnFocus:!1})}function T(){const{widgetCtx:e}=g();return{routerState:m(e.routerCtx.state),toSessionsScreen:e.routerCtx.toSessionsScreen,toChatScreen:e.routerCtx.toChatScreen}}const f=new Map;function N(){const[e,t]=u.useState([]),{widgetCtx:{api:n}}=g();function o(s){const r=s.map(a=>({file:a,id:F.v4(),status:"pending",progress:0}));t(a=>[...a,...r]),r.forEach(l)}function i(s,r){t(a=>a.map(C=>C.id===s?{...C,...r}:C))}function c(s){t(r=>r.filter(a=>a.id!==s))}const l=async s=>{const r=new AbortController;f.set(s.id,r);try{t(C=>C.map(x=>x.id===s.id?{...x,status:"uploading",progress:0}:x));const a=await n.uploadFile({file:s.file,abortSignal:r.signal,onProgress:C=>{i(s.id,{progress:C})}});i(s.id,{status:"success",fileUrl:a.fileUrl,progress:100})}catch(a){r.signal.aborted||i(s.id,{status:"error",error:a instanceof Error?a.message:"Upload failed",progress:0})}finally{f.delete(s.id)}},d=s=>{const r=f.get(s);r&&(r.abort(),f.delete(s)),c(s)},p=u.useMemo(()=>e.filter(s=>s.status==="success"&&s.fileUrl),[e]);function S(){f.forEach(s=>s.abort()),f.clear(),t([])}return u.useEffect(()=>()=>{f.forEach(s=>s.abort()),f.clear()},[]),{allFiles:e,appendFiles:o,handleCancelUpload:d,successFiles:p,emptyTheFiles:S,getFileById:s=>e.find(r=>r.id===s),getUploadProgress:s=>{var r;return((r=e.find(a=>a.id===s))==null?void 0:r.progress)??0},getUploadStatus:s=>{var r;return(r=e.find(a=>a.id===s))==null?void 0:r.status},hasErrors:e.some(s=>s.status==="error"),isUploading:e.some(s=>s.status==="uploading")}}const E=u.createContext(null);function B({children:e}){const t=h(),[n,o]=u.useState(t.isOpen??!1);return u.useEffect(()=>{o(i=>t.isOpen??i)},[t.isOpen]),u.useEffect(()=>{const i=t.openAfterNSeconds;if(typeof i!="number"||isNaN(i))return;const c=setTimeout(()=>o(!0),i*1e3);return()=>clearTimeout(c)},[t.openAfterNSeconds]),y.jsx(E.Provider,{value:{isOpen:n,setIsOpen:o},children:e})}function q(){const e=u.useContext(E);if(!e)throw new Error("useWidgetTrigger must be used within a WidgetTriggerProvider");return e}function I(){var d,p;const{widgetCtx:e,modesComponents:t}=g(),{sessionState:n}=w(),o=e.modes,i=(d=n.session)==null?void 0:d.modeId,c=o.find(S=>S.id===i),l=(p=t==null?void 0:t.find(S=>{var s,r;return[(c==null?void 0:c.id)||"",((s=c==null?void 0:c.name)==null?void 0:s.toLowerCase())||"",((r=c==null?void 0:c.slug)==null?void 0:r.toLowerCase())||""].includes(S.key.toLowerCase())}))==null?void 0:p.component;return{modes:o,modesComponents:t,activeModeId:i,activeMode:c,Component:l}}exports.WidgetProvider=A;exports.WidgetTriggerProvider=B;exports.useConfig=h;exports.useContact=M;exports.useIsAwaitingBotReply=k;exports.useMessages=v;exports.useModes=I;exports.usePreludeData=O;exports.usePrimitiveState=m;exports.useSessions=w;exports.useUploadFiles=N;exports.useWidget=g;exports.useWidgetRouter=T;exports.useWidgetTrigger=q;
2
+ //# sourceMappingURL=useModes-ZmjqOTMd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useModes-ZmjqOTMd.cjs","sources":["../src/headless/react/ComponentRegistry.ts","../src/headless/react/WidgetProvider.tsx","../src/headless/react/hooks/useConfig.ts","../src/headless/react/hooks/usePrimitiveState.ts","../src/headless/react/hooks/useContact.ts","../src/headless/react/hooks/useMessages.ts","../src/headless/react/hooks/useSessions.ts","../src/headless/react/hooks/useIsAwaitingBotReply.ts","../src/headless/react/hooks/usePreludeData.ts","../src/headless/react/hooks/useWidgetRouter.ts","../src/headless/react/hooks/useUploadFiles.ts","../src/headless/react/hooks/useWidgetTrigger.tsx","../src/headless/react/hooks/useModes.ts"],"sourcesContent":["import type { WidgetComponentKey } from '../core';\nimport type { WidgetComponentType } from './types/components';\n\nexport class ComponentRegistry {\n components: WidgetComponentType[] = [];\n\n constructor(opts: { components?: WidgetComponentType[] }) {\n const { components } = opts;\n\n if (components) {\n components.forEach((c) => this.register(c));\n }\n\n if (this.components.length === 0) {\n throw new Error('No components registered');\n }\n if (!this.get('fallback')) {\n throw new Error('No fallback component registered');\n }\n }\n\n // TODO test that this registers or replaces the component\n register(component: WidgetComponentType) {\n // Replace the key if it already exists\n const index = this.components.findIndex((c) => c.key === component.key);\n if (index !== -1) {\n this.components[index] = component;\n } else {\n this.components.push(component);\n }\n return this;\n }\n\n private get(key: WidgetComponentKey) {\n const c = this.components.find(\n (c) => c.key.toUpperCase() === key.toUpperCase(),\n );\n if (c) return c;\n return null;\n }\n\n public getComponent(key: string) {\n return this.get(key)?.component;\n }\n}\n","import React, {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { version } from '../../../package.json';\nimport { type ExternalStorage, type WidgetConfig, WidgetCtx } from '../core';\nimport { ComponentRegistry } from './ComponentRegistry';\nimport type { WidgetComponentType } from './types/components';\nimport type { WidgetModeComponentType } from './types/modes.components';\n\ninterface WidgetProviderValue {\n widgetCtx: WidgetCtx;\n config: WidgetConfig;\n components?: WidgetComponentType[];\n modesComponents?: WidgetModeComponentType[];\n componentStore: ComponentRegistry;\n version: string;\n contentIframeRef?: React.MutableRefObject<HTMLIFrameElement | null>;\n}\n\nconst context = createContext<WidgetProviderValue | null>(null);\n\nexport function WidgetProvider({\n options: config,\n children,\n components,\n modesComponents,\n storage,\n loadingComponent,\n}: {\n options: WidgetConfig;\n children: React.ReactNode;\n components?: WidgetComponentType[];\n modesComponents?: WidgetModeComponentType[];\n storage?: ExternalStorage;\n /**\n * Custom loading component while the widget is initializing\n * Not to be confused with the `loading` custom component which renders when the bot's reply is pending\n */\n loadingComponent?: React.ReactNode;\n}) {\n const contentIframeRef = useRef<HTMLIFrameElement | null>(null);\n\n const didInitialize = useRef(false);\n const [widgetCtx, setWidgetCtx] = useState<WidgetCtx | null>(null);\n\n const componentStore = useMemo(\n () =>\n new ComponentRegistry({\n components: components,\n }),\n [components],\n );\n\n useEffect(() => {\n if (didInitialize.current) return;\n didInitialize.current = true;\n\n WidgetCtx.initialize({ config, storage }).then(setWidgetCtx);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n if (!widgetCtx) {\n return loadingComponent || null;\n }\n\n return (\n <context.Provider\n value={{\n widgetCtx,\n config,\n components,\n componentStore,\n modesComponents,\n version,\n contentIframeRef,\n }}\n >\n {children}\n </context.Provider>\n );\n}\n\nexport function useWidget() {\n const ctx = useContext(context);\n if (!ctx) {\n throw new Error('useWidget must be used within a WidgetProvider');\n }\n return ctx;\n}\n","import { useWidget } from '../WidgetProvider';\n\nexport function useConfig() {\n const { config } = useWidget();\n\n return config;\n}\n","import { useSyncExternalStore } from 'react';\nimport type { PrimitiveState } from '../../core';\n\nexport function usePrimitiveState<T>(p: PrimitiveState<T>) {\n return useSyncExternalStore(p.subscribe, p.get, p.get);\n}\n","import { useWidget } from '../WidgetProvider';\nimport { usePrimitiveState } from './usePrimitiveState';\n\nexport function useContact() {\n const { widgetCtx } = useWidget();\n const contactState = usePrimitiveState(widgetCtx.contactCtx.state);\n\n return {\n contactState,\n createUnverifiedContact: widgetCtx.contactCtx.createUnverifiedContact,\n };\n}\n","import { usePrimitiveState } from './usePrimitiveState';\nimport { useWidget } from '../WidgetProvider';\n\nexport function useMessages() {\n const { widgetCtx } = useWidget();\n const messagesState = usePrimitiveState(widgetCtx.messageCtx.state);\n\n return { messagesState, sendMessage: widgetCtx.messageCtx.sendMessage };\n}\n","import { useMemo } from 'react';\nimport { useWidget } from '../WidgetProvider';\nimport { usePrimitiveState } from './usePrimitiveState';\nimport { useConfig } from './useConfig';\n\nexport function useSessions() {\n const { widgetCtx } = useWidget();\n const { oneOpenSessionAllowed } = useConfig();\n const sessionState = usePrimitiveState(widgetCtx.sessionCtx.sessionState);\n const sessionsState = usePrimitiveState(widgetCtx.sessionCtx.sessionsState);\n\n const { openSessions, closedSessions } = useMemo(() => {\n return {\n openSessions: sessionsState.data.filter((s) => s.isOpened === true),\n closedSessions: sessionsState.data.filter((s) => s.isOpened === false),\n };\n }, [sessionsState.data]);\n\n const canCreateNewSession = useMemo(() => {\n if (oneOpenSessionAllowed) {\n return openSessions.length === 0;\n }\n return true;\n }, [oneOpenSessionAllowed, openSessions.length]);\n\n return {\n sessionState,\n sessionsState,\n loadMoreSessions: widgetCtx.sessionCtx.loadMoreSessions,\n resolveSession: widgetCtx.sessionCtx.resolveSession,\n createStateCheckpoint: widgetCtx.sessionCtx.createStateCheckpoint,\n openSessions,\n closedSessions,\n canCreateNewSession,\n };\n}\n","import { useMessages } from './useMessages';\nimport { useSessions } from './useSessions';\n\nexport function useIsAwaitingBotReply() {\n const { sessionState } = useSessions();\n const { messagesState } = useMessages();\n\n const isSessionAssignedToAI = sessionState.session?.assignee.kind === 'ai';\n // This check is useful in cases where the user might navigate in and out of a chat, and `isSendingMessage` is reset back to its default value\n const lastMessage =\n messagesState.messages.length > 0\n ? messagesState.messages[messagesState.messages.length - 1]\n : null;\n const isLastMessageAUserMessage = lastMessage?.type === 'FROM_USER';\n\n const isAwaitingBotReply =\n (isSessionAssignedToAI || sessionState.isCreatingSession) &&\n (messagesState.isSendingMessage || isLastMessageAUserMessage);\n\n return { isAwaitingBotReply };\n}\n","import useSWR from 'swr';\nimport { useWidget } from '../WidgetProvider';\n\nfunction usePreludeData() {\n const { widgetCtx } = useWidget();\n\n // TODO remove swr dependency\n return useSWR([widgetCtx.config.token], widgetCtx.api.widgetPrelude, {\n revalidateOnFocus: false,\n });\n}\n\nexport { usePreludeData };\n","import { useWidget } from '../WidgetProvider';\nimport { usePrimitiveState } from './usePrimitiveState';\n\nexport function useWidgetRouter() {\n const { widgetCtx } = useWidget();\n\n const routerState = usePrimitiveState(widgetCtx.routerCtx.state);\n\n return {\n routerState,\n toSessionsScreen: widgetCtx.routerCtx.toSessionsScreen,\n toChatScreen: widgetCtx.routerCtx.toChatScreen,\n };\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { useWidget } from '../WidgetProvider';\nimport { v4 } from 'uuid';\n\nconst uploadAbortControllers: Map<string, AbortController> = new Map();\n\ninterface FileWithProgress {\n status: 'pending' | 'uploading' | 'success' | 'error';\n id: string;\n file: File;\n fileUrl?: string;\n progress: number;\n error?: string;\n}\n\nfunction useUploadFiles() {\n const [files, setFiles] = useState<FileWithProgress[]>([]);\n const {\n widgetCtx: { api },\n } = useWidget();\n function appendFiles(files: File[]) {\n const newFiles = files.map((file) => ({\n file,\n id: v4(),\n status: 'pending' as const,\n progress: 0,\n }));\n\n setFiles((prev) => [...prev, ...newFiles]);\n newFiles.forEach(uploadFile);\n }\n\n function updateFileById(id: string, update: Partial<FileWithProgress>) {\n setFiles((prev) =>\n prev.map((f) => (f.id === id ? { ...f, ...update } : f)),\n );\n }\n\n function removeFileById(id: string) {\n setFiles((prev) => prev.filter((f) => f.id !== id));\n }\n\n const uploadFile = async (fileItem: FileWithProgress) => {\n const controller = new AbortController();\n uploadAbortControllers.set(fileItem.id, controller);\n\n try {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === fileItem.id ? { ...f, status: 'uploading', progress: 0 } : f,\n ),\n );\n\n const response = await api.uploadFile({\n file: fileItem.file,\n abortSignal: controller.signal,\n onProgress: (percentage) => {\n updateFileById(fileItem.id, { progress: percentage });\n },\n });\n\n updateFileById(fileItem.id, {\n status: 'success',\n fileUrl: response.fileUrl,\n progress: 100,\n });\n } catch (error) {\n if (!controller.signal.aborted) {\n updateFileById(fileItem.id, {\n status: 'error',\n error: error instanceof Error ? error.message : 'Upload failed',\n progress: 0,\n });\n }\n } finally {\n uploadAbortControllers.delete(fileItem.id);\n }\n };\n\n const handleCancelUpload = (fileId: string) => {\n const controller = uploadAbortControllers.get(fileId);\n if (controller) {\n controller.abort();\n uploadAbortControllers.delete(fileId);\n }\n removeFileById(fileId);\n };\n\n const successFiles = useMemo(() => {\n return files.filter((f) => f.status === 'success' && f.fileUrl);\n }, [files]);\n\n function emptyTheFiles() {\n uploadAbortControllers.forEach((controller) => controller.abort());\n uploadAbortControllers.clear();\n setFiles([]);\n }\n\n useEffect(() => {\n return () => {\n uploadAbortControllers.forEach((controller) => controller.abort());\n uploadAbortControllers.clear();\n };\n }, []);\n\n return {\n allFiles: files,\n appendFiles,\n handleCancelUpload,\n successFiles,\n emptyTheFiles,\n getFileById: (id: string) => files.find((f) => f.id === id),\n getUploadProgress: (id: string) =>\n files.find((f) => f.id === id)?.progress ?? 0,\n getUploadStatus: (id: string) => files.find((f) => f.id === id)?.status,\n hasErrors: files.some((f) => f.status === 'error'),\n isUploading: files.some((f) => f.status === 'uploading'),\n };\n}\n\nexport { useUploadFiles, type FileWithProgress };\n","import React, {\n createContext,\n useContext,\n useEffect,\n useState,\n type Dispatch,\n type ReactNode,\n type SetStateAction,\n} from 'react';\nimport { useConfig } from './useConfig';\n\ntype WidgetTriggerCtx = {\n isOpen: boolean;\n setIsOpen: Dispatch<SetStateAction<boolean>>;\n};\n\nconst context = createContext<WidgetTriggerCtx | null>(null);\n\nexport function WidgetTriggerProvider({ children }: { children: ReactNode }) {\n const config = useConfig();\n const [isOpen, setIsOpen] = useState(config.isOpen ?? false);\n\n useEffect(() => {\n setIsOpen((prev) => config.isOpen ?? prev);\n }, [config.isOpen]);\n\n useEffect(() => {\n const openAfterNSeconds = config.openAfterNSeconds;\n if (typeof openAfterNSeconds !== 'number' || isNaN(openAfterNSeconds))\n return;\n\n const timeout = setTimeout(() => setIsOpen(true), openAfterNSeconds * 1000);\n\n return () => clearTimeout(timeout);\n }, [config.openAfterNSeconds]);\n\n return (\n <context.Provider value={{ isOpen, setIsOpen }}>\n {children}\n </context.Provider>\n );\n}\n\nexport function useWidgetTrigger() {\n const ctx = useContext(context);\n if (!ctx) {\n throw new Error(\n 'useWidgetTrigger must be used within a WidgetTriggerProvider',\n );\n }\n return ctx;\n}\n","import { useWidget } from '../WidgetProvider';\nimport { useSessions } from './useSessions';\n\nexport function useModes() {\n const { widgetCtx, modesComponents } = useWidget();\n const { sessionState } = useSessions();\n\n const modes = widgetCtx.modes;\n const activeModeId = sessionState.session?.modeId;\n const activeMode = modes.find((mode) => mode.id === activeModeId);\n\n const Component = modesComponents?.find((modeComponent) =>\n [\n activeMode?.id || '',\n activeMode?.name?.toLowerCase() || '',\n activeMode?.slug?.toLowerCase() || '',\n ].includes(modeComponent.key.toLowerCase()),\n )?.component;\n\n return {\n modes,\n modesComponents,\n activeModeId,\n activeMode,\n Component,\n };\n}\n"],"names":["ComponentRegistry","opts","components","c","component","index","key","_a","context","createContext","WidgetProvider","config","children","modesComponents","storage","loadingComponent","contentIframeRef","useRef","didInitialize","widgetCtx","setWidgetCtx","useState","componentStore","useMemo","useEffect","WidgetCtx","jsx","version","useWidget","ctx","useContext","useConfig","usePrimitiveState","p","useSyncExternalStore","useContact","useMessages","useSessions","oneOpenSessionAllowed","sessionState","sessionsState","openSessions","closedSessions","s","canCreateNewSession","useIsAwaitingBotReply","messagesState","isSessionAssignedToAI","lastMessage","isLastMessageAUserMessage","usePreludeData","useSWR","useWidgetRouter","uploadAbortControllers","useUploadFiles","files","setFiles","api","appendFiles","newFiles","file","v4","prev","uploadFile","updateFileById","id","update","f","removeFileById","fileItem","controller","response","percentage","error","handleCancelUpload","fileId","successFiles","emptyTheFiles","WidgetTriggerProvider","isOpen","setIsOpen","openAfterNSeconds","timeout","useWidgetTrigger","useModes","modes","activeModeId","activeMode","mode","Component","_b","modeComponent"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ "use strict";const M=require("openapi-fetch"),O=require("lodash.isequal"),E=require("uuid"),F=g=>{console.log(g.error)},_=g=>{const a=M({baseUrl:g.baseUrl}),o={onRequest:g.onRequest,onResponse:g.onResponse,onError:g.onError||F};return a.use(o),a};class U{constructor({config:a}){var n,e;this.userToken=null,this.constructClientOptions=t=>{const s=this.config.apiUrl||"https://api.open.cx",i={"X-Bot-Token":this.config.token,"Content-Type":"application/json",Accept:"application/json",Authorization:t?`Bearer ${t}`:void 0};return{baseUrl:s,headers:i}},this.createOpenAPIClient=({baseUrl:t,headers:s})=>_({baseUrl:t,onRequest:({request:i})=>{Object.entries(s).forEach(([c,r])=>{r&&i.headers.set(c,r)})}}),this.setAuthToken=t=>{this.userToken=t;const{baseUrl:s,headers:i}=this.constructClientOptions(t);this.client=this.createOpenAPIClient({baseUrl:s,headers:i})},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:i})=>{const c=s?{lastMessageTimestamp:s}:void 0;return await this.client.GET("/backend/widget/v2/poll/{sessionId}",{params:{path:{sessionId:t},query:c},signal:i})},this.getSessions=async({cursor:t,filters:s,abortSignal:i})=>await this.client.GET("/backend/widget/v2/sessions",{params:{query:{cursor:t,filters:JSON.stringify(s)}},signal:i}),this.uploadFile=async({file:t,abortSignal:s,onProgress:i})=>new Promise((c,r)=>{var v;const d=new FormData;d.append("file",t);const l=new XMLHttpRequest;if(s&&(s.addEventListener("abort",()=>{l.abort(),r(new DOMException("Aborted","AbortError"))}),s.aborted)){r(new DOMException("Aborted","AbortError"));return}l.upload.addEventListener("progress",u=>{if(u.lengthComputable&&i){const p=Math.round(u.loaded/u.total*100);i(p)}}),l.addEventListener("load",()=>{if(l.status>=200&&l.status<300)try{const u=JSON.parse(l.responseText);c(u)}catch(u){r(new Error(`Failed to parse response: ${u}`))}else r(new Error(`Upload failed with status: ${l.status}`))}),l.addEventListener("error",()=>{r(new Error("Network error occurred"))}),l.addEventListener("timeout",()=>{r(new Error("Upload timed out"))});const{baseUrl:C}=this.constructClientOptions(this.userToken),S=`${C}/backend/widget/v2/upload`;l.open("POST",S),l.setRequestHeader("X-Bot-Token",this.config.token),this.userToken??((v=this.config.user)==null?void 0:v.token)?l.setRequestHeader("Authorization",`Bearer ${this.userToken}`):console.error("User token not set"),l.send(d)}),this.vote=async t=>await this.client.POST("/backend/widget/v2/chat/vote",{body:t}),this.resolveSession=async(t,s)=>await this.client.POST("/backend/widget/v2/session/resolve",{body:t,signal:s}),this.createStateCheckpoint=async t=>await this.client.POST("/backend/widget/v2/checkpoint",{body:t}),this.config=a,this.userToken=((n=a.user)==null?void 0:n.token)||null;const{baseUrl:o,headers:h}=this.constructClientOptions((e=a.user)==null?void 0:e.token);this.client=this.createOpenAPIClient({baseUrl:o,headers:h})}}class w{constructor(a){this.subscribers=new Set,this.get=()=>this.state,this.set=o=>{O(this.state,o)||(this.state=o,this.notifySubscribers(o))},this.setPartial=o=>{if(o==null)return;const h={...this.state,...o};this.set(h)},this.reset=()=>{this.set(this.initialState)},this.notifySubscribers=o=>{Array.from(this.subscribers).forEach(n=>{try{n(o)}catch(e){console.error(e)}})},this.subscribe=o=>(this.subscribers.add(o),()=>{this.subscribers.delete(o)}),this.state=a,this.initialState=a}}class R{constructor(){this.state=new w({isPolling:!1,isError:!1}),this.abortController=new AbortController,this.reset=()=>{var a;this.abortController.abort("Resetting poller"),(a=this.stopPolling)==null||a.call(this),this.stopPolling=null},this.stopPolling=null,this.startPolling=(a,o)=>{if(this.stopPolling)return;const h=[],n=async()=>{this.abortController=new AbortController,this.state.setPartial({isPolling:!0});try{await a(this.abortController.signal)}catch(e){if(this.abortController.signal.aborted)return;console.error("Failed to poll:",e),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(n,o))};n(),this.stopPolling=()=>{h.forEach(clearTimeout),this.state.reset()}}}}function D(g){try{const a=g();return a instanceof Promise?a.then(o=>({data:o})).catch(o=>({error:o})):{data:a}}catch(a){return{error:a}}}class L{constructor({api:a,config:o,sessionCtx:h,messageCtx:n,sessionPollingIntervalSeconds:e}){this.poller=new R,this.registerPolling=()=>{this.sessionCtx.sessionState.subscribe(({session:t})=>{t!=null&&t.id?this.poller.startPolling(async s=>{this.hackAndSlash(t.id,s)},this.sessionPollingIntervalSeconds*1e3):this.poller.reset()})},this.hackAndSlash=async(t,s)=>{var d;this.messageCtx.state.get().messages.length===0&&this.messageCtx.state.setPartial({isInitialFetchLoading:!0});const i=this.messageCtx.state.get().messages,c=i.length>0?(d=i[i.length-1])==null?void 0:d.timestamp:void 0,{data:r}=await this.api.pollSessionAndHistory({sessionId:t,abortSignal:s,lastMessageTimestamp:c});if(r!=null&&r.session&&(this.sessionCtx.sessionState.setPartial({session:r.session}),this.sessionCtx.setSessions([r.session])),r!=null&&r.history&&r.history.length>0){const l=this.messageCtx.state.get().messages,C=r.history.map(this.mapHistoryToMessage).filter(x=>!l.some(S=>S.id===x.id));this.messageCtx.state.setPartial({messages:[...l,...C]})}this.messageCtx.state.get().isInitialFetchLoading&&this.messageCtx.state.setPartial({isInitialFetchLoading:!1})},this.mapHistoryToMessage=t=>{var c,r;const s={id:t.publicId,timestamp:t.sentAt||"",attachments:t.attachments||void 0};if(t.sender.kind==="user")return{...s,type:"FROM_USER",content:t.content.text||"",deliveredAt:t.sentAt||""};if(t.sender.kind==="agent")return{...s,type:"FROM_AGENT",component:"agent_message",data:{message:t.content.text||""},agent:{name:t.sender.name||"",avatar:t.sender.avatar||"",id:null,isAi:!1}};const i=t.actionCalls&&t.actionCalls.length>0?t.actionCalls[t.actionCalls.length-1]:void 0;return{...s,type:"FROM_BOT",component:"bot_message",agent:{id:null,name:((c=this.config.bot)==null?void 0:c.name)||"",isAi:!0,avatar:((r=this.config.bot)==null?void 0:r.avatar)||""},data:{message:t.content.text||"",action:i?{name:i.actionName,data:this.extractActionResult(i)}:void 0}}},this.extractActionResult=t=>{const s=t.result;if(s===null||typeof s!="object")return s;if("responseBodyText"in s&&typeof s.responseBodyText=="string"){const i=s.responseBodyText,c=D(()=>JSON.parse(i)).data;if(c)return c}return t.result},this.api=a,this.config=o,this.sessionCtx=h,this.messageCtx=n,this.sessionPollingIntervalSeconds=e,this.registerPolling()}}class B{constructor({config:a,api:o,storageCtx:h}){var n;this.shouldCollectData=()=>{var e;return!!(!((e=this.state.get().contact)!=null&&e.token)&&this.config.collectUserData)},this.autoCreateUnverifiedUserIfNotExists=async()=>{var e,t,s,i,c,r,d,l,C,x,S,b,v,u;if(!((e=this.config.user)!=null&&e.token)){if(this.config.collectUserData&&!((s=(t=this.config.user)==null?void 0:t.data)!=null&&s.email)){if((i=this.config.extraDataCollectionFields)!=null&&i.length)return;const p=await((c=this.storageCtx)==null?void 0:c.getContactToken());p&&await this.setUnverifiedContact(p);return}if(!((d=(r=this.config.user)==null?void 0:r.data)!=null&&d.email)){const p=await((l=this.storageCtx)==null?void 0:l.getContactToken());if(p){await this.setUnverifiedContact(p);return}}await this.createUnverifiedContact({email:(x=(C=this.config.user)==null?void 0:C.data)==null?void 0:x.email,non_verified_name:((b=(S=this.config.user)==null?void 0:S.data)==null?void 0:b.name)||"Anonymous",non_verified_custom_data:(u=(v=this.config.user)==null?void 0:v.data)==null?void 0:u.customData})}},this.createUnverifiedContact=async(e,t)=>{this.state.setPartial({extraCollectedData:t});try{this.state.setPartial({isCreatingUnverifiedContact:!0,isErrorCreatingUnverifiedContact:!1});const{data:s}=await this.api.createUnverifiedContact(e);s!=null&&s.token?await this.setUnverifiedContact(s.token):this.state.setPartial({isErrorCreatingUnverifiedContact:!0})}finally{this.state.setPartial({isCreatingUnverifiedContact:!1})}},this.setUnverifiedContact=async e=>{var i,c,r,d;const t=await((i=this.storageCtx)==null?void 0:i.getExternalContactId()),s=((c=this.config.user)==null?void 0:c.externalId)||t||E.v4();this.api.setAuthToken(e),await((r=this.storageCtx)==null?void 0:r.setContactToken(e)),await((d=this.storageCtx)==null?void 0:d.setExternalContactId(s)),this.state.setPartial({contact:{token:e,externalId:s}})},this.config=a,this.storageCtx=h,this.api=o,this.state=new w({contact:(n=a.user)!=null&&n.token?{token:a.user.token,externalId:a.user.externalId}:null,extraCollectedData:void 0,isCreatingUnverifiedContact:!1,isErrorCreatingUnverifiedContact:!1}),this.autoCreateUnverifiedUserIfNotExists()}}function y(){return E.v4()}class q{constructor({api:a,contactCtx:o,sessionsPollingIntervalSeconds:h}){this.sessionsRefresher=new R,this.sessionState=new w({session:null,isCreatingSession:!1,isResolvingSession:!1}),this.sessionsState=new w({data:[],cursor:void 0,isLastPage:!1,didStartInitialFetch:!1,isInitialFetchLoading:!0}),this.reset=async()=>{this.sessionState.reset()},this.registerSessionsRefresherWrapper=()=>{var n;(n=this.contactCtx.state.get().contact)!=null&&n.token&&!this.sessionsState.get().didStartInitialFetch?this.registerSessionsRefresher():this.contactCtx.state.subscribe(({contact:e})=>{e!=null&&e.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 s;this.sessionState.setPartial({session:null,isCreatingSession:!0});const n=(s=this.contactCtx.state.get().contact)==null?void 0:s.externalId,{data:e,error:t}=await this.api.createSession({customData:n?{external_id:n}:void 0});return e?(this.sessionState.setPartial({session:e,isCreatingSession:!1}),e):(this.sessionState.setPartial({isCreatingSession:!1}),console.error("Failed to create session:",t),null)},this.loadMoreSessions=async()=>{if(this.sessionsState.get().isLastPage)return;const{data:n}=await this.getSessions({cursor:this.sessionsState.get().cursor});if(n){const t=[...this.sessionsState.get().data,...n.items].filter((s,i,c)=>i===c.findIndex(r=>s.id===r.id));this.sessionsState.setPartial({data:t,cursor:n.next||void 0,isLastPage:n.next===null})}},this.getSessions=async({cursor:n})=>{var t,s;if(!((t=this.contactCtx.state.get().contact)!=null&&t.token))return{data:null};const e=(s=this.contactCtx.state.get().contact)==null?void 0:s.externalId;return await this.api.getSessions({cursor:n,filters:e?{external_id:e}:{}})},this.setSessions=n=>{const e=[...n,...this.sessionsState.get().data].filter((t,s,i)=>s===i.findIndex(c=>t.id===c.id));this.sessionsState.setPartial({data:e})},this.refreshSessions=async()=>{const{data:n}=await this.getSessions({cursor:void 0});n&&this.setSessions(n.items)},this.resolveSession=async()=>{const n=this.sessionState.get().session;if(!n||!n.isOpened)return{success:!1,error:"Session is not opened"};this.sessionState.setPartial({isResolvingSession:!0});const{data:e,error:t}=await this.api.resolveSession({session_id:n.id});return e?(this.sessionState.setPartial({session:e,isResolvingSession:!1}),{success:!0,data:e}):(this.sessionState.setPartial({isResolvingSession:!1}),{success:!1,error:t})},this.createStateCheckpoint=async n=>{var i;const e=(i=this.sessionState.get().session)==null?void 0:i.id;if(!e)return;const{data:t,error:s}=await this.api.createStateCheckpoint({session_id:e,payload:n});return t?{data:t}:{success:!1,error:s}},this.api=a,this.contactCtx=o,this.sessionsPollingIntervalSeconds=h,this.registerSessionsRefresherWrapper()}}class ${constructor({config:a,api:o,sessionCtx:h,contactCtx:n}){this.state=new w({messages:[],isSendingMessage:!1,lastAIResMightSolveUserIssue:!1,isInitialFetchLoading:!1}),this.sendMessageAbortController=new AbortController,this.reset=()=>{this.sendMessageAbortController.abort("Resetting chat"),this.state.reset()},this.sendMessage=async e=>{var r,d,l,C,x,S,b,v;if(!e.content.trim()&&(!e.attachments||e.attachments.length===0)){console.warn("Cannot send an empty message of no content or attachments");return}const t=this.state.get().isSendingMessage,s=((r=this.sessionCtx.sessionState.get().session)==null?void 0:r.assignee.kind)==="ai",i=this.state.get().messages,c=i.length>0?i[i.length-1]:void 0;if(s&&t||s&&(c==null?void 0:c.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 u=this.toUserMessage(e.content.trim(),e.attachments||void 0),p=this.state.get().messages;if(this.state.setPartial({messages:[...p,u]}),!((d=this.sessionCtx.sessionState.get().session)!=null&&d.id)){if(!await this.sessionCtx.createSession()){console.error("Failed to create session");return}this.sessionCtx.refreshSessions()}const T=(l=this.sessionCtx.sessionState.get().session)==null?void 0:l.id;if(!T)return;const{data:f}=await this.api.sendMessage({uuid:u.id,bot_token:this.config.token,headers:this.config.headers,query_params:this.config.queryParams,body_properties:this.config.bodyProperties,session_id:T,content:u.content,attachments:e.attachments,clientContext:this.config.context,custom_data:{...this.config.messageCustomData||{},...e.customData||{}},language:this.config.language,exit_mode_prompt:e.exitModePrompt},this.sendMessageAbortController.signal);if(f!=null&&f.success){const P=this.toBotMessage(f);if(P){const I=this.state.get().messages;if(!!I.some(A=>A.id===P.id)){this.state.setPartial({lastAIResMightSolveUserIssue:((C=f.autopilotResponse)==null?void 0:C.mightSolveUserIssue)||((x=f.uiResponse)==null?void 0:x.mightSolveUserIssue)});return}this.state.setPartial({messages:[...I,P],lastAIResMightSolveUserIssue:((S=f.autopilotResponse)==null?void 0:S.mightSolveUserIssue)||((b=f.uiResponse)==null?void 0:b.mightSolveUserIssue)})}f.session&&this.sessionCtx.sessionState.setPartial({session:f.session})}else{const P=this.toBotErrorMessage(((v=f==null?void 0:f.error)==null?void 0:v.message)||"Unknown error occurred"),I=this.state.get().messages;this.state.setPartial({messages:[...I,P]})}}catch(u){this.sendMessageAbortController.signal.aborted||console.error("Failed to send message:",u)}finally{this.state.setPartial({isSendingMessage:!1})}},this.toUserMessage=(e,t)=>{const s=(()=>{const i=this.contactCtx.state.get().extraCollectedData;return this.state.get().messages.length===0&&i&&Object.keys(i).length>0?`${Object.entries(i).filter(([r,d])=>!!d).map(([r,d])=>`${r}: ${d}`).join(`
2
+ `)}
3
+
4
+ ${e}`:e})();return{id:y(),type:"FROM_USER",content:s,deliveredAt:new Date().toISOString(),attachments:t,timestamp:new Date().toISOString()}},this.toBotMessage=e=>{var t;return e.success&&e.autopilotResponse?{type:"FROM_BOT",id:e.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:e.autopilotResponse.value.content,action:(t=e.uiResponse)!=null&&t.value.name?{name:e.uiResponse.value.name,data:e.uiResponse.value.request_response}:void 0}}:null},this.toBotErrorMessage=e=>({type:"FROM_BOT",id:y(),timestamp:new Date().toISOString(),component:"TEXT",data:{message:e,variant:"error",action:void 0}}),this.config=a,this.api=o,this.sessionCtx=h,this.contactCtx=n}}class N{constructor({config:a,contactCtx:o,sessionCtx:h,resetChat:n}){var e;this.registerRoutingListener=()=>{this.contactCtx.state.subscribe(({contact:t})=>{var s;t!=null&&t.token&&this.state.get().screen==="welcome"&&this.state.setPartial({screen:(s=this.config.router)!=null&&s.chatScreenOnly?"chat":"sessions"})}),this.sessionCtx.sessionsState.subscribe(({isInitialFetchLoading:t,data:s})=>{var i,c,r,d;if((i=this.config.router)!=null&&i.chatScreenOnly&&!((c=this.sessionCtx.sessionState.get().session)!=null&&c.id)){const l=(r=s.find(C=>C.isOpened))==null?void 0:r.id;return l?this.toChatScreen(l):void 0}s.length||((d=this.config.router)==null?void 0:d.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(i=>i.id===t);if(!s)return;this.sessionCtx.sessionState.setPartial({session:s})}this.state.setPartial({screen:"chat"})},this.config=a,this.contactCtx=o,this.sessionCtx=h,this.resetChat=n,this.state=new w({screen:this.contactCtx.shouldCollectData()?"welcome":(e=this.config.router)!=null&&e.chatScreenOnly?"chat":"sessions"}),this.registerRoutingListener()}}class H{constructor({storage:a}){this.KEYS={contactToken:"opencx__widget__contactToken",externalContactId:"opencx__widget__externalContactId"},this.setContactToken=async o=>{await this.storage.set(this.KEYS.contactToken,o)},this.getContactToken=async()=>this.storage.get(this.KEYS.contactToken),this.setExternalContactId=async o=>{await this.storage.set(this.KEYS.externalContactId,o)},this.getExternalContactId=async()=>this.storage.get(this.KEYS.externalContactId),this.storage=a}}const m=class m{constructor({config:a,storage:o,modes:h}){if(this.modes=[],this.resetChat=()=>{this.sessionCtx.reset(),this.messageCtx.reset()},!m.pollingIntervalsSeconds)throw Error("Widget polling values are not defined, did you call WidgetCtx.initialize()");this.config=a,this.api=new U({config:a}),this.storageCtx=o?new H({storage:o}):void 0,this.modes=h,this.contactCtx=new B({api:this.api,config:this.config,storageCtx:this.storageCtx}),this.sessionCtx=new q({api:this.api,contactCtx:this.contactCtx,sessionsPollingIntervalSeconds:m.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:m.pollingIntervalsSeconds.session}),this.routerCtx=new N({config:this.config,contactCtx:this.contactCtx,sessionCtx:this.sessionCtx,resetChat:this.resetChat})}};m.pollingIntervalsSeconds=null,m.initialize=async({config:a,storage:o})=>{var n,e,t;const h=await new U({config:a}).getExternalWidgetConfig();return m.pollingIntervalsSeconds={session:((n=h.data)==null?void 0:n.sessionPollingIntervalSeconds)||10,sessions:((e=h.data)==null?void 0:e.sessionsPollingIntervalSeconds)||60},new m({config:a,storage:o,modes:((t=h.data)==null?void 0:t.modes)||[]})};let k=m;exports.PrimitiveState=w;exports.WidgetCtx=k;
5
+ //# sourceMappingURL=widget.ctx-6xcbtF7q.cjs.map