@opencx/widget 3.0.88 → 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/designs.cjs +47 -19
- package/dist/designs.cjs.map +1 -1
- package/dist/designs.js +16252 -1279
- package/dist/designs.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -6
- package/dist/index.js.map +1 -1
- package/dist/is-exhaustive-9o43S91P.cjs +2 -0
- package/dist/is-exhaustive-9o43S91P.cjs.map +1 -0
- package/dist/is-exhaustive-DGJzQK69.js +7 -0
- package/dist/is-exhaustive-DGJzQK69.js.map +1 -0
- package/dist/react.cjs +1 -1
- package/dist/react.js +2 -2
- package/dist/{useModes-DleBrdDK.js → useModes-B3IdrBWZ.js} +34 -33
- package/dist/{useModes-DleBrdDK.js.map → useModes-B3IdrBWZ.js.map} +1 -1
- package/dist/useModes-ZmjqOTMd.cjs +2 -0
- package/dist/{useModes-DSFNdOy3.cjs.map → useModes-ZmjqOTMd.cjs.map} +1 -1
- package/dist/widget.ctx-6xcbtF7q.cjs +5 -0
- package/dist/widget.ctx-6xcbtF7q.cjs.map +1 -0
- package/dist/widget.ctx-uAWzif3-.js +688 -0
- package/dist/widget.ctx-uAWzif3-.js.map +1 -0
- package/dist-embed/script.js +1 -1
- package/package.json +1 -4
- package/dist/useModes-DSFNdOy3.cjs +0 -2
- package/dist/widget.ctx-CC3c7FPb.js +0 -1542
- package/dist/widget.ctx-CC3c7FPb.js.map +0 -1
- package/dist/widget.ctx-HuLTTMAM.cjs +0 -5
- package/dist/widget.ctx-HuLTTMAM.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./widget.ctx-
|
|
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
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { P as
|
|
2
|
-
|
|
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
|
-
|
|
4
|
+
e as PrimitiveState,
|
|
7
5
|
a as WidgetCtx,
|
|
8
|
-
|
|
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":[
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
|
@@ -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 @@
|
|
|
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-
|
|
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
|
package/dist/react.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { u as o } from "./useModes-
|
|
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-
|
|
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
3
|
import r from "react-use/lib/useAsyncFn";
|
|
4
4
|
function n(e, s, t) {
|
|
5
5
|
const {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import k from "swr";
|
|
2
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 {
|
|
4
|
-
import { jsx as
|
|
5
|
-
|
|
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";
|
|
6
7
|
class T {
|
|
7
8
|
constructor(t) {
|
|
8
9
|
this.components = [];
|
|
@@ -28,8 +29,8 @@ class T {
|
|
|
28
29
|
return (n = this.get(t)) == null ? void 0 : n.component;
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
|
-
const
|
|
32
|
-
function
|
|
32
|
+
const W = b(null);
|
|
33
|
+
function D({
|
|
33
34
|
options: e,
|
|
34
35
|
children: t,
|
|
35
36
|
components: n,
|
|
@@ -44,9 +45,9 @@ function z({
|
|
|
44
45
|
[n]
|
|
45
46
|
);
|
|
46
47
|
return h(() => {
|
|
47
|
-
u.current || (u.current = !0,
|
|
48
|
-
}, []), p ? /* @__PURE__ */
|
|
49
|
-
|
|
48
|
+
u.current || (u.current = !0, R.initialize({ config: e, storage: i }).then(f));
|
|
49
|
+
}, []), p ? /* @__PURE__ */ F(
|
|
50
|
+
W.Provider,
|
|
50
51
|
{
|
|
51
52
|
value: {
|
|
52
53
|
widgetCtx: p,
|
|
@@ -62,19 +63,19 @@ function z({
|
|
|
62
63
|
) : a || null;
|
|
63
64
|
}
|
|
64
65
|
function g() {
|
|
65
|
-
const e = U(
|
|
66
|
+
const e = U(W);
|
|
66
67
|
if (!e)
|
|
67
68
|
throw new Error("useWidget must be used within a WidgetProvider");
|
|
68
69
|
return e;
|
|
69
70
|
}
|
|
70
|
-
function
|
|
71
|
+
function v() {
|
|
71
72
|
const { config: e } = g();
|
|
72
73
|
return e;
|
|
73
74
|
}
|
|
74
75
|
function C(e) {
|
|
75
76
|
return P(e.subscribe, e.get, e.get);
|
|
76
77
|
}
|
|
77
|
-
function
|
|
78
|
+
function _() {
|
|
78
79
|
const { widgetCtx: e } = g();
|
|
79
80
|
return {
|
|
80
81
|
contactState: C(e.contactCtx.state),
|
|
@@ -86,7 +87,7 @@ function M() {
|
|
|
86
87
|
return { messagesState: C(e.messageCtx.state), sendMessage: e.messageCtx.sendMessage };
|
|
87
88
|
}
|
|
88
89
|
function E() {
|
|
89
|
-
const { widgetCtx: e } = g(), { oneOpenSessionAllowed: t } =
|
|
90
|
+
const { widgetCtx: e } = g(), { oneOpenSessionAllowed: t } = v(), n = C(e.sessionCtx.sessionState), o = C(e.sessionCtx.sessionsState), { openSessions: i, closedSessions: a } = m(() => ({
|
|
90
91
|
openSessions: o.data.filter((u) => u.isOpened === !0),
|
|
91
92
|
closedSessions: o.data.filter((u) => u.isOpened === !1)
|
|
92
93
|
}), [o.data]), d = m(() => t ? i.length === 0 : !0, [t, i.length]);
|
|
@@ -101,18 +102,18 @@ function E() {
|
|
|
101
102
|
canCreateNewSession: d
|
|
102
103
|
};
|
|
103
104
|
}
|
|
104
|
-
function
|
|
105
|
+
function $() {
|
|
105
106
|
var d;
|
|
106
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";
|
|
107
108
|
return { isAwaitingBotReply: (n || e.isCreatingSession) && (t.isSendingMessage || i) };
|
|
108
109
|
}
|
|
109
|
-
function
|
|
110
|
+
function q() {
|
|
110
111
|
const { widgetCtx: e } = g();
|
|
111
112
|
return k([e.config.token], e.api.widgetPrelude, {
|
|
112
113
|
revalidateOnFocus: !1
|
|
113
114
|
});
|
|
114
115
|
}
|
|
115
|
-
function
|
|
116
|
+
function G() {
|
|
116
117
|
const { widgetCtx: e } = g();
|
|
117
118
|
return {
|
|
118
119
|
routerState: C(e.routerCtx.state),
|
|
@@ -121,14 +122,14 @@ function q() {
|
|
|
121
122
|
};
|
|
122
123
|
}
|
|
123
124
|
const l = /* @__PURE__ */ new Map();
|
|
124
|
-
function
|
|
125
|
+
function H() {
|
|
125
126
|
const [e, t] = w([]), {
|
|
126
127
|
widgetCtx: { api: n }
|
|
127
128
|
} = g();
|
|
128
129
|
function o(s) {
|
|
129
130
|
const r = s.map((c) => ({
|
|
130
131
|
file: c,
|
|
131
|
-
id:
|
|
132
|
+
id: O(),
|
|
132
133
|
status: "pending",
|
|
133
134
|
progress: 0
|
|
134
135
|
}));
|
|
@@ -201,8 +202,8 @@ function G() {
|
|
|
201
202
|
};
|
|
202
203
|
}
|
|
203
204
|
const A = b(null);
|
|
204
|
-
function
|
|
205
|
-
const t =
|
|
205
|
+
function J({ children: e }) {
|
|
206
|
+
const t = v(), [n, o] = w(t.isOpen ?? !1);
|
|
206
207
|
return h(() => {
|
|
207
208
|
o((i) => t.isOpen ?? i);
|
|
208
209
|
}, [t.isOpen]), h(() => {
|
|
@@ -211,9 +212,9 @@ function H({ children: e }) {
|
|
|
211
212
|
return;
|
|
212
213
|
const a = setTimeout(() => o(!0), i * 1e3);
|
|
213
214
|
return () => clearTimeout(a);
|
|
214
|
-
}, [t.openAfterNSeconds]), /* @__PURE__ */
|
|
215
|
+
}, [t.openAfterNSeconds]), /* @__PURE__ */ F(A.Provider, { value: { isOpen: n, setIsOpen: o }, children: e });
|
|
215
216
|
}
|
|
216
|
-
function
|
|
217
|
+
function K() {
|
|
217
218
|
const e = U(A);
|
|
218
219
|
if (!e)
|
|
219
220
|
throw new Error(
|
|
@@ -221,7 +222,7 @@ function J() {
|
|
|
221
222
|
);
|
|
222
223
|
return e;
|
|
223
224
|
}
|
|
224
|
-
function
|
|
225
|
+
function Q() {
|
|
225
226
|
var u, p;
|
|
226
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(
|
|
227
228
|
(f) => {
|
|
@@ -242,19 +243,19 @@ function K() {
|
|
|
242
243
|
};
|
|
243
244
|
}
|
|
244
245
|
export {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
D as W,
|
|
247
|
+
v as a,
|
|
248
|
+
_ as b,
|
|
249
|
+
$ as c,
|
|
249
250
|
M as d,
|
|
250
|
-
|
|
251
|
+
q as e,
|
|
251
252
|
C as f,
|
|
252
253
|
E as g,
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
254
|
+
G as h,
|
|
255
|
+
H as i,
|
|
256
|
+
K as j,
|
|
257
|
+
J as k,
|
|
258
|
+
Q as l,
|
|
258
259
|
g as u
|
|
259
260
|
};
|
|
260
|
-
//# sourceMappingURL=useModes-
|
|
261
|
+
//# sourceMappingURL=useModes-B3IdrBWZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModes-DleBrdDK.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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"}
|
|
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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModes-DSFNdOy3.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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"}
|
|
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
|