@hissuno/widget 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.mts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +42 -20
- package/dist/index.mjs +42 -20
- package/dist/styles.css +4 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ function App() {
|
|
|
51
51
|
| `theme` | `'light' \| 'dark' \| 'auto'` | `'light'` | Color theme (`auto` follows system preference) |
|
|
52
52
|
| `userId` | `string` | - | End-user identifier for session tracking |
|
|
53
53
|
| `userMetadata` | `Record<string, string>` | - | Additional user info (name, email, plan, etc.) |
|
|
54
|
-
| `apiUrl` | `string` | `'/api/
|
|
54
|
+
| `apiUrl` | `string` | `'/api/integrations/widget/chat'` | Custom API endpoint URL |
|
|
55
55
|
| `title` | `string` | `'Support'` | Chat window title |
|
|
56
56
|
| `placeholder` | `string` | `'Ask a question...'` | Input field placeholder |
|
|
57
57
|
| `initialMessage` | `string` | `'Hi! How can I help?'` | First message shown to users |
|
package/dist/index.d.mts
CHANGED
|
@@ -88,8 +88,7 @@ interface HissunoWidgetProps {
|
|
|
88
88
|
*/
|
|
89
89
|
userMetadata?: Record<string, string>;
|
|
90
90
|
/**
|
|
91
|
-
* The URL of your Hissuno API endpoint
|
|
92
|
-
* @default "/api/agent"
|
|
91
|
+
* Optional: The URL of your Hissuno API endpoint
|
|
93
92
|
*/
|
|
94
93
|
apiUrl?: string;
|
|
95
94
|
/**
|
|
@@ -160,6 +159,13 @@ interface HissunoWidgetProps {
|
|
|
160
159
|
* Callback when the chat window closes
|
|
161
160
|
*/
|
|
162
161
|
onClose?: () => void;
|
|
162
|
+
/**
|
|
163
|
+
* Callback that exposes chat controls for external manipulation
|
|
164
|
+
* Useful for programmatically setting input values
|
|
165
|
+
*/
|
|
166
|
+
onControlsReady?: (controls: {
|
|
167
|
+
setInput: (value: string) => void;
|
|
168
|
+
}) => void;
|
|
163
169
|
/**
|
|
164
170
|
* Additional CSS class name for custom styling
|
|
165
171
|
*/
|
|
@@ -232,7 +238,7 @@ interface WidgetSettings {
|
|
|
232
238
|
* }
|
|
233
239
|
* ```
|
|
234
240
|
*/
|
|
235
|
-
declare function HissunoWidget({ projectId, widgetToken, trigger: propTrigger, display: propDisplay, shortcut: propShortcut, fetchDefaults, userId, userMetadata, apiUrl, theme: propTheme, bubblePosition: propBubblePosition, bubbleOffset, drawerBadgeLabel: propDrawerBadgeLabel, dialogWidth: propDialogWidth, dialogHeight: propDialogHeight, renderTrigger, title: propTitle, placeholder, initialMessage: propInitialMessage, defaultOpen, onOpen, onClose, className, headers, }: HissunoWidgetProps): react_jsx_runtime.JSX.Element | null;
|
|
241
|
+
declare function HissunoWidget({ projectId, widgetToken, trigger: propTrigger, display: propDisplay, shortcut: propShortcut, fetchDefaults, userId, userMetadata, apiUrl, theme: propTheme, bubblePosition: propBubblePosition, bubbleOffset, drawerBadgeLabel: propDrawerBadgeLabel, dialogWidth: propDialogWidth, dialogHeight: propDialogHeight, renderTrigger, title: propTitle, placeholder, initialMessage: propInitialMessage, defaultOpen, onOpen, onClose, onControlsReady, className, headers, }: HissunoWidgetProps): react_jsx_runtime.JSX.Element | null;
|
|
236
242
|
|
|
237
243
|
interface ChatBubbleProps {
|
|
238
244
|
isOpen: boolean;
|
|
@@ -275,7 +281,7 @@ interface UseHissunoChatOptions {
|
|
|
275
281
|
projectId: string;
|
|
276
282
|
/** JWT token for secure widget authentication */
|
|
277
283
|
widgetToken?: string;
|
|
278
|
-
/** Custom API endpoint URL (default: '/api/
|
|
284
|
+
/** Custom API endpoint URL (default: '/api/integrations/widget/chat') */
|
|
279
285
|
apiUrl?: string;
|
|
280
286
|
/** Initial assistant message shown when chat opens */
|
|
281
287
|
initialMessage?: string;
|
|
@@ -287,6 +293,8 @@ interface UseHissunoChatOptions {
|
|
|
287
293
|
userMetadata?: Record<string, string>;
|
|
288
294
|
/** Custom session ID (auto-generated if not provided) */
|
|
289
295
|
sessionId?: string;
|
|
296
|
+
/** Override the knowledge package used for this chat session (for testing) */
|
|
297
|
+
packageId?: string;
|
|
290
298
|
/** Inactivity timeout in ms before auto-closing session (default: 30 minutes) */
|
|
291
299
|
inactivityTimeout?: number;
|
|
292
300
|
/** Callback when session is closed */
|
|
@@ -352,7 +360,7 @@ interface UseHissunoChatReturn {
|
|
|
352
360
|
* @param options - Hook configuration options
|
|
353
361
|
* @returns Chat state and control functions
|
|
354
362
|
*/
|
|
355
|
-
declare function useHissunoChat({ projectId, widgetToken, apiUrl, initialMessage, headers, userId, userMetadata, sessionId: providedSessionId, inactivityTimeout, onSessionClose, }: UseHissunoChatOptions): UseHissunoChatReturn;
|
|
363
|
+
declare function useHissunoChat({ projectId, widgetToken, apiUrl, initialMessage, headers, userId, userMetadata, sessionId: providedSessionId, packageId, inactivityTimeout, onSessionClose, }: UseHissunoChatOptions): UseHissunoChatReturn;
|
|
356
364
|
|
|
357
365
|
interface ChatPopupProps {
|
|
358
366
|
isOpen: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -88,8 +88,7 @@ interface HissunoWidgetProps {
|
|
|
88
88
|
*/
|
|
89
89
|
userMetadata?: Record<string, string>;
|
|
90
90
|
/**
|
|
91
|
-
* The URL of your Hissuno API endpoint
|
|
92
|
-
* @default "/api/agent"
|
|
91
|
+
* Optional: The URL of your Hissuno API endpoint
|
|
93
92
|
*/
|
|
94
93
|
apiUrl?: string;
|
|
95
94
|
/**
|
|
@@ -160,6 +159,13 @@ interface HissunoWidgetProps {
|
|
|
160
159
|
* Callback when the chat window closes
|
|
161
160
|
*/
|
|
162
161
|
onClose?: () => void;
|
|
162
|
+
/**
|
|
163
|
+
* Callback that exposes chat controls for external manipulation
|
|
164
|
+
* Useful for programmatically setting input values
|
|
165
|
+
*/
|
|
166
|
+
onControlsReady?: (controls: {
|
|
167
|
+
setInput: (value: string) => void;
|
|
168
|
+
}) => void;
|
|
163
169
|
/**
|
|
164
170
|
* Additional CSS class name for custom styling
|
|
165
171
|
*/
|
|
@@ -232,7 +238,7 @@ interface WidgetSettings {
|
|
|
232
238
|
* }
|
|
233
239
|
* ```
|
|
234
240
|
*/
|
|
235
|
-
declare function HissunoWidget({ projectId, widgetToken, trigger: propTrigger, display: propDisplay, shortcut: propShortcut, fetchDefaults, userId, userMetadata, apiUrl, theme: propTheme, bubblePosition: propBubblePosition, bubbleOffset, drawerBadgeLabel: propDrawerBadgeLabel, dialogWidth: propDialogWidth, dialogHeight: propDialogHeight, renderTrigger, title: propTitle, placeholder, initialMessage: propInitialMessage, defaultOpen, onOpen, onClose, className, headers, }: HissunoWidgetProps): react_jsx_runtime.JSX.Element | null;
|
|
241
|
+
declare function HissunoWidget({ projectId, widgetToken, trigger: propTrigger, display: propDisplay, shortcut: propShortcut, fetchDefaults, userId, userMetadata, apiUrl, theme: propTheme, bubblePosition: propBubblePosition, bubbleOffset, drawerBadgeLabel: propDrawerBadgeLabel, dialogWidth: propDialogWidth, dialogHeight: propDialogHeight, renderTrigger, title: propTitle, placeholder, initialMessage: propInitialMessage, defaultOpen, onOpen, onClose, onControlsReady, className, headers, }: HissunoWidgetProps): react_jsx_runtime.JSX.Element | null;
|
|
236
242
|
|
|
237
243
|
interface ChatBubbleProps {
|
|
238
244
|
isOpen: boolean;
|
|
@@ -275,7 +281,7 @@ interface UseHissunoChatOptions {
|
|
|
275
281
|
projectId: string;
|
|
276
282
|
/** JWT token for secure widget authentication */
|
|
277
283
|
widgetToken?: string;
|
|
278
|
-
/** Custom API endpoint URL (default: '/api/
|
|
284
|
+
/** Custom API endpoint URL (default: '/api/integrations/widget/chat') */
|
|
279
285
|
apiUrl?: string;
|
|
280
286
|
/** Initial assistant message shown when chat opens */
|
|
281
287
|
initialMessage?: string;
|
|
@@ -287,6 +293,8 @@ interface UseHissunoChatOptions {
|
|
|
287
293
|
userMetadata?: Record<string, string>;
|
|
288
294
|
/** Custom session ID (auto-generated if not provided) */
|
|
289
295
|
sessionId?: string;
|
|
296
|
+
/** Override the knowledge package used for this chat session (for testing) */
|
|
297
|
+
packageId?: string;
|
|
290
298
|
/** Inactivity timeout in ms before auto-closing session (default: 30 minutes) */
|
|
291
299
|
inactivityTimeout?: number;
|
|
292
300
|
/** Callback when session is closed */
|
|
@@ -352,7 +360,7 @@ interface UseHissunoChatReturn {
|
|
|
352
360
|
* @param options - Hook configuration options
|
|
353
361
|
* @returns Chat state and control functions
|
|
354
362
|
*/
|
|
355
|
-
declare function useHissunoChat({ projectId, widgetToken, apiUrl, initialMessage, headers, userId, userMetadata, sessionId: providedSessionId, inactivityTimeout, onSessionClose, }: UseHissunoChatOptions): UseHissunoChatReturn;
|
|
363
|
+
declare function useHissunoChat({ projectId, widgetToken, apiUrl, initialMessage, headers, userId, userMetadata, sessionId: providedSessionId, packageId, inactivityTimeout, onSessionClose, }: UseHissunoChatOptions): UseHissunoChatReturn;
|
|
356
364
|
|
|
357
365
|
interface ChatPopupProps {
|
|
358
366
|
isOpen: boolean;
|
package/dist/index.js
CHANGED
|
@@ -957,15 +957,15 @@ function ChatPopup({
|
|
|
957
957
|
},
|
|
958
958
|
children: [
|
|
959
959
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
960
|
-
"
|
|
960
|
+
"textarea",
|
|
961
961
|
{
|
|
962
|
-
type: "text",
|
|
963
962
|
value: input,
|
|
964
963
|
onChange: (e) => setInput(e.target.value),
|
|
965
964
|
onKeyDown: handleKeyDown,
|
|
966
965
|
placeholder,
|
|
967
966
|
disabled: isLoading,
|
|
968
967
|
"aria-label": "Type your message",
|
|
968
|
+
rows: 1,
|
|
969
969
|
style: {
|
|
970
970
|
flex: 1,
|
|
971
971
|
padding: "10px 14px",
|
|
@@ -975,7 +975,12 @@ function ChatPopup({
|
|
|
975
975
|
color: textColor,
|
|
976
976
|
fontSize: 14,
|
|
977
977
|
outline: "none",
|
|
978
|
-
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
978
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
979
|
+
resize: "none",
|
|
980
|
+
minHeight: 40,
|
|
981
|
+
maxHeight: 120,
|
|
982
|
+
overflow: "auto",
|
|
983
|
+
lineHeight: "20px"
|
|
979
984
|
}
|
|
980
985
|
}
|
|
981
986
|
),
|
|
@@ -1099,7 +1104,7 @@ function ChatSidepanel({
|
|
|
1099
1104
|
position: "fixed",
|
|
1100
1105
|
top: 0,
|
|
1101
1106
|
right: 0,
|
|
1102
|
-
width:
|
|
1107
|
+
width: 480,
|
|
1103
1108
|
height: "100vh",
|
|
1104
1109
|
display: "flex",
|
|
1105
1110
|
flexDirection: "column",
|
|
@@ -1255,15 +1260,15 @@ function ChatSidepanel({
|
|
|
1255
1260
|
},
|
|
1256
1261
|
children: [
|
|
1257
1262
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1258
|
-
"
|
|
1263
|
+
"textarea",
|
|
1259
1264
|
{
|
|
1260
|
-
type: "text",
|
|
1261
1265
|
value: input,
|
|
1262
1266
|
onChange: (e) => setInput(e.target.value),
|
|
1263
1267
|
onKeyDown: handleKeyDown,
|
|
1264
1268
|
placeholder,
|
|
1265
1269
|
disabled: isLoading,
|
|
1266
1270
|
"aria-label": "Type your message",
|
|
1271
|
+
rows: 1,
|
|
1267
1272
|
style: {
|
|
1268
1273
|
flex: 1,
|
|
1269
1274
|
padding: "10px 14px",
|
|
@@ -1273,7 +1278,12 @@ function ChatSidepanel({
|
|
|
1273
1278
|
color: textColor,
|
|
1274
1279
|
fontSize: 14,
|
|
1275
1280
|
outline: "none",
|
|
1276
|
-
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
1281
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1282
|
+
resize: "none",
|
|
1283
|
+
minHeight: 40,
|
|
1284
|
+
maxHeight: 120,
|
|
1285
|
+
overflow: "auto",
|
|
1286
|
+
lineHeight: "20px"
|
|
1277
1287
|
}
|
|
1278
1288
|
}
|
|
1279
1289
|
),
|
|
@@ -1638,9 +1648,8 @@ function ChatDialog({
|
|
|
1638
1648
|
},
|
|
1639
1649
|
children: [
|
|
1640
1650
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1641
|
-
"
|
|
1651
|
+
"textarea",
|
|
1642
1652
|
{
|
|
1643
|
-
type: "text",
|
|
1644
1653
|
value: input,
|
|
1645
1654
|
onChange: (e) => setInput(e.target.value),
|
|
1646
1655
|
onKeyDown: handleKeyDown,
|
|
@@ -1648,6 +1657,7 @@ function ChatDialog({
|
|
|
1648
1657
|
disabled: isLoading,
|
|
1649
1658
|
autoFocus: true,
|
|
1650
1659
|
"aria-label": "Type your message",
|
|
1660
|
+
rows: 1,
|
|
1651
1661
|
style: {
|
|
1652
1662
|
flex: 1,
|
|
1653
1663
|
padding: "12px 16px",
|
|
@@ -1657,7 +1667,12 @@ function ChatDialog({
|
|
|
1657
1667
|
color: textColor,
|
|
1658
1668
|
fontSize: 14,
|
|
1659
1669
|
outline: "none",
|
|
1660
|
-
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
1670
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1671
|
+
resize: "none",
|
|
1672
|
+
minHeight: 44,
|
|
1673
|
+
maxHeight: 120,
|
|
1674
|
+
overflow: "auto",
|
|
1675
|
+
lineHeight: "20px"
|
|
1661
1676
|
}
|
|
1662
1677
|
}
|
|
1663
1678
|
),
|
|
@@ -2012,12 +2027,13 @@ function deleteSessionFromRegistry(projectId, userId, sessionId) {
|
|
|
2012
2027
|
function useHissunoChat({
|
|
2013
2028
|
projectId,
|
|
2014
2029
|
widgetToken,
|
|
2015
|
-
apiUrl = "/api/
|
|
2030
|
+
apiUrl = "/api/integrations/widget/chat",
|
|
2016
2031
|
initialMessage,
|
|
2017
2032
|
headers = {},
|
|
2018
2033
|
userId,
|
|
2019
2034
|
userMetadata,
|
|
2020
2035
|
sessionId: providedSessionId,
|
|
2036
|
+
packageId,
|
|
2021
2037
|
inactivityTimeout = DEFAULT_INACTIVITY_TIMEOUT,
|
|
2022
2038
|
onSessionClose
|
|
2023
2039
|
}) {
|
|
@@ -2171,7 +2187,7 @@ function useHissunoChat({
|
|
|
2171
2187
|
}, [apiUrl, projectId, sessionId, connectToStream]);
|
|
2172
2188
|
(0, import_react4.useEffect)(() => {
|
|
2173
2189
|
if (sessionClosedRef.current || !sessionId) return;
|
|
2174
|
-
const updatesUrl = `${apiUrl}/
|
|
2190
|
+
const updatesUrl = `${apiUrl}/updates?sessionId=${encodeURIComponent(sessionId)}&projectId=${encodeURIComponent(projectId)}`;
|
|
2175
2191
|
const connectUpdates = () => {
|
|
2176
2192
|
if (updatesEventSourceRef.current) return;
|
|
2177
2193
|
const eventSource = new EventSource(updatesUrl);
|
|
@@ -2328,7 +2344,7 @@ function useHissunoChat({
|
|
|
2328
2344
|
inactivityTimerRef.current = null;
|
|
2329
2345
|
}
|
|
2330
2346
|
try {
|
|
2331
|
-
await fetch(`${apiUrl}/
|
|
2347
|
+
await fetch(`${apiUrl}/close`, {
|
|
2332
2348
|
method: "POST",
|
|
2333
2349
|
headers: {
|
|
2334
2350
|
"Content-Type": "application/json",
|
|
@@ -2343,7 +2359,7 @@ function useHissunoChat({
|
|
|
2343
2359
|
}, [sessionId, apiUrl, projectId, headers, onSessionClose]);
|
|
2344
2360
|
const cancelChat = (0, import_react4.useCallback)(async () => {
|
|
2345
2361
|
try {
|
|
2346
|
-
const cancelUrl = `${apiUrl}/cancel`;
|
|
2362
|
+
const cancelUrl = `${apiUrl}/stream/cancel`;
|
|
2347
2363
|
const response = await fetch(cancelUrl, {
|
|
2348
2364
|
method: "POST",
|
|
2349
2365
|
headers: {
|
|
@@ -2363,6 +2379,7 @@ function useHissunoChat({
|
|
|
2363
2379
|
eventSourceRef.current.close();
|
|
2364
2380
|
eventSourceRef.current = null;
|
|
2365
2381
|
}
|
|
2382
|
+
isConnectingRef.current = false;
|
|
2366
2383
|
setIsLoading(false);
|
|
2367
2384
|
setIsStreaming(false);
|
|
2368
2385
|
setStreamingContent("");
|
|
@@ -2389,7 +2406,7 @@ function useHissunoChat({
|
|
|
2389
2406
|
(0, import_react4.useEffect)(() => {
|
|
2390
2407
|
const handleBeforeUnload = () => {
|
|
2391
2408
|
if (!sessionId || sessionClosedRef.current) return;
|
|
2392
|
-
const url = `${apiUrl}/
|
|
2409
|
+
const url = `${apiUrl}/close`;
|
|
2393
2410
|
const data = JSON.stringify({ sessionId, projectId });
|
|
2394
2411
|
navigator.sendBeacon(url, data);
|
|
2395
2412
|
};
|
|
@@ -2437,7 +2454,8 @@ function useHissunoChat({
|
|
|
2437
2454
|
pageUrl,
|
|
2438
2455
|
pageTitle,
|
|
2439
2456
|
sessionId,
|
|
2440
|
-
widgetToken
|
|
2457
|
+
widgetToken,
|
|
2458
|
+
packageId
|
|
2441
2459
|
})
|
|
2442
2460
|
});
|
|
2443
2461
|
if (!response.ok) {
|
|
@@ -2455,7 +2473,7 @@ function useHissunoChat({
|
|
|
2455
2473
|
setIsLoading(false);
|
|
2456
2474
|
}
|
|
2457
2475
|
},
|
|
2458
|
-
[input, messages, apiUrl, headers, projectId, widgetToken, userId, userMetadata, pageUrl, pageTitle, sessionId, connectToStream]
|
|
2476
|
+
[input, messages, apiUrl, headers, projectId, widgetToken, userId, userMetadata, pageUrl, pageTitle, sessionId, packageId, connectToStream]
|
|
2459
2477
|
);
|
|
2460
2478
|
return (0, import_react4.useMemo)(
|
|
2461
2479
|
() => ({
|
|
@@ -2584,7 +2602,7 @@ function useResolvedTheme(theme) {
|
|
|
2584
2602
|
|
|
2585
2603
|
// src/HissunoWidget.tsx
|
|
2586
2604
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2587
|
-
var DEFAULT_API_URL = "/api/
|
|
2605
|
+
var DEFAULT_API_URL = "/api/integrations/widget/chat";
|
|
2588
2606
|
function HissunoWidget({
|
|
2589
2607
|
projectId,
|
|
2590
2608
|
widgetToken,
|
|
@@ -2608,6 +2626,7 @@ function HissunoWidget({
|
|
|
2608
2626
|
defaultOpen = false,
|
|
2609
2627
|
onOpen,
|
|
2610
2628
|
onClose,
|
|
2629
|
+
onControlsReady,
|
|
2611
2630
|
className,
|
|
2612
2631
|
headers = {}
|
|
2613
2632
|
}) {
|
|
@@ -2619,7 +2638,7 @@ function HissunoWidget({
|
|
|
2619
2638
|
blocked,
|
|
2620
2639
|
loading: settingsLoading,
|
|
2621
2640
|
error: settingsError
|
|
2622
|
-
} = useWidgetSettings(projectId || "", fetchDefaults && !!projectId, apiUrl, widgetToken);
|
|
2641
|
+
} = useWidgetSettings(projectId || "", fetchDefaults && !!projectId, apiUrl ?? DEFAULT_API_URL, widgetToken);
|
|
2623
2642
|
const resolveTrigger = () => {
|
|
2624
2643
|
if (propTrigger) return propTrigger;
|
|
2625
2644
|
if (renderTrigger) return "headless";
|
|
@@ -2666,6 +2685,9 @@ function HissunoWidget({
|
|
|
2666
2685
|
userId,
|
|
2667
2686
|
userMetadata
|
|
2668
2687
|
});
|
|
2688
|
+
(0, import_react7.useEffect)(() => {
|
|
2689
|
+
onControlsReady?.({ setInput });
|
|
2690
|
+
}, [onControlsReady, setInput]);
|
|
2669
2691
|
const canShowHistory = !!userId;
|
|
2670
2692
|
const handleOpenHistory = (0, import_react7.useCallback)(() => {
|
|
2671
2693
|
if (!canShowHistory) return;
|
|
@@ -2858,7 +2880,7 @@ function useWidgetSettings(projectId, enabled, apiUrl, widgetToken) {
|
|
|
2858
2880
|
}
|
|
2859
2881
|
setLoading(true);
|
|
2860
2882
|
setError(false);
|
|
2861
|
-
const settingsUrl = `${apiUrl.replace(/\/
|
|
2883
|
+
const settingsUrl = `${apiUrl.replace(/\/chat\/?$/, "")}?projectId=${encodeURIComponent(projectId)}`;
|
|
2862
2884
|
const controller = new AbortController();
|
|
2863
2885
|
fetch(settingsUrl, {
|
|
2864
2886
|
signal: controller.signal
|
package/dist/index.mjs
CHANGED
|
@@ -917,15 +917,15 @@ function ChatPopup({
|
|
|
917
917
|
},
|
|
918
918
|
children: [
|
|
919
919
|
/* @__PURE__ */ jsx6(
|
|
920
|
-
"
|
|
920
|
+
"textarea",
|
|
921
921
|
{
|
|
922
|
-
type: "text",
|
|
923
922
|
value: input,
|
|
924
923
|
onChange: (e) => setInput(e.target.value),
|
|
925
924
|
onKeyDown: handleKeyDown,
|
|
926
925
|
placeholder,
|
|
927
926
|
disabled: isLoading,
|
|
928
927
|
"aria-label": "Type your message",
|
|
928
|
+
rows: 1,
|
|
929
929
|
style: {
|
|
930
930
|
flex: 1,
|
|
931
931
|
padding: "10px 14px",
|
|
@@ -935,7 +935,12 @@ function ChatPopup({
|
|
|
935
935
|
color: textColor,
|
|
936
936
|
fontSize: 14,
|
|
937
937
|
outline: "none",
|
|
938
|
-
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
938
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
939
|
+
resize: "none",
|
|
940
|
+
minHeight: 40,
|
|
941
|
+
maxHeight: 120,
|
|
942
|
+
overflow: "auto",
|
|
943
|
+
lineHeight: "20px"
|
|
939
944
|
}
|
|
940
945
|
}
|
|
941
946
|
),
|
|
@@ -1059,7 +1064,7 @@ function ChatSidepanel({
|
|
|
1059
1064
|
position: "fixed",
|
|
1060
1065
|
top: 0,
|
|
1061
1066
|
right: 0,
|
|
1062
|
-
width:
|
|
1067
|
+
width: 480,
|
|
1063
1068
|
height: "100vh",
|
|
1064
1069
|
display: "flex",
|
|
1065
1070
|
flexDirection: "column",
|
|
@@ -1215,15 +1220,15 @@ function ChatSidepanel({
|
|
|
1215
1220
|
},
|
|
1216
1221
|
children: [
|
|
1217
1222
|
/* @__PURE__ */ jsx7(
|
|
1218
|
-
"
|
|
1223
|
+
"textarea",
|
|
1219
1224
|
{
|
|
1220
|
-
type: "text",
|
|
1221
1225
|
value: input,
|
|
1222
1226
|
onChange: (e) => setInput(e.target.value),
|
|
1223
1227
|
onKeyDown: handleKeyDown,
|
|
1224
1228
|
placeholder,
|
|
1225
1229
|
disabled: isLoading,
|
|
1226
1230
|
"aria-label": "Type your message",
|
|
1231
|
+
rows: 1,
|
|
1227
1232
|
style: {
|
|
1228
1233
|
flex: 1,
|
|
1229
1234
|
padding: "10px 14px",
|
|
@@ -1233,7 +1238,12 @@ function ChatSidepanel({
|
|
|
1233
1238
|
color: textColor,
|
|
1234
1239
|
fontSize: 14,
|
|
1235
1240
|
outline: "none",
|
|
1236
|
-
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
1241
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1242
|
+
resize: "none",
|
|
1243
|
+
minHeight: 40,
|
|
1244
|
+
maxHeight: 120,
|
|
1245
|
+
overflow: "auto",
|
|
1246
|
+
lineHeight: "20px"
|
|
1237
1247
|
}
|
|
1238
1248
|
}
|
|
1239
1249
|
),
|
|
@@ -1598,9 +1608,8 @@ function ChatDialog({
|
|
|
1598
1608
|
},
|
|
1599
1609
|
children: [
|
|
1600
1610
|
/* @__PURE__ */ jsx8(
|
|
1601
|
-
"
|
|
1611
|
+
"textarea",
|
|
1602
1612
|
{
|
|
1603
|
-
type: "text",
|
|
1604
1613
|
value: input,
|
|
1605
1614
|
onChange: (e) => setInput(e.target.value),
|
|
1606
1615
|
onKeyDown: handleKeyDown,
|
|
@@ -1608,6 +1617,7 @@ function ChatDialog({
|
|
|
1608
1617
|
disabled: isLoading,
|
|
1609
1618
|
autoFocus: true,
|
|
1610
1619
|
"aria-label": "Type your message",
|
|
1620
|
+
rows: 1,
|
|
1611
1621
|
style: {
|
|
1612
1622
|
flex: 1,
|
|
1613
1623
|
padding: "12px 16px",
|
|
@@ -1617,7 +1627,12 @@ function ChatDialog({
|
|
|
1617
1627
|
color: textColor,
|
|
1618
1628
|
fontSize: 14,
|
|
1619
1629
|
outline: "none",
|
|
1620
|
-
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
1630
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1631
|
+
resize: "none",
|
|
1632
|
+
minHeight: 44,
|
|
1633
|
+
maxHeight: 120,
|
|
1634
|
+
overflow: "auto",
|
|
1635
|
+
lineHeight: "20px"
|
|
1621
1636
|
}
|
|
1622
1637
|
}
|
|
1623
1638
|
),
|
|
@@ -1972,12 +1987,13 @@ function deleteSessionFromRegistry(projectId, userId, sessionId) {
|
|
|
1972
1987
|
function useHissunoChat({
|
|
1973
1988
|
projectId,
|
|
1974
1989
|
widgetToken,
|
|
1975
|
-
apiUrl = "/api/
|
|
1990
|
+
apiUrl = "/api/integrations/widget/chat",
|
|
1976
1991
|
initialMessage,
|
|
1977
1992
|
headers = {},
|
|
1978
1993
|
userId,
|
|
1979
1994
|
userMetadata,
|
|
1980
1995
|
sessionId: providedSessionId,
|
|
1996
|
+
packageId,
|
|
1981
1997
|
inactivityTimeout = DEFAULT_INACTIVITY_TIMEOUT,
|
|
1982
1998
|
onSessionClose
|
|
1983
1999
|
}) {
|
|
@@ -2131,7 +2147,7 @@ function useHissunoChat({
|
|
|
2131
2147
|
}, [apiUrl, projectId, sessionId, connectToStream]);
|
|
2132
2148
|
useEffect4(() => {
|
|
2133
2149
|
if (sessionClosedRef.current || !sessionId) return;
|
|
2134
|
-
const updatesUrl = `${apiUrl}/
|
|
2150
|
+
const updatesUrl = `${apiUrl}/updates?sessionId=${encodeURIComponent(sessionId)}&projectId=${encodeURIComponent(projectId)}`;
|
|
2135
2151
|
const connectUpdates = () => {
|
|
2136
2152
|
if (updatesEventSourceRef.current) return;
|
|
2137
2153
|
const eventSource = new EventSource(updatesUrl);
|
|
@@ -2288,7 +2304,7 @@ function useHissunoChat({
|
|
|
2288
2304
|
inactivityTimerRef.current = null;
|
|
2289
2305
|
}
|
|
2290
2306
|
try {
|
|
2291
|
-
await fetch(`${apiUrl}/
|
|
2307
|
+
await fetch(`${apiUrl}/close`, {
|
|
2292
2308
|
method: "POST",
|
|
2293
2309
|
headers: {
|
|
2294
2310
|
"Content-Type": "application/json",
|
|
@@ -2303,7 +2319,7 @@ function useHissunoChat({
|
|
|
2303
2319
|
}, [sessionId, apiUrl, projectId, headers, onSessionClose]);
|
|
2304
2320
|
const cancelChat = useCallback3(async () => {
|
|
2305
2321
|
try {
|
|
2306
|
-
const cancelUrl = `${apiUrl}/cancel`;
|
|
2322
|
+
const cancelUrl = `${apiUrl}/stream/cancel`;
|
|
2307
2323
|
const response = await fetch(cancelUrl, {
|
|
2308
2324
|
method: "POST",
|
|
2309
2325
|
headers: {
|
|
@@ -2323,6 +2339,7 @@ function useHissunoChat({
|
|
|
2323
2339
|
eventSourceRef.current.close();
|
|
2324
2340
|
eventSourceRef.current = null;
|
|
2325
2341
|
}
|
|
2342
|
+
isConnectingRef.current = false;
|
|
2326
2343
|
setIsLoading(false);
|
|
2327
2344
|
setIsStreaming(false);
|
|
2328
2345
|
setStreamingContent("");
|
|
@@ -2349,7 +2366,7 @@ function useHissunoChat({
|
|
|
2349
2366
|
useEffect4(() => {
|
|
2350
2367
|
const handleBeforeUnload = () => {
|
|
2351
2368
|
if (!sessionId || sessionClosedRef.current) return;
|
|
2352
|
-
const url = `${apiUrl}/
|
|
2369
|
+
const url = `${apiUrl}/close`;
|
|
2353
2370
|
const data = JSON.stringify({ sessionId, projectId });
|
|
2354
2371
|
navigator.sendBeacon(url, data);
|
|
2355
2372
|
};
|
|
@@ -2397,7 +2414,8 @@ function useHissunoChat({
|
|
|
2397
2414
|
pageUrl,
|
|
2398
2415
|
pageTitle,
|
|
2399
2416
|
sessionId,
|
|
2400
|
-
widgetToken
|
|
2417
|
+
widgetToken,
|
|
2418
|
+
packageId
|
|
2401
2419
|
})
|
|
2402
2420
|
});
|
|
2403
2421
|
if (!response.ok) {
|
|
@@ -2415,7 +2433,7 @@ function useHissunoChat({
|
|
|
2415
2433
|
setIsLoading(false);
|
|
2416
2434
|
}
|
|
2417
2435
|
},
|
|
2418
|
-
[input, messages, apiUrl, headers, projectId, widgetToken, userId, userMetadata, pageUrl, pageTitle, sessionId, connectToStream]
|
|
2436
|
+
[input, messages, apiUrl, headers, projectId, widgetToken, userId, userMetadata, pageUrl, pageTitle, sessionId, packageId, connectToStream]
|
|
2419
2437
|
);
|
|
2420
2438
|
return useMemo(
|
|
2421
2439
|
() => ({
|
|
@@ -2544,7 +2562,7 @@ function useResolvedTheme(theme) {
|
|
|
2544
2562
|
|
|
2545
2563
|
// src/HissunoWidget.tsx
|
|
2546
2564
|
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2547
|
-
var DEFAULT_API_URL = "/api/
|
|
2565
|
+
var DEFAULT_API_URL = "/api/integrations/widget/chat";
|
|
2548
2566
|
function HissunoWidget({
|
|
2549
2567
|
projectId,
|
|
2550
2568
|
widgetToken,
|
|
@@ -2568,6 +2586,7 @@ function HissunoWidget({
|
|
|
2568
2586
|
defaultOpen = false,
|
|
2569
2587
|
onOpen,
|
|
2570
2588
|
onClose,
|
|
2589
|
+
onControlsReady,
|
|
2571
2590
|
className,
|
|
2572
2591
|
headers = {}
|
|
2573
2592
|
}) {
|
|
@@ -2579,7 +2598,7 @@ function HissunoWidget({
|
|
|
2579
2598
|
blocked,
|
|
2580
2599
|
loading: settingsLoading,
|
|
2581
2600
|
error: settingsError
|
|
2582
|
-
} = useWidgetSettings(projectId || "", fetchDefaults && !!projectId, apiUrl, widgetToken);
|
|
2601
|
+
} = useWidgetSettings(projectId || "", fetchDefaults && !!projectId, apiUrl ?? DEFAULT_API_URL, widgetToken);
|
|
2583
2602
|
const resolveTrigger = () => {
|
|
2584
2603
|
if (propTrigger) return propTrigger;
|
|
2585
2604
|
if (renderTrigger) return "headless";
|
|
@@ -2626,6 +2645,9 @@ function HissunoWidget({
|
|
|
2626
2645
|
userId,
|
|
2627
2646
|
userMetadata
|
|
2628
2647
|
});
|
|
2648
|
+
useEffect7(() => {
|
|
2649
|
+
onControlsReady?.({ setInput });
|
|
2650
|
+
}, [onControlsReady, setInput]);
|
|
2629
2651
|
const canShowHistory = !!userId;
|
|
2630
2652
|
const handleOpenHistory = useCallback5(() => {
|
|
2631
2653
|
if (!canShowHistory) return;
|
|
@@ -2818,7 +2840,7 @@ function useWidgetSettings(projectId, enabled, apiUrl, widgetToken) {
|
|
|
2818
2840
|
}
|
|
2819
2841
|
setLoading(true);
|
|
2820
2842
|
setError(false);
|
|
2821
|
-
const settingsUrl = `${apiUrl.replace(/\/
|
|
2843
|
+
const settingsUrl = `${apiUrl.replace(/\/chat\/?$/, "")}?projectId=${encodeURIComponent(projectId)}`;
|
|
2822
2844
|
const controller = new AbortController();
|
|
2823
2845
|
fetch(settingsUrl, {
|
|
2824
2846
|
signal: controller.signal
|
package/dist/styles.css
CHANGED
|
@@ -105,27 +105,14 @@
|
|
|
105
105
|
animation: hissuno-fade-in-backdrop 0.2s ease-out;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
/* Messages container */
|
|
108
|
+
/* Messages container - hide scrollbar but keep scrolling */
|
|
109
109
|
.hissuno-messages {
|
|
110
|
-
scrollbar-width:
|
|
111
|
-
|
|
110
|
+
scrollbar-width: none; /* Firefox */
|
|
111
|
+
-ms-overflow-style: none; /* IE and Edge */
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
.hissuno-messages::-webkit-scrollbar {
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.hissuno-messages::-webkit-scrollbar-track {
|
|
119
|
-
background: transparent;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
.hissuno-messages::-webkit-scrollbar-thumb {
|
|
123
|
-
background-color: rgba(155, 155, 155, 0.5);
|
|
124
|
-
border-radius: 3px;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
.hissuno-messages::-webkit-scrollbar-thumb:hover {
|
|
128
|
-
background-color: rgba(155, 155, 155, 0.7);
|
|
115
|
+
display: none; /* Chrome, Safari, Opera */
|
|
129
116
|
}
|
|
130
117
|
|
|
131
118
|
/* Loading dots animation */
|