@channlize/react 0.3.0 → 0.5.0
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/CHANGELOG.md +29 -0
- package/README.md +20 -3
- package/dist/index.d.mts +10 -6
- package/dist/index.d.ts +10 -6
- package/dist/index.js +77 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +86 -42
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @channlize/react
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [b9d54a0]
|
|
8
|
+
- Updated dependencies [7815276]
|
|
9
|
+
- @channlize/core@0.5.0
|
|
10
|
+
|
|
11
|
+
## 0.4.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- Release every `@channlize/*` package under one shared version. From 0.4.0 on, core, react, mcp and skills always publish together at the same version, so matching versions work together.
|
|
16
|
+
- 7b82215: Add a `debug` option to `useChatSession` and `SupportChat` (also through `ChannlizeChat`'s `chatProps`). The chat no longer writes to the console unless `debug` is on; it used to log every session step and SSE message. `ChannlizeProvider` keeps one client per configuration instead of creating one on every render, the chat calls the latest `onMessage` / `onError` without reopening the stream, and `UseContactFormOptions`, `UseContactFormReturn` and `ChannlizeProviderProps` are exported.
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 5663cd2: Make `@channlize/core` the single source for what the packages share.
|
|
21
|
+
|
|
22
|
+
- core exports `DEFAULT_BASE_URL`, `DEFAULT_TIMEOUT`, `EVENT_SEVERITIES`, `EVENT_KEY_PATTERN`, `isValidEventKey`, `keyKind` (widget vs. server key), `readChannlizeEnv` (the `CHANNLIZE_*` variables) and `parseApiError` (the API's error shape). `createNotifier`, the client and `@channlize/mcp` use them instead of their own copies.
|
|
23
|
+
- `ChannlizeError` gains `requestId` and `details` (the API's error body, e.g. `limit`, `used` and `resetAt` on a plan-limit 429). When a legacy route puts its human-readable text in `error`, it becomes the message instead of `HTTP <status>`.
|
|
24
|
+
- The chat types document where the API differs from them (ISO string timestamps, session summaries without `messages`).
|
|
25
|
+
- `@channlize/react` and `@channlize/mcp` re-export the error classes as values, so `instanceof` works without importing core.
|
|
26
|
+
- mcp tool errors no longer end with a doubled period when a core error message ends with one.
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [5663cd2]
|
|
29
|
+
- Updated dependencies
|
|
30
|
+
- @channlize/core@0.4.0
|
|
31
|
+
|
|
3
32
|
## 0.3.0
|
|
4
33
|
|
|
5
34
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ function App() {
|
|
|
61
61
|
return (
|
|
62
62
|
<ChannlizeProvider
|
|
63
63
|
config={{
|
|
64
|
-
apiKey: 'your-
|
|
64
|
+
apiKey: 'your-widget-key',
|
|
65
65
|
projectId: 'your-project-id',
|
|
66
66
|
}}
|
|
67
67
|
>
|
|
@@ -71,6 +71,8 @@ function App() {
|
|
|
71
71
|
}
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
`ContactForm`, `SupportChat` and the hooks below must be rendered inside `ChannlizeProvider` (`ChannlizeChat` includes it).
|
|
75
|
+
|
|
74
76
|
### Contact Form Component
|
|
75
77
|
|
|
76
78
|
```tsx
|
|
@@ -113,7 +115,7 @@ import { SupportChat } from '@channlize/react';
|
|
|
113
115
|
function SupportPage() {
|
|
114
116
|
return (
|
|
115
117
|
<SupportChat
|
|
116
|
-
|
|
118
|
+
autoConnect={true}
|
|
117
119
|
title="Customer Support"
|
|
118
120
|
placeholder="How can we help you?"
|
|
119
121
|
onMessage={(message) => {
|
|
@@ -158,7 +160,7 @@ function CustomContactForm() {
|
|
|
158
160
|
await submit({
|
|
159
161
|
name: 'John Doe',
|
|
160
162
|
email: 'john@example.com',
|
|
161
|
-
message: 'Hello
|
|
163
|
+
message: 'Hello, I have a question about pricing.', // at least 10 characters
|
|
162
164
|
});
|
|
163
165
|
};
|
|
164
166
|
|
|
@@ -397,6 +399,8 @@ its parent, so give the parent a height.
|
|
|
397
399
|
- `metadata?: Record<string, unknown>` - Session metadata
|
|
398
400
|
- `onMessage?: (message: ChatMessage) => void` - New message callback
|
|
399
401
|
- `onError?: (error: Error) => void` - Error callback
|
|
402
|
+
- `sessionId?: string`, `persistSession?: boolean` (default `true`), `storageKey?: string` - Resume a session, and where its id is kept in `localStorage`
|
|
403
|
+
- `debug?: boolean` - Log connection and session details to the console (default `false`)
|
|
400
404
|
- `className?: string` - CSS class name
|
|
401
405
|
- `styles?` - Inline style overrides: `container`, `header`, `messagesContainer`, `message`, `userMessage`, `agentMessage`, `inputContainer`, `input`, `button`, `error`, `timestamp`
|
|
402
406
|
- `title?: string` - Team or brand name in the header (default `'Support'`)
|
|
@@ -443,6 +447,10 @@ Hook for managing chat sessions with real-time messaging.
|
|
|
443
447
|
- `metadata?: Record<string, unknown>`
|
|
444
448
|
- `onMessage?: (message: ChatMessage) => void`
|
|
445
449
|
- `onError?: (error: ChannlizeError) => void`
|
|
450
|
+
- `sessionId?: string` - Resume this session instead of the stored one
|
|
451
|
+
- `persistSession?: boolean` - Keep the session id in `localStorage` so a reload resumes it (default `true`)
|
|
452
|
+
- `storageKey?: string` - `localStorage` key (default `channlize_session_<widget key>`)
|
|
453
|
+
- `debug?: boolean` - Log connection and session details to the console with a `[channlize]` prefix (default `false`). Failures are always reported through `error` and `onError`.
|
|
446
454
|
|
|
447
455
|
**Returns:**
|
|
448
456
|
- `session: ChatSession | null`
|
|
@@ -491,6 +499,15 @@ The chat widget ships its own small stylesheet, scoped under `.channlize-widget`
|
|
|
491
499
|
|
|
492
500
|
This package is written in TypeScript and includes full type definitions. All components, hooks, and utilities are fully typed.
|
|
493
501
|
|
|
502
|
+
## Documentation
|
|
503
|
+
|
|
504
|
+
- Guide: https://channlize.com/docs/react
|
|
505
|
+
- All docs: https://channlize.com/docs (quick start, API keys, troubleshooting)
|
|
506
|
+
|
|
507
|
+
## Changelog
|
|
508
|
+
|
|
509
|
+
[CHANGELOG.md](./CHANGELOG.md) lists every release of `@channlize/react`. Product updates: https://channlize.com/docs/changelog
|
|
510
|
+
|
|
494
511
|
## License
|
|
495
512
|
|
|
496
513
|
MIT
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, CSSProperties } from 'react';
|
|
3
|
+
import * as _channlize_core from '@channlize/core';
|
|
3
4
|
import { ChannlizeConfig, ChannlizeClient, CreateContactResponse, ChannlizeError, ContactFormData, ChatMessage, ChatSession, TrackEventOptions } from '@channlize/core';
|
|
4
5
|
export { AuthenticationError, ChannlizeConfig, ChannlizeError, ChatMessage, ChatSession, ContactFormData, CreateChatSessionResponse, CreateContactResponse, EventSeverity, FileAttachment, RateLimitError, SendMessageResponse, TrackEventOptions, ValidationError } from '@channlize/core';
|
|
5
6
|
|
|
@@ -44,6 +45,12 @@ interface UseChatSessionOptions {
|
|
|
44
45
|
sessionId?: string;
|
|
45
46
|
persistSession?: boolean;
|
|
46
47
|
storageKey?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Log connection and session details to the console (`[channlize]`
|
|
50
|
+
* prefix). Off by default; failures are always reported through `error`
|
|
51
|
+
* and `onError`.
|
|
52
|
+
*/
|
|
53
|
+
debug?: boolean;
|
|
47
54
|
}
|
|
48
55
|
interface UseChatSessionReturn {
|
|
49
56
|
session: ChatSession | null;
|
|
@@ -72,10 +79,7 @@ declare function useChatSession(options?: UseChatSessionOptions): UseChatSession
|
|
|
72
79
|
* (`notify` from `@channlize/core`) on your server instead.
|
|
73
80
|
*/
|
|
74
81
|
declare function useChannlizeAnalytics(): {
|
|
75
|
-
track: (name: string, options?: TrackEventOptions) => Promise<
|
|
76
|
-
success: boolean;
|
|
77
|
-
id: string;
|
|
78
|
-
}>;
|
|
82
|
+
track: (name: string, options?: TrackEventOptions) => Promise<_channlize_core.TrackEventResult>;
|
|
79
83
|
};
|
|
80
84
|
|
|
81
85
|
/** `auto` and `system` both follow `prefers-color-scheme`. */
|
|
@@ -314,7 +318,7 @@ interface SupportChatProps extends UseChatSessionOptions {
|
|
|
314
318
|
* SupportChat component - Real-time chat interface
|
|
315
319
|
* Provides a complete chat UI with message history and real-time updates
|
|
316
320
|
*/
|
|
317
|
-
declare function SupportChat({ autoConnect, metadata, onMessage, onError, sessionId, persistSession, storageKey, className, styles, placeholder, title, sendButtonText, showTimestamps, allowAttachments, avatarUrl, avatar, statusText, greeting, welcomeMessage, suggestions, theme, primaryColor, primaryTextColor, locale, maxLength, allowEndChat, onMinimize, labels: labelOverrides, }: SupportChatProps): react.JSX.Element;
|
|
321
|
+
declare function SupportChat({ autoConnect, metadata, onMessage, onError, sessionId, persistSession, storageKey, debug, className, styles, placeholder, title, sendButtonText, showTimestamps, allowAttachments, avatarUrl, avatar, statusText, greeting, welcomeMessage, suggestions, theme, primaryColor, primaryTextColor, locale, maxLength, allowEndChat, onMinimize, labels: labelOverrides, }: SupportChatProps): react.JSX.Element;
|
|
318
322
|
|
|
319
323
|
interface ChannlizeChatProps {
|
|
320
324
|
/** Channlize configuration */
|
|
@@ -394,4 +398,4 @@ interface ChannlizeChatProps {
|
|
|
394
398
|
declare function ChannlizeChat({ config, position, offset, buttonElement, buttonIcon, buttonSize, buttonColors, chatProps, primaryColor, theme, defaultOpen, showBadge, unreadCount, zIndex, showOnMobile, onOpen, onClose, enableAnimations, buttonClassName, chatClassName, }: ChannlizeChatProps): react.JSX.Element | null;
|
|
395
399
|
|
|
396
400
|
export { ChannlizeChat, ChannlizeProvider, ContactForm, SupportChat, defaultContactFormLabels, defaultSupportChatLabels, useChannlize, useChannlizeAnalytics, useChatSession, useContactForm };
|
|
397
|
-
export type { ChannlizeChatProps, ChatTheme, ContactFieldMode, ContactFormCustomField, ContactFormLabels, ContactFormProps, ContactFormTheme, ContactFormTopic, ContactFormValues, SupportChatLabels, SupportChatProps, UseChatSessionOptions, UseChatSessionReturn };
|
|
401
|
+
export type { ChannlizeChatProps, ChannlizeProviderProps, ChatTheme, ContactFieldMode, ContactFormCustomField, ContactFormLabels, ContactFormProps, ContactFormTheme, ContactFormTopic, ContactFormValues, SupportChatLabels, SupportChatProps, UseChatSessionOptions, UseChatSessionReturn, UseContactFormOptions, UseContactFormReturn };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, CSSProperties } from 'react';
|
|
3
|
+
import * as _channlize_core from '@channlize/core';
|
|
3
4
|
import { ChannlizeConfig, ChannlizeClient, CreateContactResponse, ChannlizeError, ContactFormData, ChatMessage, ChatSession, TrackEventOptions } from '@channlize/core';
|
|
4
5
|
export { AuthenticationError, ChannlizeConfig, ChannlizeError, ChatMessage, ChatSession, ContactFormData, CreateChatSessionResponse, CreateContactResponse, EventSeverity, FileAttachment, RateLimitError, SendMessageResponse, TrackEventOptions, ValidationError } from '@channlize/core';
|
|
5
6
|
|
|
@@ -44,6 +45,12 @@ interface UseChatSessionOptions {
|
|
|
44
45
|
sessionId?: string;
|
|
45
46
|
persistSession?: boolean;
|
|
46
47
|
storageKey?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Log connection and session details to the console (`[channlize]`
|
|
50
|
+
* prefix). Off by default; failures are always reported through `error`
|
|
51
|
+
* and `onError`.
|
|
52
|
+
*/
|
|
53
|
+
debug?: boolean;
|
|
47
54
|
}
|
|
48
55
|
interface UseChatSessionReturn {
|
|
49
56
|
session: ChatSession | null;
|
|
@@ -72,10 +79,7 @@ declare function useChatSession(options?: UseChatSessionOptions): UseChatSession
|
|
|
72
79
|
* (`notify` from `@channlize/core`) on your server instead.
|
|
73
80
|
*/
|
|
74
81
|
declare function useChannlizeAnalytics(): {
|
|
75
|
-
track: (name: string, options?: TrackEventOptions) => Promise<
|
|
76
|
-
success: boolean;
|
|
77
|
-
id: string;
|
|
78
|
-
}>;
|
|
82
|
+
track: (name: string, options?: TrackEventOptions) => Promise<_channlize_core.TrackEventResult>;
|
|
79
83
|
};
|
|
80
84
|
|
|
81
85
|
/** `auto` and `system` both follow `prefers-color-scheme`. */
|
|
@@ -314,7 +318,7 @@ interface SupportChatProps extends UseChatSessionOptions {
|
|
|
314
318
|
* SupportChat component - Real-time chat interface
|
|
315
319
|
* Provides a complete chat UI with message history and real-time updates
|
|
316
320
|
*/
|
|
317
|
-
declare function SupportChat({ autoConnect, metadata, onMessage, onError, sessionId, persistSession, storageKey, className, styles, placeholder, title, sendButtonText, showTimestamps, allowAttachments, avatarUrl, avatar, statusText, greeting, welcomeMessage, suggestions, theme, primaryColor, primaryTextColor, locale, maxLength, allowEndChat, onMinimize, labels: labelOverrides, }: SupportChatProps): react.JSX.Element;
|
|
321
|
+
declare function SupportChat({ autoConnect, metadata, onMessage, onError, sessionId, persistSession, storageKey, debug, className, styles, placeholder, title, sendButtonText, showTimestamps, allowAttachments, avatarUrl, avatar, statusText, greeting, welcomeMessage, suggestions, theme, primaryColor, primaryTextColor, locale, maxLength, allowEndChat, onMinimize, labels: labelOverrides, }: SupportChatProps): react.JSX.Element;
|
|
318
322
|
|
|
319
323
|
interface ChannlizeChatProps {
|
|
320
324
|
/** Channlize configuration */
|
|
@@ -394,4 +398,4 @@ interface ChannlizeChatProps {
|
|
|
394
398
|
declare function ChannlizeChat({ config, position, offset, buttonElement, buttonIcon, buttonSize, buttonColors, chatProps, primaryColor, theme, defaultOpen, showBadge, unreadCount, zIndex, showOnMobile, onOpen, onClose, enableAnimations, buttonClassName, chatClassName, }: ChannlizeChatProps): react.JSX.Element | null;
|
|
395
399
|
|
|
396
400
|
export { ChannlizeChat, ChannlizeProvider, ContactForm, SupportChat, defaultContactFormLabels, defaultSupportChatLabels, useChannlize, useChannlizeAnalytics, useChatSession, useContactForm };
|
|
397
|
-
export type { ChannlizeChatProps, ChatTheme, ContactFieldMode, ContactFormCustomField, ContactFormLabels, ContactFormProps, ContactFormTheme, ContactFormTopic, ContactFormValues, SupportChatLabels, SupportChatProps, UseChatSessionOptions, UseChatSessionReturn };
|
|
401
|
+
export type { ChannlizeChatProps, ChannlizeProviderProps, ChatTheme, ContactFieldMode, ContactFormCustomField, ContactFormLabels, ContactFormProps, ContactFormTheme, ContactFormTopic, ContactFormValues, SupportChatLabels, SupportChatProps, UseChatSessionOptions, UseChatSessionReturn, UseContactFormOptions, UseContactFormReturn };
|
package/dist/index.js
CHANGED
|
@@ -20,10 +20,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
AuthenticationError: () => import_core4.AuthenticationError,
|
|
23
24
|
ChannlizeChat: () => ChannlizeChat,
|
|
25
|
+
ChannlizeError: () => import_core4.ChannlizeError,
|
|
24
26
|
ChannlizeProvider: () => ChannlizeProvider,
|
|
25
27
|
ContactForm: () => ContactForm,
|
|
28
|
+
RateLimitError: () => import_core4.RateLimitError,
|
|
26
29
|
SupportChat: () => SupportChat,
|
|
30
|
+
ValidationError: () => import_core4.ValidationError,
|
|
27
31
|
defaultContactFormLabels: () => defaultContactFormLabels,
|
|
28
32
|
defaultSupportChatLabels: () => defaultSupportChatLabels,
|
|
29
33
|
useChannlize: () => useChannlize,
|
|
@@ -42,8 +46,19 @@ function ChannlizeProvider({
|
|
|
42
46
|
config,
|
|
43
47
|
children
|
|
44
48
|
}) {
|
|
45
|
-
const
|
|
46
|
-
|
|
49
|
+
const { apiKey, baseUrl, projectId, timeout, serverApiKey } = config;
|
|
50
|
+
const client = (0, import_react.useMemo)(
|
|
51
|
+
() => new import_core.ChannlizeClient({
|
|
52
|
+
apiKey,
|
|
53
|
+
baseUrl,
|
|
54
|
+
projectId,
|
|
55
|
+
timeout,
|
|
56
|
+
serverApiKey
|
|
57
|
+
}),
|
|
58
|
+
[apiKey, baseUrl, projectId, timeout, serverApiKey]
|
|
59
|
+
);
|
|
60
|
+
const value = (0, import_react.useMemo)(() => ({ client, config }), [client, config]);
|
|
61
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChannlizeContext.Provider, { value, children });
|
|
47
62
|
}
|
|
48
63
|
function useChannlize() {
|
|
49
64
|
const context = (0, import_react.useContext)(ChannlizeContext);
|
|
@@ -95,6 +110,7 @@ function useContactForm(options = {}) {
|
|
|
95
110
|
|
|
96
111
|
// src/hooks/useChatSession.ts
|
|
97
112
|
var import_react3 = require("react");
|
|
113
|
+
var import_core2 = require("@channlize/core");
|
|
98
114
|
function useChatSession(options = {}) {
|
|
99
115
|
const { client, config } = useChannlize();
|
|
100
116
|
const [session, setSession] = (0, import_react3.useState)(null);
|
|
@@ -105,9 +121,27 @@ function useChatSession(options = {}) {
|
|
|
105
121
|
const eventSourceRef = (0, import_react3.useRef)(null);
|
|
106
122
|
const sessionRef = (0, import_react3.useRef)(null);
|
|
107
123
|
const isInitializedRef = (0, import_react3.useRef)(false);
|
|
108
|
-
const baseUrl = config.baseUrl ||
|
|
124
|
+
const baseUrl = config.baseUrl || import_core2.DEFAULT_BASE_URL;
|
|
109
125
|
const storageKey = options.storageKey || `channlize_session_${config.apiKey}`;
|
|
110
126
|
const persistSession = options.persistSession ?? true;
|
|
127
|
+
const latest = (0, import_react3.useRef)({
|
|
128
|
+
onMessage: options.onMessage,
|
|
129
|
+
onError: options.onError,
|
|
130
|
+
debug: options.debug
|
|
131
|
+
});
|
|
132
|
+
(0, import_react3.useEffect)(() => {
|
|
133
|
+
latest.current = {
|
|
134
|
+
onMessage: options.onMessage,
|
|
135
|
+
onError: options.onError,
|
|
136
|
+
debug: options.debug
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
const log = (0, import_react3.useCallback)(
|
|
140
|
+
(level, ...args) => {
|
|
141
|
+
if (latest.current.debug) console[level]("[channlize]", ...args);
|
|
142
|
+
},
|
|
143
|
+
[]
|
|
144
|
+
);
|
|
111
145
|
(0, import_react3.useEffect)(() => {
|
|
112
146
|
sessionRef.current = session;
|
|
113
147
|
}, [session]);
|
|
@@ -117,51 +151,50 @@ function useChatSession(options = {}) {
|
|
|
117
151
|
try {
|
|
118
152
|
localStorage.setItem(storageKey, sessionId);
|
|
119
153
|
} catch (err) {
|
|
120
|
-
|
|
154
|
+
log("warn", "Failed to save session to localStorage:", err);
|
|
121
155
|
}
|
|
122
156
|
}
|
|
123
157
|
},
|
|
124
|
-
[persistSession, storageKey]
|
|
158
|
+
[persistSession, storageKey, log]
|
|
125
159
|
);
|
|
126
160
|
const getSessionFromStorage = (0, import_react3.useCallback)(() => {
|
|
127
161
|
if (persistSession && typeof window !== "undefined") {
|
|
128
162
|
try {
|
|
129
163
|
return localStorage.getItem(storageKey);
|
|
130
164
|
} catch (err) {
|
|
131
|
-
|
|
165
|
+
log("warn", "Failed to get session from localStorage:", err);
|
|
132
166
|
}
|
|
133
167
|
}
|
|
134
168
|
return null;
|
|
135
|
-
}, [persistSession, storageKey]);
|
|
169
|
+
}, [persistSession, storageKey, log]);
|
|
136
170
|
const clearSessionFromStorage = (0, import_react3.useCallback)(() => {
|
|
137
171
|
if (persistSession && typeof window !== "undefined") {
|
|
138
172
|
try {
|
|
139
173
|
localStorage.removeItem(storageKey);
|
|
140
174
|
} catch (err) {
|
|
141
|
-
|
|
175
|
+
log("warn", "Failed to clear session from localStorage:", err);
|
|
142
176
|
}
|
|
143
177
|
}
|
|
144
|
-
}, [persistSession, storageKey]);
|
|
178
|
+
}, [persistSession, storageKey, log]);
|
|
145
179
|
const connectToSSE = (0, import_react3.useCallback)(
|
|
146
180
|
(sseEndpoint) => {
|
|
147
181
|
if (eventSourceRef.current) {
|
|
148
182
|
eventSourceRef.current.close();
|
|
149
183
|
}
|
|
150
184
|
const fullUrl = sseEndpoint.startsWith("http") ? sseEndpoint : `${baseUrl}${sseEndpoint}`;
|
|
151
|
-
|
|
185
|
+
log("log", "SSE connecting to", fullUrl);
|
|
152
186
|
const eventSource = new EventSource(fullUrl);
|
|
153
187
|
eventSourceRef.current = eventSource;
|
|
154
188
|
eventSource.onopen = () => {
|
|
155
|
-
|
|
189
|
+
log("log", "SSE connection opened");
|
|
156
190
|
setIsConnected(true);
|
|
157
191
|
setError(null);
|
|
158
192
|
};
|
|
159
193
|
eventSource.addEventListener("connected", (event) => {
|
|
160
|
-
|
|
194
|
+
log("log", "SSE connected:", event.data);
|
|
161
195
|
});
|
|
162
196
|
eventSource.addEventListener("message", (event) => {
|
|
163
197
|
try {
|
|
164
|
-
console.log("SSE message:", event.data);
|
|
165
198
|
const message = JSON.parse(event.data);
|
|
166
199
|
const chatMessage = {
|
|
167
200
|
...message,
|
|
@@ -171,9 +204,9 @@ function useChatSession(options = {}) {
|
|
|
171
204
|
const exists = prev.some((m) => m.id === chatMessage.id);
|
|
172
205
|
return exists ? prev : [...prev, chatMessage];
|
|
173
206
|
});
|
|
174
|
-
|
|
207
|
+
latest.current.onMessage?.(chatMessage);
|
|
175
208
|
} catch (err) {
|
|
176
|
-
|
|
209
|
+
log("warn", "Failed to parse SSE message:", err, event.data);
|
|
177
210
|
}
|
|
178
211
|
});
|
|
179
212
|
eventSource.onmessage = (event) => {
|
|
@@ -188,10 +221,10 @@ function useChatSession(options = {}) {
|
|
|
188
221
|
const exists = prev.some((m) => m.id === message.id);
|
|
189
222
|
return exists ? prev : [...prev, message];
|
|
190
223
|
});
|
|
191
|
-
|
|
224
|
+
latest.current.onMessage?.(message);
|
|
192
225
|
}
|
|
193
226
|
} catch (err) {
|
|
194
|
-
|
|
227
|
+
log("warn", "Failed to parse default SSE message:", err);
|
|
195
228
|
}
|
|
196
229
|
};
|
|
197
230
|
eventSource.onerror = (event) => {
|
|
@@ -199,7 +232,7 @@ function useChatSession(options = {}) {
|
|
|
199
232
|
setIsConnected(false);
|
|
200
233
|
return;
|
|
201
234
|
}
|
|
202
|
-
|
|
235
|
+
log("error", "SSE connection error", {
|
|
203
236
|
readyState: eventSource.readyState,
|
|
204
237
|
url: fullUrl,
|
|
205
238
|
event
|
|
@@ -211,10 +244,10 @@ function useChatSession(options = {}) {
|
|
|
211
244
|
const error2 = new Error(`SSE ${stateMessage}`);
|
|
212
245
|
error2.code = "SSE_ERROR";
|
|
213
246
|
setError(error2);
|
|
214
|
-
|
|
247
|
+
latest.current.onError?.(error2);
|
|
215
248
|
};
|
|
216
249
|
},
|
|
217
|
-
[baseUrl,
|
|
250
|
+
[baseUrl, log]
|
|
218
251
|
);
|
|
219
252
|
const startSession = (0, import_react3.useCallback)(async () => {
|
|
220
253
|
if (isConnecting || session) return;
|
|
@@ -224,7 +257,7 @@ function useChatSession(options = {}) {
|
|
|
224
257
|
const existingSessionId = options.sessionId || getSessionFromStorage();
|
|
225
258
|
if (existingSessionId) {
|
|
226
259
|
try {
|
|
227
|
-
|
|
260
|
+
log("log", "Resuming session", existingSessionId);
|
|
228
261
|
const existingSession = await client.getChatSession(existingSessionId);
|
|
229
262
|
const existingMessages = await client.getChatMessages(existingSessionId);
|
|
230
263
|
sessionRef.current = existingSession;
|
|
@@ -238,14 +271,14 @@ function useChatSession(options = {}) {
|
|
|
238
271
|
setMessages(normalizedMessages2);
|
|
239
272
|
const sseEndpoint = `/v1/chat/sessions/${existingSessionId}/events`;
|
|
240
273
|
connectToSSE(sseEndpoint);
|
|
241
|
-
|
|
274
|
+
log("log", "Session resumed");
|
|
242
275
|
return;
|
|
243
276
|
} catch (err) {
|
|
244
|
-
|
|
277
|
+
log("warn", "Could not resume the session, starting a new one:", err);
|
|
245
278
|
clearSessionFromStorage();
|
|
246
279
|
}
|
|
247
280
|
}
|
|
248
|
-
|
|
281
|
+
log("log", "Creating a chat session");
|
|
249
282
|
const response = await client.createChatSession(options.metadata);
|
|
250
283
|
sessionRef.current = response.session;
|
|
251
284
|
setSession(response.session);
|
|
@@ -260,19 +293,19 @@ function useChatSession(options = {}) {
|
|
|
260
293
|
if (response.sseEndpoint) {
|
|
261
294
|
connectToSSE(response.sseEndpoint);
|
|
262
295
|
}
|
|
263
|
-
|
|
296
|
+
log("log", "Session created", response.session.id);
|
|
264
297
|
} catch (err) {
|
|
265
298
|
const error2 = err;
|
|
266
299
|
setError(error2);
|
|
267
|
-
|
|
300
|
+
latest.current.onError?.(error2);
|
|
268
301
|
} finally {
|
|
269
302
|
setIsConnecting(false);
|
|
270
303
|
}
|
|
271
304
|
}, [
|
|
272
305
|
client,
|
|
273
306
|
connectToSSE,
|
|
307
|
+
log,
|
|
274
308
|
options.metadata,
|
|
275
|
-
options.onError,
|
|
276
309
|
options.sessionId,
|
|
277
310
|
getSessionFromStorage,
|
|
278
311
|
saveSessionToStorage,
|
|
@@ -303,11 +336,11 @@ function useChatSession(options = {}) {
|
|
|
303
336
|
} catch (err) {
|
|
304
337
|
const error2 = err;
|
|
305
338
|
setError(error2);
|
|
306
|
-
|
|
339
|
+
latest.current.onError?.(error2);
|
|
307
340
|
throw error2;
|
|
308
341
|
}
|
|
309
342
|
},
|
|
310
|
-
[client
|
|
343
|
+
[client]
|
|
311
344
|
);
|
|
312
345
|
const endSession = (0, import_react3.useCallback)(async () => {
|
|
313
346
|
if (!sessionRef.current) return;
|
|
@@ -322,13 +355,13 @@ function useChatSession(options = {}) {
|
|
|
322
355
|
setSession(null);
|
|
323
356
|
setMessages([]);
|
|
324
357
|
setIsConnected(false);
|
|
325
|
-
|
|
358
|
+
log("log", "Session ended");
|
|
326
359
|
} catch (err) {
|
|
327
360
|
const error2 = err;
|
|
328
361
|
setError(error2);
|
|
329
|
-
|
|
362
|
+
latest.current.onError?.(error2);
|
|
330
363
|
}
|
|
331
|
-
}, [client,
|
|
364
|
+
}, [client, log, clearSessionFromStorage]);
|
|
332
365
|
const reconnect = (0, import_react3.useCallback)(() => {
|
|
333
366
|
const current = sessionRef.current;
|
|
334
367
|
if (!current) return;
|
|
@@ -1311,6 +1344,7 @@ function ContactForm(props) {
|
|
|
1311
1344
|
|
|
1312
1345
|
// src/components/SupportChat.tsx
|
|
1313
1346
|
var import_react7 = require("react");
|
|
1347
|
+
var import_core3 = require("@channlize/core");
|
|
1314
1348
|
|
|
1315
1349
|
// src/components/chat/internal.tsx
|
|
1316
1350
|
var import_react6 = require("react");
|
|
@@ -1667,6 +1701,7 @@ function SupportChat({
|
|
|
1667
1701
|
sessionId,
|
|
1668
1702
|
persistSession,
|
|
1669
1703
|
storageKey,
|
|
1704
|
+
debug,
|
|
1670
1705
|
className = "",
|
|
1671
1706
|
styles = {},
|
|
1672
1707
|
placeholder = "Write a message\u2026",
|
|
@@ -1694,7 +1729,7 @@ function SupportChat({
|
|
|
1694
1729
|
[labelOverrides]
|
|
1695
1730
|
);
|
|
1696
1731
|
const { config } = useChannlize();
|
|
1697
|
-
const baseUrl = config.baseUrl ||
|
|
1732
|
+
const baseUrl = config.baseUrl || import_core3.DEFAULT_BASE_URL;
|
|
1698
1733
|
const [text, setText] = (0, import_react7.useState)("");
|
|
1699
1734
|
const [files, setFiles] = (0, import_react7.useState)([]);
|
|
1700
1735
|
const [pending, setPending] = (0, import_react7.useState)([]);
|
|
@@ -1732,7 +1767,8 @@ function SupportChat({
|
|
|
1732
1767
|
onError,
|
|
1733
1768
|
sessionId,
|
|
1734
1769
|
persistSession,
|
|
1735
|
-
storageKey
|
|
1770
|
+
storageKey,
|
|
1771
|
+
debug
|
|
1736
1772
|
});
|
|
1737
1773
|
const sseFailed = error?.code === "SSE_ERROR";
|
|
1738
1774
|
const ownSendError = !!error && error === sendError;
|
|
@@ -2611,12 +2647,19 @@ function ChannlizeChat({
|
|
|
2611
2647
|
) }) });
|
|
2612
2648
|
return typeof document !== "undefined" ? (0, import_react_dom.createPortal)(widget, document.body) : widget;
|
|
2613
2649
|
}
|
|
2650
|
+
|
|
2651
|
+
// src/index.ts
|
|
2652
|
+
var import_core4 = require("@channlize/core");
|
|
2614
2653
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2615
2654
|
0 && (module.exports = {
|
|
2655
|
+
AuthenticationError,
|
|
2616
2656
|
ChannlizeChat,
|
|
2657
|
+
ChannlizeError,
|
|
2617
2658
|
ChannlizeProvider,
|
|
2618
2659
|
ContactForm,
|
|
2660
|
+
RateLimitError,
|
|
2619
2661
|
SupportChat,
|
|
2662
|
+
ValidationError,
|
|
2620
2663
|
defaultContactFormLabels,
|
|
2621
2664
|
defaultSupportChatLabels,
|
|
2622
2665
|
useChannlize,
|