@nimbusai/webchat-sdk 1.0.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/README.md +888 -0
- package/dist/index.d.mts +406 -0
- package/dist/index.d.ts +406 -0
- package/dist/index.js +183 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +183 -0
- package/dist/index.mjs.map +1 -0
- package/dist/nimbus-chat.umd.global.js +1881 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,888 @@
|
|
|
1
|
+
# Nimbus WebChat SDK
|
|
2
|
+
|
|
3
|
+
A modern, embeddable WebChat SDK with Shadow DOM isolation and real-time WebSocket messaging. Built with TypeScript, Tailwind CSS, and Lucide icons.
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/%40nimbus%2Fwebchat-sdk)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://tailwindcss.com/)
|
|
9
|
+
[](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Screenshots
|
|
14
|
+
|
|
15
|
+
### Full Dashboard View
|
|
16
|
+
<p align="center">
|
|
17
|
+
<img src="screenshoots/full-screen.png" alt="Full Application Dashboard" width="800">
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
### Theme Variations
|
|
21
|
+
<p align="center">
|
|
22
|
+
<img src="screenshoots/welcome-message.png" alt="Light Theme - Welcome Message" width="300">
|
|
23
|
+
|
|
24
|
+
<img src="screenshoots/black-edition.png" alt="Dark Theme - Black Edition" width="300">
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
### Layout Options
|
|
28
|
+
<p align="center">
|
|
29
|
+
<img src="screenshoots/bottom.png" alt="Bottom Position with Typing Indicator" width="300">
|
|
30
|
+
|
|
31
|
+
<img src="screenshoots/sidepanel.png" alt="Sidepanel Integration" width="300">
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
### File Upload & Media Handling
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="screenshoots/send-json.png" alt="JSON Data Exchange" width="300">
|
|
37
|
+
|
|
38
|
+
<img src="screenshoots/describe-pictures.png" alt="AI Image Description" width="300">
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<p align="center">
|
|
42
|
+
<img src="screenshoots/max-size.png" alt="File Size Limit" width="300">
|
|
43
|
+
|
|
44
|
+
<img src="screenshoots/uploaded-file-preview.png" alt="File Preview" width="300">
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
## Features
|
|
48
|
+
|
|
49
|
+
- **Zero dependencies** (except Lucide icons)
|
|
50
|
+
- **Fully customizable** UI and theming
|
|
51
|
+
- **Responsive design** with mobile support
|
|
52
|
+
- **Shadow DOM isolation** prevents CSS conflicts
|
|
53
|
+
- **Real-time WebSocket** messaging
|
|
54
|
+
- **TypeScript support** with full type definitions
|
|
55
|
+
- **Multiple formats** (ESM, CommonJS, UMD)
|
|
56
|
+
- **Flexible icons** (Lucide icons or custom images)
|
|
57
|
+
- **Automatic reconnection** with configurable retries
|
|
58
|
+
- **Optional message history** loading with resume conversation
|
|
59
|
+
- **Multiple layouts** (floating popup or sidepanel)
|
|
60
|
+
- **File upload support** with image previews (config-driven)
|
|
61
|
+
- **Character limits** with counter display
|
|
62
|
+
- **Developer-friendly** debug mode and logging
|
|
63
|
+
|
|
64
|
+
## Tech Stack
|
|
65
|
+
|
|
66
|
+
| Technology | Version | Purpose |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| [TypeScript](https://www.typescriptlang.org/) | `^5.7.2` | Type-safe development |
|
|
69
|
+
| [Tailwind CSS](https://tailwindcss.com/) | `^3.4.17` | Utility-first styling (pre-compiled into Shadow DOM) |
|
|
70
|
+
| [tsup](https://tsup.egoist.dev/) | `^8.3.5` | Bundler (ESM + CJS + IIFE) |
|
|
71
|
+
| [PostCSS](https://postcss.org/) | `^8.4.49` | CSS processing |
|
|
72
|
+
| [Autoprefixer](https://github.com/postcss/autoprefixer) | `^10.4.20` | Vendor prefix automation |
|
|
73
|
+
| [Vitest](https://vitest.dev/) | `^2.1.8` | Unit testing |
|
|
74
|
+
| [Lucide](https://lucide.dev/) | inline SVGs | Icons (Shadow DOM compatible) |
|
|
75
|
+
|
|
76
|
+
## Installation
|
|
77
|
+
|
|
78
|
+
### npm / yarn / pnpm
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm install @nimbusai/webchat-sdk
|
|
82
|
+
# or
|
|
83
|
+
yarn add @nimbusai/webchat-sdk
|
|
84
|
+
# or
|
|
85
|
+
pnpm add @nimbusai/webchat-sdk
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { NimbusChat } from "@nimbusai/webchat-sdk";
|
|
90
|
+
|
|
91
|
+
const chat = new NimbusChat({
|
|
92
|
+
agent_id: "550e8400-e29b-41d4-a716-446655440000",
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
chat.open();
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### CDN (script tag)
|
|
99
|
+
|
|
100
|
+
```html
|
|
101
|
+
<script src="https://cdn.nimbus.ai/sdk/nimbus-chat.umd.global.js"></script>
|
|
102
|
+
<script>
|
|
103
|
+
NimbusChat.init({
|
|
104
|
+
agent_id: "550e8400-e29b-41d4-a716-446655440000",
|
|
105
|
+
});
|
|
106
|
+
</script>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The CDN bundle exposes a global `NimbusChat` object with a singleton `init()` method — safe to call multiple times.
|
|
110
|
+
|
|
111
|
+
## Quick Start
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
const chat = new NimbusChat({
|
|
115
|
+
agent_id: "550e8400-e29b-41d4-a716-446655440000",
|
|
116
|
+
style: { position: "bottom-right" }
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The widget renders a floating chat bubble in the corner of the page. Click it to open the chat panel. The WebSocket connection is established lazily — only when the user opens the chat for the first time.
|
|
121
|
+
|
|
122
|
+
## API Reference
|
|
123
|
+
|
|
124
|
+
### Initialization
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
// NPM usage
|
|
128
|
+
const chat = new NimbusChat(config);
|
|
129
|
+
|
|
130
|
+
// CDN usage
|
|
131
|
+
const chat = NimbusChat.init(config);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Methods
|
|
135
|
+
|
|
136
|
+
| Method | Description |
|
|
137
|
+
|--------|-------------|
|
|
138
|
+
| `chat.open()` | Show the chat widget |
|
|
139
|
+
| `chat.close()` | Hide the chat widget |
|
|
140
|
+
| `chat.toggle()` | Toggle chat widget visibility |
|
|
141
|
+
| `chat.destroy()` | Remove the widget from DOM completely |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Configuration Reference
|
|
146
|
+
|
|
147
|
+
The SDK provides extensive configuration options to customize every aspect of the chat widget. All properties are optional except `agent_id`.
|
|
148
|
+
|
|
149
|
+
### Required Configuration
|
|
150
|
+
|
|
151
|
+
| Property | Type | Description |
|
|
152
|
+
|----------|------|-------------|
|
|
153
|
+
| `agent_id` | `string` | **Required** - Your agent ID (UUID) |
|
|
154
|
+
|
|
155
|
+
### Core Settings
|
|
156
|
+
|
|
157
|
+
| Property | Type | Default | Description |
|
|
158
|
+
|----------|------|---------|-------------|
|
|
159
|
+
| `dns` | `string` | `"api.nimbus.ai/api/v1/webchat"` | API endpoint for chat services |
|
|
160
|
+
| `resumeConversation` | `boolean` | `false` | When `true`, loads message history on reconnect and shows the "Show More" button. When `false`, starts fresh each time (flow_id is still reused). |
|
|
161
|
+
| `messagesPerPage` | `number` | `10` | Number of messages to load per page when scrolling history |
|
|
162
|
+
| `debug` | `boolean` | `false` | Enable debug logging to console |
|
|
163
|
+
| `allowNewChat` | `boolean` | `false` | Show "New Chat" button in header |
|
|
164
|
+
|
|
165
|
+
### Style Configuration
|
|
166
|
+
|
|
167
|
+
Controls layout, dimensions, and visual appearance of the widget:
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
style: {
|
|
171
|
+
position: "bottom-right",
|
|
172
|
+
width: "380px", // CSS width string (e.g. "380px", "100%")
|
|
173
|
+
height: "560px", // CSS height string (window mode only)
|
|
174
|
+
font: '"Inter Variable", sans-serif', // Global font family override
|
|
175
|
+
background: "#ffffff", // CSS color or image URL
|
|
176
|
+
mobile: {
|
|
177
|
+
position: "bottom-right", // Override position on mobile devices
|
|
178
|
+
breakpoint: "480px" // Viewport width to trigger mobile mode
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
| Property | Type | Default | Description |
|
|
184
|
+
|----------|------|---------|-------------|
|
|
185
|
+
| `style.position` | `ChatPosition` | `"bottom-right"` | Widget position on page. <br>Options: `"bottom-right"`, `"bottom-left"`, `"sidepanel-left"`, `"sidepanel-right"` |
|
|
186
|
+
| `style.width` | `string` | `"380px"` | Chat window width (CSS value) |
|
|
187
|
+
| `style.height` | `string` | `"560px"` | Chat window height (CSS value, window mode only) |
|
|
188
|
+
| `style.font` | `string` | System font | Global font family override |
|
|
189
|
+
| `style.background` | `string` | `"#f3f1ef"` | Chat body background (CSS color or image URL) |
|
|
190
|
+
| `style.mobile.position` | `ChatPosition` | Same as `style.position` | Widget position on mobile devices |
|
|
191
|
+
| `style.mobile.breakpoint` | `string` | `undefined` | Viewport width breakpoint for mobile mode (e.g. `"480px"`) |
|
|
192
|
+
|
|
193
|
+
### Theme Configuration
|
|
194
|
+
|
|
195
|
+
Global theme colors used throughout the widget:
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
theme: {
|
|
199
|
+
primary: "#ffce1c", // Primary color (buttons, headers, bubbles)
|
|
200
|
+
secondary: "#f3f1ef" // Secondary color (text, icons on primary bg)
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Chat Bubble Settings
|
|
205
|
+
|
|
206
|
+
The floating trigger button that opens/closes the chat:
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
bubble: {
|
|
210
|
+
position: "bottom-right",
|
|
211
|
+
autoHide: false, // Hide bubble when chat is open
|
|
212
|
+
icon: {
|
|
213
|
+
img: "message-circle", // Lucide icon or image URL
|
|
214
|
+
size: { width: 35, height: 35 }
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
| Property | Type | Default | Description |
|
|
220
|
+
|----------|------|---------|-------------|
|
|
221
|
+
| `position` | `BubblePosition` | `"bottom-right"` | Bubble position. <br>Options: `"bottom-right"`, `"bottom-left"` |
|
|
222
|
+
| `autoHide` | `boolean` | `false` | Hide the bubble when the chat panel is open |
|
|
223
|
+
| `icon` | `IconConfig \| null` | Default Lucide icon | Custom icon for the bubble |
|
|
224
|
+
|
|
225
|
+
### Header Configuration
|
|
226
|
+
|
|
227
|
+
```javascript
|
|
228
|
+
header: {
|
|
229
|
+
icon: {
|
|
230
|
+
img: "https://example.com/logo.svg", // Custom image URL or Lucide icon
|
|
231
|
+
size: { width: 125, height: 19 }
|
|
232
|
+
},
|
|
233
|
+
text: {
|
|
234
|
+
value: "Support Chat",
|
|
235
|
+
color: "#1e293b",
|
|
236
|
+
font: "Inter",
|
|
237
|
+
},
|
|
238
|
+
color: {
|
|
239
|
+
primary: "#f3f1ef", // Header background color
|
|
240
|
+
secondary: "#ffce1c" // Close button icon color
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Welcome Message
|
|
246
|
+
|
|
247
|
+
Shown when chat is empty, automatically hidden after first message:
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
welcome: {
|
|
251
|
+
display: true, // Show/hide welcome message
|
|
252
|
+
preTitle: {
|
|
253
|
+
value: "Welcome to :",
|
|
254
|
+
text: { color: "#1e293b", font: "" }
|
|
255
|
+
},
|
|
256
|
+
title: {
|
|
257
|
+
value: " Nimbus Chat!",
|
|
258
|
+
text: { color: "#1e293b", font: "" }
|
|
259
|
+
},
|
|
260
|
+
subtitle: {
|
|
261
|
+
value: "Send a message to start a conversation",
|
|
262
|
+
text: { color: "gray", font: "" }
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Message Styling
|
|
268
|
+
|
|
269
|
+
Configure user and bot message bubbles independently:
|
|
270
|
+
|
|
271
|
+
```javascript
|
|
272
|
+
userMessage: {
|
|
273
|
+
background: "#DCF8C6",
|
|
274
|
+
width: "80%", // Max width of message bubble (CSS value). Default: "80%"
|
|
275
|
+
text: {
|
|
276
|
+
color: "#111B21",
|
|
277
|
+
font: "",
|
|
278
|
+
size: 13
|
|
279
|
+
},
|
|
280
|
+
icon: {
|
|
281
|
+
img: "user", // Lucide icon or custom image URL
|
|
282
|
+
size: { width: 20, height: 20 }
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
botMessage: {
|
|
287
|
+
background: "#FFFFFF",
|
|
288
|
+
width: "80%", // Max width of message bubble (CSS value). Default: "80%"
|
|
289
|
+
text: {
|
|
290
|
+
color: "#111B21",
|
|
291
|
+
font: "",
|
|
292
|
+
size: 13
|
|
293
|
+
},
|
|
294
|
+
icon: {
|
|
295
|
+
img: "bot", // Lucide icon or custom image URL
|
|
296
|
+
size: { width: 20, height: 20 }
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
> **Note**: Set `icon: null` to explicitly hide the avatar. Omit `icon` entirely to use the default.
|
|
302
|
+
|
|
303
|
+
### Input Configuration
|
|
304
|
+
|
|
305
|
+
```javascript
|
|
306
|
+
input: {
|
|
307
|
+
placeholder: "Ask Nimbus",
|
|
308
|
+
expandable: true, // Auto-expanding textarea (up to 8 lines)
|
|
309
|
+
text: {
|
|
310
|
+
color: "#1e293b",
|
|
311
|
+
font: "",
|
|
312
|
+
},
|
|
313
|
+
background: {
|
|
314
|
+
primary: "white", // Input field background
|
|
315
|
+
secondary: "#f3f1ef" // Container background
|
|
316
|
+
},
|
|
317
|
+
upload: { // File upload settings (omit or set null to disable)
|
|
318
|
+
maxFileSize: 5242880, // 5MB in bytes
|
|
319
|
+
errorDisplayDuration: 2000, // Error message duration (ms)
|
|
320
|
+
allowedFileTypes: [
|
|
321
|
+
"image/jpeg",
|
|
322
|
+
"image/png",
|
|
323
|
+
"image/gif",
|
|
324
|
+
"application/pdf"
|
|
325
|
+
],
|
|
326
|
+
icon: {
|
|
327
|
+
img: "paperclip",
|
|
328
|
+
size: { width: 20, height: 20 }
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
maxCharacters: { // Character limit with counter
|
|
332
|
+
limit: 10000, // Maximum characters allowed
|
|
333
|
+
text: {
|
|
334
|
+
color: "gray",
|
|
335
|
+
size: 12
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
> **Note**: File upload is config-driven. Omit the `upload` property or set it to `null` to disable file uploads. Provide an `upload` object to enable the upload button.
|
|
342
|
+
|
|
343
|
+
### Send Button
|
|
344
|
+
|
|
345
|
+
```javascript
|
|
346
|
+
sendButton: {
|
|
347
|
+
align: false, // true = input and button on same row
|
|
348
|
+
icon: {
|
|
349
|
+
img: "send", // Lucide icon or custom image URL
|
|
350
|
+
size: { width: 20, height: 20 }
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Reconnection Settings
|
|
356
|
+
|
|
357
|
+
Control automatic reconnection behavior:
|
|
358
|
+
|
|
359
|
+
```javascript
|
|
360
|
+
reconnect: {
|
|
361
|
+
attempts: 5, // Maximum reconnection attempts
|
|
362
|
+
timeout: 5000 // Delay between attempts (ms)
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Wait for Reply Configuration
|
|
367
|
+
|
|
368
|
+
Control message sending while waiting for bot responses. Works independently from the typing indicator.
|
|
369
|
+
|
|
370
|
+
```javascript
|
|
371
|
+
waitForReply: {
|
|
372
|
+
timeout: 30000, // Max wait time (ms) before allowing next message
|
|
373
|
+
firstReply: false // Wait for bot's first message in new chat
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
> **Note**: Omit `waitForReply` to disable input blocking entirely.
|
|
378
|
+
|
|
379
|
+
### Typing Indicator Configuration
|
|
380
|
+
|
|
381
|
+
Show a typing indicator when waiting for bot responses. Independent from `waitForReply` — you can use either or both.
|
|
382
|
+
|
|
383
|
+
```javascript
|
|
384
|
+
isTypingIndicator: {
|
|
385
|
+
position: "bottom",
|
|
386
|
+
title: {
|
|
387
|
+
value: "AI Assistant is typing...",
|
|
388
|
+
text: {
|
|
389
|
+
color: "#1e293b",
|
|
390
|
+
font: ""
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
| Property | Type | Default | Description |
|
|
397
|
+
|----------|------|---------|-------------|
|
|
398
|
+
| `position` | `"top" \| "bottom"` | `"top"` | Where to display the indicator. <br>Options: `"top"` (header status area), `"bottom"` (above input area) |
|
|
399
|
+
| `title.value` | `string` | `"AI Assistant is typing..."` | Indicator text |
|
|
400
|
+
| `title.text` | `TextConfig` | `{ color: "#1e293b" }` | Text styling |
|
|
401
|
+
|
|
402
|
+
> **Note**: Omit `isTypingIndicator` to disable the typing indicator.
|
|
403
|
+
|
|
404
|
+
### Show More Button
|
|
405
|
+
|
|
406
|
+
Configure the "Show More" button for loading message history (only visible when `resumeConversation: true`):
|
|
407
|
+
|
|
408
|
+
```javascript
|
|
409
|
+
showMore: {
|
|
410
|
+
value: "Show More",
|
|
411
|
+
sticky: true, // Stick to top of message list
|
|
412
|
+
background: "#FFF4CC",
|
|
413
|
+
text: {
|
|
414
|
+
color: "black",
|
|
415
|
+
size: 13
|
|
416
|
+
},
|
|
417
|
+
icon: {
|
|
418
|
+
img: "chevron-down",
|
|
419
|
+
size: { width: 16, height: 16 }
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Icon System
|
|
427
|
+
|
|
428
|
+
The SDK supports two types of icons throughout all configuration:
|
|
429
|
+
|
|
430
|
+
### Lucide Icons (Recommended)
|
|
431
|
+
|
|
432
|
+
Text-based icon names that render as inline SVG:
|
|
433
|
+
|
|
434
|
+
```javascript
|
|
435
|
+
icon: {
|
|
436
|
+
img: "message-circle",
|
|
437
|
+
size: { width: 24, height: 24 },
|
|
438
|
+
color: "#ffffff"
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**Popular Lucide Icons:**
|
|
443
|
+
- `"message-circle"` - Chat bubble
|
|
444
|
+
- `"send"` - Send arrow
|
|
445
|
+
- `"x"` - Close/X mark
|
|
446
|
+
- `"rotate-cw"` - Refresh/new chat
|
|
447
|
+
- `"chevron-down"` / `"chevron-up"` - Arrows
|
|
448
|
+
- `"user"` - User avatar
|
|
449
|
+
- `"bot"` - Bot avatar
|
|
450
|
+
- `"paperclip"` - File attachment
|
|
451
|
+
|
|
452
|
+
[Browse all 1000+ Lucide icons →](https://lucide.dev/icons/)
|
|
453
|
+
|
|
454
|
+
### Custom Images
|
|
455
|
+
|
|
456
|
+
URL-based custom images:
|
|
457
|
+
|
|
458
|
+
```javascript
|
|
459
|
+
icon: {
|
|
460
|
+
img: "https://example.com/logo.png",
|
|
461
|
+
size: { width: 32, height: 32 }
|
|
462
|
+
// color is ignored for image URLs
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### Hiding Icons
|
|
467
|
+
|
|
468
|
+
```javascript
|
|
469
|
+
icon: null // Explicitly hide the icon
|
|
470
|
+
// or
|
|
471
|
+
// Omit the icon property entirely to use default
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## Shared Type Definitions
|
|
477
|
+
|
|
478
|
+
### TextConfig
|
|
479
|
+
|
|
480
|
+
Used for styling text elements throughout the SDK:
|
|
481
|
+
|
|
482
|
+
```typescript
|
|
483
|
+
interface TextConfig {
|
|
484
|
+
display?: boolean; // Show/hide text (not used everywhere)
|
|
485
|
+
value?: string; // The text content
|
|
486
|
+
color?: string; // CSS color value
|
|
487
|
+
font?: string; // Font family override
|
|
488
|
+
size?: number; // Font size in pixels
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### IconConfig
|
|
493
|
+
|
|
494
|
+
Used for all icons in the SDK:
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
interface IconConfig {
|
|
498
|
+
img?: string; // Lucide icon name or image URL
|
|
499
|
+
size?: {
|
|
500
|
+
width: number; // Width in pixels
|
|
501
|
+
height: number; // Height in pixels
|
|
502
|
+
};
|
|
503
|
+
color?: string; // Icon color (CSS color). Only applies to Lucide icons, ignored for image URLs.
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### ColorPair
|
|
508
|
+
|
|
509
|
+
Used for primary/secondary color combinations:
|
|
510
|
+
|
|
511
|
+
```typescript
|
|
512
|
+
interface ColorPair {
|
|
513
|
+
primary?: string; // Primary color (usually background)
|
|
514
|
+
secondary?: string; // Secondary color (usually foreground)
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## Complete Configuration Example
|
|
521
|
+
|
|
522
|
+
```javascript
|
|
523
|
+
const chat = new NimbusChat({
|
|
524
|
+
// Required
|
|
525
|
+
agent_id: "550e8400-e29b-41d4-a716-446655440000",
|
|
526
|
+
|
|
527
|
+
// Core Settings
|
|
528
|
+
dns: "api.nimbus.ai/api/v1/chat/ws",
|
|
529
|
+
resumeConversation: false,
|
|
530
|
+
messagesPerPage: 10,
|
|
531
|
+
debug: true,
|
|
532
|
+
allowNewChat: true,
|
|
533
|
+
|
|
534
|
+
// Theme
|
|
535
|
+
theme: {
|
|
536
|
+
primary: "#ffce1c",
|
|
537
|
+
secondary: "#f3f1ef"
|
|
538
|
+
},
|
|
539
|
+
|
|
540
|
+
// Style
|
|
541
|
+
style: {
|
|
542
|
+
position: "bottom-right",
|
|
543
|
+
width: "450px",
|
|
544
|
+
height: "500px",
|
|
545
|
+
font: "",
|
|
546
|
+
background: "#f3f1ef",
|
|
547
|
+
mobile: {
|
|
548
|
+
position: "bottom-right",
|
|
549
|
+
breakpoint: "480px"
|
|
550
|
+
}
|
|
551
|
+
},
|
|
552
|
+
|
|
553
|
+
// Chat Bubble
|
|
554
|
+
bubble: {
|
|
555
|
+
position: "bottom-right",
|
|
556
|
+
autoHide: false,
|
|
557
|
+
icon: {
|
|
558
|
+
img: "message-circle",
|
|
559
|
+
size: { width: 35, height: 35 }
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
|
|
563
|
+
// Header
|
|
564
|
+
header: {
|
|
565
|
+
icon: {
|
|
566
|
+
img: "https://example.com/logo.svg",
|
|
567
|
+
size: { width: 125, height: 19 }
|
|
568
|
+
},
|
|
569
|
+
text: {
|
|
570
|
+
value: "",
|
|
571
|
+
color: "#1e293b",
|
|
572
|
+
font: "",
|
|
573
|
+
},
|
|
574
|
+
color: {
|
|
575
|
+
primary: "#f3f1ef",
|
|
576
|
+
secondary: "#ffce1c"
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
|
|
580
|
+
// Welcome Message
|
|
581
|
+
welcome: {
|
|
582
|
+
display: true,
|
|
583
|
+
preTitle: {
|
|
584
|
+
value: "Welcome to :",
|
|
585
|
+
text: { color: "#1e293b", font: "" }
|
|
586
|
+
},
|
|
587
|
+
title: {
|
|
588
|
+
value: " Nimbus Chat!",
|
|
589
|
+
text: { color: "#1e293b", font: "" }
|
|
590
|
+
},
|
|
591
|
+
subtitle: {
|
|
592
|
+
value: "Send a message to start a conversation",
|
|
593
|
+
text: { color: "gray", font: "" }
|
|
594
|
+
}
|
|
595
|
+
},
|
|
596
|
+
|
|
597
|
+
// Messages
|
|
598
|
+
userMessage: {
|
|
599
|
+
background: "#DCF8C6",
|
|
600
|
+
width: "80%",
|
|
601
|
+
text: { color: "#111B21", font: "", size: 13 },
|
|
602
|
+
icon: {
|
|
603
|
+
img: "user",
|
|
604
|
+
size: { width: 20, height: 20 }
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
|
|
608
|
+
botMessage: {
|
|
609
|
+
background: "#FFFFFF",
|
|
610
|
+
width: "80%",
|
|
611
|
+
text: { color: "#111B21", font: "", size: 13 },
|
|
612
|
+
icon: {
|
|
613
|
+
img: "bot",
|
|
614
|
+
size: { width: 20, height: 20 }
|
|
615
|
+
}
|
|
616
|
+
},
|
|
617
|
+
|
|
618
|
+
// Input Area
|
|
619
|
+
input: {
|
|
620
|
+
placeholder: "Ask Nimbus",
|
|
621
|
+
expandable: true,
|
|
622
|
+
text: {
|
|
623
|
+
color: "#1e293b",
|
|
624
|
+
font: "",
|
|
625
|
+
},
|
|
626
|
+
background: {
|
|
627
|
+
primary: "white",
|
|
628
|
+
secondary: "#f3f1ef"
|
|
629
|
+
},
|
|
630
|
+
maxCharacters: {
|
|
631
|
+
limit: 10000,
|
|
632
|
+
text: {
|
|
633
|
+
color: "gray",
|
|
634
|
+
font: "",
|
|
635
|
+
size: 12
|
|
636
|
+
}
|
|
637
|
+
},
|
|
638
|
+
upload: null
|
|
639
|
+
},
|
|
640
|
+
|
|
641
|
+
// Send Button
|
|
642
|
+
sendButton: {
|
|
643
|
+
align: false,
|
|
644
|
+
icon: {
|
|
645
|
+
img: "send",
|
|
646
|
+
size: { width: 20, height: 20 }
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
|
|
650
|
+
// Reconnection
|
|
651
|
+
reconnect: {
|
|
652
|
+
attempts: 5,
|
|
653
|
+
timeout: 5000
|
|
654
|
+
},
|
|
655
|
+
|
|
656
|
+
// Wait for Reply
|
|
657
|
+
waitForReply: {
|
|
658
|
+
timeout: 30000,
|
|
659
|
+
firstReply: false
|
|
660
|
+
},
|
|
661
|
+
|
|
662
|
+
// Typing Indicator (independent from waitForReply)
|
|
663
|
+
isTypingIndicator: {
|
|
664
|
+
position: "bottom",
|
|
665
|
+
title: {
|
|
666
|
+
value: "AI Assistant is typing...",
|
|
667
|
+
text: { color: "#1e293b", font: "" }
|
|
668
|
+
}
|
|
669
|
+
},
|
|
670
|
+
|
|
671
|
+
// Show More (only visible when resumeConversation: true)
|
|
672
|
+
showMore: {
|
|
673
|
+
value: "Show More",
|
|
674
|
+
sticky: true,
|
|
675
|
+
background: "#FFF4CC",
|
|
676
|
+
text: {
|
|
677
|
+
color: "black",
|
|
678
|
+
font: "",
|
|
679
|
+
size: 13
|
|
680
|
+
},
|
|
681
|
+
icon: {
|
|
682
|
+
img: "chevron-down",
|
|
683
|
+
size: { width: 16, height: 16 }
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
});
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
---
|
|
690
|
+
|
|
691
|
+
## Debug Mode
|
|
692
|
+
|
|
693
|
+
Enable comprehensive logging for development and troubleshooting:
|
|
694
|
+
|
|
695
|
+
```javascript
|
|
696
|
+
const chat = new NimbusChat({
|
|
697
|
+
agent_id: "your-uuid-here",
|
|
698
|
+
debug: true
|
|
699
|
+
});
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
**Debug mode provides:**
|
|
703
|
+
- WebSocket connection events
|
|
704
|
+
- Message send/receive logs
|
|
705
|
+
- Session state changes
|
|
706
|
+
- Configuration resolution details
|
|
707
|
+
- Error stack traces
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
|
|
711
|
+
## Development
|
|
712
|
+
|
|
713
|
+
### Prerequisites
|
|
714
|
+
|
|
715
|
+
- Node.js >= 18
|
|
716
|
+
- npm >= 9
|
|
717
|
+
|
|
718
|
+
### Setup
|
|
719
|
+
|
|
720
|
+
```bash
|
|
721
|
+
git clone https://github.com/nichemarket/chat-sdk.git
|
|
722
|
+
cd chat-sdk
|
|
723
|
+
npm install
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
### Scripts
|
|
727
|
+
|
|
728
|
+
```bash
|
|
729
|
+
npm run build # Full build (CSS + TypeScript)
|
|
730
|
+
npm run build:css # Compile Tailwind only
|
|
731
|
+
npm run build:ts # Compile TypeScript only
|
|
732
|
+
npm run type-check # Type-check without emitting
|
|
733
|
+
npm run dev # Watch mode
|
|
734
|
+
npm test # Run tests
|
|
735
|
+
npm run test:watch # Watch mode tests
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
### Testing
|
|
739
|
+
|
|
740
|
+
The SDK uses [Vitest](https://vitest.dev/) with `jsdom` for unit testing. Tests cover configuration resolution, validation, core modules, UI utilities, and DOM components.
|
|
741
|
+
|
|
742
|
+
```bash
|
|
743
|
+
npm test # Run all tests
|
|
744
|
+
npm run test:watch # Run in watch mode
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
**Test suite structure:**
|
|
748
|
+
|
|
749
|
+
| File | Covers |
|
|
750
|
+
|---|---|
|
|
751
|
+
| `tests/types/resolveConfig.test.ts` | Config resolution, defaults, overrides, deep merging |
|
|
752
|
+
| `tests/utils/validateConfig.test.ts` | Required fields, type validation, nested config validation |
|
|
753
|
+
| `tests/core/EventBus.test.ts` | Pub/sub, `on`/`off`/`once`/`emit`, error isolation, typed events |
|
|
754
|
+
| `tests/core/ChatSession.test.ts` | Session ID, messages, history load/merge, dedup, clear |
|
|
755
|
+
| `tests/utils/FileUtils.test.ts` | File size formatting, Base64 conversion |
|
|
756
|
+
| `tests/utils/DOMBuilder.test.ts` | Element creation, props, chaining, append, conditionals, fragments |
|
|
757
|
+
| `tests/ui/ThemeManager.test.ts` | CSS variables, theme colors, backgrounds, fonts, input styles |
|
|
758
|
+
| `tests/utils/IconRenderer.test.ts` | Lucide SVG rendering, URL images, unknown icons, wrapper/simple modes |
|
|
759
|
+
|
|
760
|
+
### Common Development Commands
|
|
761
|
+
|
|
762
|
+
```bash
|
|
763
|
+
# Clean installation (recommended for troubleshooting)
|
|
764
|
+
rm -rf node_modules package-lock.json && npm install && npm run build
|
|
765
|
+
|
|
766
|
+
# Fast build and serve for testing
|
|
767
|
+
npm run build && npx http-server -p 8081 -c-1
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
### Code Standards
|
|
771
|
+
|
|
772
|
+
**Logging**: Always use the custom logger instead of `console.*` statements:
|
|
773
|
+
|
|
774
|
+
```typescript
|
|
775
|
+
import { createLogger } from './utils/logger';
|
|
776
|
+
|
|
777
|
+
// For utility files - create logger at top level
|
|
778
|
+
const logger = createLogger('ComponentName');
|
|
779
|
+
|
|
780
|
+
// For classes - create logger in constructor
|
|
781
|
+
class MyComponent {
|
|
782
|
+
private logger: Logger;
|
|
783
|
+
|
|
784
|
+
constructor(debug = false) {
|
|
785
|
+
this.logger = createLogger('MyComponent', debug);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// Usage
|
|
790
|
+
logger.info('Info message');
|
|
791
|
+
logger.warn('Warning message');
|
|
792
|
+
logger.error('Error message');
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
### Output Files
|
|
796
|
+
|
|
797
|
+
| Format | File | Size |
|
|
798
|
+
|---|---|---|
|
|
799
|
+
| ESM | `dist/index.mjs` | ~48 KB |
|
|
800
|
+
| CJS | `dist/index.js` | ~49 KB |
|
|
801
|
+
| IIFE/UMD | `dist/nimbus-chat.umd.global.js` | ~49 KB |
|
|
802
|
+
| Types | `dist/index.d.ts` | ~8.5 KB |
|
|
803
|
+
|
|
804
|
+
### Project Structure
|
|
805
|
+
|
|
806
|
+
```
|
|
807
|
+
chat-sdk/
|
|
808
|
+
├── src/
|
|
809
|
+
│ ├── core/ # EventBus, ChatSession, WebSocketManager, ApiClient
|
|
810
|
+
│ ├── icons/ # Lucide SVG icon definitions
|
|
811
|
+
│ ├── styles/ # Tailwind globals + compiled CSS
|
|
812
|
+
│ ├── types/ # TypeScript interfaces (config, message)
|
|
813
|
+
│ ├── ui/ # UI components (Header, MessageList, InputArea, etc.)
|
|
814
|
+
│ ├── utils/ # Utilities (logger, validator, parser, etc.)
|
|
815
|
+
│ ├── NimbusChat.ts # Main SDK orchestrator
|
|
816
|
+
│ └── index.ts # Public exports
|
|
817
|
+
├── examples/
|
|
818
|
+
│ ├── cdn-usage.html # CDN integration example (full config)
|
|
819
|
+
│ ├── cdn-usage-basic.html # CDN integration example (minimal config)
|
|
820
|
+
│ └── cdn-usage-black.html # CDN integration example (dark theme)
|
|
821
|
+
├── dist/ # Build output
|
|
822
|
+
├── tsconfig.json
|
|
823
|
+
├── tsup.config.js
|
|
824
|
+
├── tailwind.config.js
|
|
825
|
+
├── postcss.config.js
|
|
826
|
+
└── package.json
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
---
|
|
830
|
+
|
|
831
|
+
## Architecture
|
|
832
|
+
|
|
833
|
+
The SDK uses **Shadow DOM** (open mode) to fully isolate styles from the host page. Tailwind CSS is pre-compiled at build time and injected into the shadow root at runtime alongside CSS custom properties for theming.
|
|
834
|
+
|
|
835
|
+
### Component Architecture
|
|
836
|
+
|
|
837
|
+
```
|
|
838
|
+
NimbusChat (orchestrator)
|
|
839
|
+
├── EventBus (pub/sub messaging)
|
|
840
|
+
├── ChatSession (message state + history)
|
|
841
|
+
├── WebSocketManager (connection lifecycle)
|
|
842
|
+
├── ApiClient (REST API)
|
|
843
|
+
└── UI Components
|
|
844
|
+
├── ShadowContainer (DOM isolation)
|
|
845
|
+
├── ThemeManager (CSS custom properties)
|
|
846
|
+
├── ChatWindow/SidepanelWindow (containers)
|
|
847
|
+
├── Header
|
|
848
|
+
├── MessageList
|
|
849
|
+
├── InputArea (with FileUpload)
|
|
850
|
+
├── MessageBubble
|
|
851
|
+
└── ChatBubble (floating trigger)
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
### Connection Lifecycle
|
|
855
|
+
|
|
856
|
+
1. **Initial Connection**: Client opens WebSocket with `agent_id` (and `flow_id` if available from localStorage)
|
|
857
|
+
2. **Connected**: Server responds with `{ "type": "connected", "flow_id": "uuid" }`
|
|
858
|
+
3. **Persistence**: `flow_id` is always stored in localStorage and reused on reconnect
|
|
859
|
+
4. **History Loading**: If `resumeConversation: true`, fetches message history via REST API after connection
|
|
860
|
+
5. **Messaging**: Simple message exchange with `direction: "inbound"` (user) and `direction: "outbound"` (bot)
|
|
861
|
+
|
|
862
|
+
### WebSocket Events
|
|
863
|
+
|
|
864
|
+
**Incoming:**
|
|
865
|
+
- `connected` - Connection established, provides `flow_id`
|
|
866
|
+
- `message` - New message from server (`direction: "outbound"`)
|
|
867
|
+
|
|
868
|
+
**Outgoing:**
|
|
869
|
+
- `message` - User message (`direction: "inbound"`)
|
|
870
|
+
|
|
871
|
+
### Message Schema
|
|
872
|
+
|
|
873
|
+
```javascript
|
|
874
|
+
// User message (sent to server)
|
|
875
|
+
{ "type": "message", "direction": "inbound", "content": "Hello!" }
|
|
876
|
+
|
|
877
|
+
// Bot message (received from server)
|
|
878
|
+
{ "type": "message", "direction": "outbound", "content": "Hi there!" }
|
|
879
|
+
|
|
880
|
+
// Connected event (received from server)
|
|
881
|
+
{ "type": "connected", "flow_id": "550e8400-e29b-41d4-a716-446655440000" }
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
---
|
|
885
|
+
|
|
886
|
+
## License
|
|
887
|
+
|
|
888
|
+
[MIT](LICENSE)
|