@ihoomanai/chat-widget 2.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 ADDED
@@ -0,0 +1,188 @@
1
+ # @ihooman/chat-widget
2
+
3
+ Universal chat support widget for any website. Uses secure Widget ID based initialization - no API keys exposed in client code.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ihooman/chat-widget
9
+ # or
10
+ yarn add @ihooman/chat-widget
11
+ # or
12
+ pnpm add @ihooman/chat-widget
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ### ES Modules
18
+
19
+ ```typescript
20
+ import { IhoomanChat } from '@ihooman/chat-widget';
21
+
22
+ IhoomanChat.init({
23
+ widgetId: 'wgt_your_widget_id', // Get this from your Ihooman dashboard
24
+ });
25
+ ```
26
+
27
+ ### CommonJS
28
+
29
+ ```javascript
30
+ const { IhoomanChat } = require('@ihooman/chat-widget');
31
+
32
+ IhoomanChat.init({
33
+ widgetId: 'wgt_your_widget_id',
34
+ });
35
+ ```
36
+
37
+ ### CDN / Script Tag
38
+
39
+ ```html
40
+ <script src="https://cdn.ihooman.ai/widget/latest/chat.min.js"></script>
41
+ <script>
42
+ IhoomanChat.init({
43
+ widgetId: 'wgt_your_widget_id',
44
+ });
45
+ </script>
46
+ ```
47
+
48
+ ## Configuration Options
49
+
50
+ ```typescript
51
+ IhoomanChat.init({
52
+ // Required
53
+ widgetId: 'wgt_your_widget_id',
54
+
55
+ // Optional
56
+ theme: 'light', // 'light' | 'dark'
57
+ position: 'bottom-right', // 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
58
+ title: 'Chat Support',
59
+ subtitle: 'We typically reply within minutes',
60
+ welcomeMessage: 'Hi there! 👋 How can we help you today?',
61
+ placeholder: 'Type a message...',
62
+ primaryColor: '#00aeff',
63
+ startOpen: false,
64
+
65
+ // Callbacks
66
+ onReady: () => console.log('Widget ready'),
67
+ onOpen: () => console.log('Widget opened'),
68
+ onClose: () => console.log('Widget closed'),
69
+ onMessage: (message) => console.log('Message:', message),
70
+ onError: (error) => console.error('Error:', error),
71
+ });
72
+ ```
73
+
74
+
75
+ ## API Methods
76
+
77
+ ### `IhoomanChat.init(config)`
78
+
79
+ Initialize the widget with configuration options. Returns a Promise that resolves when the widget is ready.
80
+
81
+ ### `IhoomanChat.open()`
82
+
83
+ Open the chat widget window.
84
+
85
+ ### `IhoomanChat.close()`
86
+
87
+ Close the chat widget window.
88
+
89
+ ### `IhoomanChat.toggle()`
90
+
91
+ Toggle the chat widget window open/closed.
92
+
93
+ ### `IhoomanChat.destroy()`
94
+
95
+ Destroy the widget and clean up all resources.
96
+
97
+ ### `IhoomanChat.sendMessage(content)`
98
+
99
+ Send a message programmatically.
100
+
101
+ ```typescript
102
+ IhoomanChat.sendMessage('Hello, I need help!');
103
+ ```
104
+
105
+ ### `IhoomanChat.setUser(user)`
106
+
107
+ Set user information for personalization.
108
+
109
+ ```typescript
110
+ IhoomanChat.setUser({
111
+ name: 'John Doe',
112
+ email: 'john@example.com',
113
+ metadata: {
114
+ plan: 'premium',
115
+ },
116
+ });
117
+ ```
118
+
119
+ ### `IhoomanChat.clearHistory()`
120
+
121
+ Clear chat history and start a new conversation.
122
+
123
+ ### `IhoomanChat.on(event, callback)`
124
+
125
+ Subscribe to widget events.
126
+
127
+ ```typescript
128
+ IhoomanChat.on('message', (message) => {
129
+ console.log('New message:', message);
130
+ });
131
+ ```
132
+
133
+ ### `IhoomanChat.off(event, callback)`
134
+
135
+ Unsubscribe from widget events.
136
+
137
+ ### `IhoomanChat.getState()`
138
+
139
+ Get the current widget state.
140
+
141
+ ```typescript
142
+ const state = IhoomanChat.getState();
143
+ console.log('Is open:', state.isOpen);
144
+ console.log('Messages:', state.messages);
145
+ ```
146
+
147
+ ## Events
148
+
149
+ - `ready` - Widget is initialized and ready
150
+ - `open` - Widget window opened
151
+ - `close` - Widget window closed
152
+ - `message` - Message sent or received
153
+ - `error` - An error occurred
154
+
155
+ ## TypeScript Support
156
+
157
+ This package includes TypeScript type definitions. All types are exported:
158
+
159
+ ```typescript
160
+ import type {
161
+ WidgetConfig,
162
+ WidgetState,
163
+ UserInfo,
164
+ Message,
165
+ WidgetEvent,
166
+ } from '@ihooman/chat-widget';
167
+ ```
168
+
169
+ ## Security
170
+
171
+ This widget uses Widget ID based initialization, which means:
172
+
173
+ - ✅ No API keys are exposed in client-side code
174
+ - ✅ Domain validation ensures the widget only works on authorized domains
175
+ - ✅ All sensitive operations happen server-side
176
+
177
+ Get your Widget ID from the [Ihooman Dashboard](https://dashboard.ihooman.ai).
178
+
179
+ ## Browser Support
180
+
181
+ - Chrome (latest)
182
+ - Firefox (latest)
183
+ - Safari (latest)
184
+ - Edge (latest)
185
+
186
+ ## License
187
+
188
+ MIT © [Ihooman AI](https://ihooman.ai)
@@ -0,0 +1,199 @@
1
+ # CDN Deployment Guide
2
+
3
+ This document describes how to deploy the Ihooman Chat Widget to a CDN with proper URL structure and caching configuration.
4
+
5
+ ## Overview
6
+
7
+ The widget is served from `https://cdn.ihooman.ai/widget/` with the following URL structure:
8
+
9
+ | URL Pattern | Description | Cache Duration |
10
+ |-------------|-------------|----------------|
11
+ | `/v2/chat.min.js` | Latest v2.x.x release | 1 year (immutable) |
12
+ | `/v2.1.0/chat.min.js` | Specific version | 1 year (immutable) |
13
+ | `/latest/chat.min.js` | Always latest stable | 5 minutes |
14
+
15
+ ## URL Structure
16
+
17
+ ### Versioned URLs (Recommended for Production)
18
+
19
+ ```
20
+ https://cdn.ihooman.ai/widget/v2/chat.min.js # Latest v2.x.x
21
+ https://cdn.ihooman.ai/widget/v2.1.0/chat.min.js # Specific version
22
+ https://cdn.ihooman.ai/widget/v2.1.0/chat.min.js.map # Source map
23
+ ```
24
+
25
+ ### Latest URL (For Development/Testing)
26
+
27
+ ```
28
+ https://cdn.ihooman.ai/widget/latest/chat.min.js # Always latest stable
29
+ https://cdn.ihooman.ai/widget/latest/chat.min.js.map # Source map
30
+ ```
31
+
32
+ ## Cache Headers
33
+
34
+ ### Versioned Content (v2/, v2.1.0/, etc.)
35
+
36
+ ```
37
+ Cache-Control: public, max-age=31536000, immutable
38
+ ```
39
+
40
+ - **max-age=31536000**: Cache for 1 year (365 days)
41
+ - **immutable**: Content will never change, browsers can skip revalidation
42
+ - **public**: Can be cached by CDN edge nodes and browsers
43
+
44
+ ### Latest Content (/latest/)
45
+
46
+ ```
47
+ Cache-Control: public, max-age=300
48
+ ```
49
+
50
+ - **max-age=300**: Cache for 5 minutes
51
+ - **public**: Can be cached by CDN edge nodes and browsers
52
+ - No `immutable` flag since content changes with each release
53
+
54
+ ## Deployment Options
55
+
56
+ ### Option 1: AWS CloudFront + S3
57
+
58
+ See `cloudfront-config.json` for CloudFront distribution configuration.
59
+
60
+ ### Option 2: Cloudflare
61
+
62
+ See `cloudflare-config.json` for Cloudflare configuration.
63
+
64
+ ### Option 3: Nginx (Self-Hosted)
65
+
66
+ See `nginx.conf` for Nginx configuration.
67
+
68
+ ## Deployment Steps
69
+
70
+ ### 1. Build CDN Assets
71
+
72
+ ```bash
73
+ cd packages/chat-widget
74
+ npm run build:cdn
75
+ ```
76
+
77
+ This generates:
78
+ - `cdn/v2/` - Major version directory
79
+ - `cdn/v2.x.x/` - Full version directory
80
+ - `cdn/latest/` - Latest version directory
81
+ - `cdn/manifest.json` - Build manifest with SRI hashes
82
+
83
+ ### 2. Upload to CDN Origin
84
+
85
+ Upload the contents of the `cdn/` directory to your CDN origin (S3, R2, or origin server).
86
+
87
+ ```bash
88
+ # Example: AWS S3
89
+ aws s3 sync cdn/ s3://cdn-ihooman-widget/widget/ \
90
+ --cache-control "public, max-age=31536000, immutable" \
91
+ --exclude "latest/*"
92
+
93
+ aws s3 sync cdn/latest/ s3://cdn-ihooman-widget/widget/latest/ \
94
+ --cache-control "public, max-age=300"
95
+ ```
96
+
97
+ ### 3. Invalidate CDN Cache (if updating)
98
+
99
+ ```bash
100
+ # AWS CloudFront
101
+ aws cloudfront create-invalidation \
102
+ --distribution-id YOUR_DISTRIBUTION_ID \
103
+ --paths "/widget/latest/*" "/widget/v2/*"
104
+ ```
105
+
106
+ ### 4. Verify Deployment
107
+
108
+ ```bash
109
+ # Check versioned URL
110
+ curl -I https://cdn.ihooman.ai/widget/v2.0.0/chat.min.js
111
+
112
+ # Expected headers:
113
+ # Cache-Control: public, max-age=31536000, immutable
114
+ # Content-Type: application/javascript
115
+
116
+ # Check latest URL
117
+ curl -I https://cdn.ihooman.ai/widget/latest/chat.min.js
118
+
119
+ # Expected headers:
120
+ # Cache-Control: public, max-age=300
121
+ # Content-Type: application/javascript
122
+ ```
123
+
124
+ ## CORS Configuration
125
+
126
+ The CDN must allow cross-origin requests for the widget to work on any domain:
127
+
128
+ ```
129
+ Access-Control-Allow-Origin: *
130
+ Access-Control-Allow-Methods: GET, HEAD, OPTIONS
131
+ Access-Control-Allow-Headers: Content-Type
132
+ ```
133
+
134
+ ## Security Headers
135
+
136
+ Recommended security headers for the CDN:
137
+
138
+ ```
139
+ X-Content-Type-Options: nosniff
140
+ X-Frame-Options: DENY
141
+ Referrer-Policy: strict-origin-when-cross-origin
142
+ ```
143
+
144
+ ## Monitoring
145
+
146
+ ### Key Metrics to Monitor
147
+
148
+ 1. **Cache Hit Ratio**: Should be >95% for versioned URLs
149
+ 2. **Latency**: P99 should be <100ms globally
150
+ 3. **Error Rate**: Should be <0.1%
151
+ 4. **Bandwidth**: Track for cost optimization
152
+
153
+ ### Health Check Endpoint
154
+
155
+ Create a health check at `/widget/health.json`:
156
+
157
+ ```json
158
+ {
159
+ "status": "healthy",
160
+ "version": "2.0.0",
161
+ "timestamp": "2024-01-01T00:00:00Z"
162
+ }
163
+ ```
164
+
165
+ ## Rollback Procedure
166
+
167
+ If a deployment causes issues:
168
+
169
+ 1. **For versioned URLs**: Deploy the previous version to the major version directory
170
+ 2. **For latest URL**: Update the latest directory to point to the previous stable version
171
+
172
+ ```bash
173
+ # Rollback latest to v2.0.0
174
+ aws s3 sync s3://cdn-ihooman-widget/widget/v2.0.0/ \
175
+ s3://cdn-ihooman-widget/widget/latest/ \
176
+ --cache-control "public, max-age=300"
177
+
178
+ # Invalidate latest cache
179
+ aws cloudfront create-invalidation \
180
+ --distribution-id YOUR_DISTRIBUTION_ID \
181
+ --paths "/widget/latest/*"
182
+ ```
183
+
184
+ ## Version Management
185
+
186
+ ### Semantic Versioning
187
+
188
+ - **Major version (v2/)**: Updated only for breaking changes
189
+ - **Minor/Patch versions (v2.1.0/)**: Immutable, never updated
190
+ - **Latest**: Always points to the most recent stable release
191
+
192
+ ### Release Process
193
+
194
+ 1. Build new version: `npm run build:cdn`
195
+ 2. Upload new version directory (e.g., `v2.1.1/`)
196
+ 3. Update major version directory (`v2/`) with new content
197
+ 4. Update `latest/` directory with new content
198
+ 5. Invalidate CDN cache for `latest/` and major version
199
+ 6. Update `manifest.json` with new SRI hashes
@@ -0,0 +1,66 @@
1
+ # SRI Hashes for @ihooman/chat-widget
2
+
3
+ ## Version: 2.0.0
4
+
5
+ Build Date: 2026-01-31T15:26:43.871Z
6
+
7
+ ## Subresource Integrity (SRI) Hashes
8
+
9
+ Use these hashes to ensure the integrity of the widget script when loading from CDN.
10
+
11
+ ### Minified Bundle (Recommended for Production)
12
+
13
+ | Version | URL | SRI Hash |
14
+ |---------|-----|----------|
15
+ | Major (v2) | `https://cdn.ihooman.ai/widget/v2/chat.min.js` | `sha384-mlEtuVKMa+PyLTHKqrCGcvMEKTbkhS4wZbVw89B39K3f7WnGjXkh5N672KmRXPMH` |
16
+ | Full (v2.0.0) | `https://cdn.ihooman.ai/widget/v2.0.0/chat.min.js` | `sha384-mlEtuVKMa+PyLTHKqrCGcvMEKTbkhS4wZbVw89B39K3f7WnGjXkh5N672KmRXPMH` |
17
+ | Latest | `https://cdn.ihooman.ai/widget/latest/chat.min.js` | *(SRI not recommended for latest)* |
18
+
19
+ ### Unminified Bundle (For Development/Debugging)
20
+
21
+ | Version | URL | SRI Hash |
22
+ |---------|-----|----------|
23
+ | Major (v2) | `https://cdn.ihooman.ai/widget/v2/chat.js` | `sha384-zCM1t6eGYjrL9CIiDq2M+sJzCcPkXGi8UKO6OMglPGsb/vGj6N2urtUat80fzKGE` |
24
+ | Full (v2.0.0) | `https://cdn.ihooman.ai/widget/v2.0.0/chat.js` | `sha384-zCM1t6eGYjrL9CIiDq2M+sJzCcPkXGi8UKO6OMglPGsb/vGj6N2urtUat80fzKGE` |
25
+ | Latest | `https://cdn.ihooman.ai/widget/latest/chat.js` | *(SRI not recommended for latest)* |
26
+
27
+ ## Usage Examples
28
+
29
+ ### With SRI (Recommended for versioned URLs)
30
+
31
+ ```html
32
+ <script src="https://cdn.ihooman.ai/widget/v2.0.0/chat.min.js"
33
+ integrity="sha384-mlEtuVKMa+PyLTHKqrCGcvMEKTbkhS4wZbVw89B39K3f7WnGjXkh5N672KmRXPMH"
34
+ crossorigin="anonymous"></script>
35
+ <script>
36
+ IhoomanChat.init({
37
+ widgetId: 'YOUR_WIDGET_ID'
38
+ });
39
+ </script>
40
+ ```
41
+
42
+ ### Without SRI (For latest URL)
43
+
44
+ ```html
45
+ <script src="https://cdn.ihooman.ai/widget/latest/chat.min.js"></script>
46
+ <script>
47
+ IhoomanChat.init({
48
+ widgetId: 'YOUR_WIDGET_ID'
49
+ });
50
+ </script>
51
+ ```
52
+
53
+ ## Notes
54
+
55
+ - **SRI hashes are recommended** for versioned URLs to ensure script integrity
56
+ - **SRI is not recommended** for the `latest` URL as the content changes with each release
57
+ - The `crossorigin="anonymous"` attribute is required when using SRI
58
+ - Major version URLs (e.g., `/v2/`) always point to the latest patch within that major version
59
+ - Full version URLs (e.g., `/v2.1.0/`) are immutable and will never change
60
+
61
+ ## Cache Headers
62
+
63
+ | URL Type | Cache-Control |
64
+ |----------|---------------|
65
+ | Versioned (`/v2/`, `/v2.1.0/`) | `public, max-age=31536000, immutable` |
66
+ | Latest (`/latest/`) | `public, max-age=300` |
@@ -0,0 +1,203 @@
1
+ {
2
+ "$schema": "https://developers.cloudflare.com/api/",
3
+ "_comment": "Cloudflare Configuration for Ihooman Chat Widget CDN",
4
+ "zone": {
5
+ "name": "ihooman.ai",
6
+ "settings": {
7
+ "ssl": "full_strict",
8
+ "min_tls_version": "1.2",
9
+ "http3": "on",
10
+ "brotli": "on",
11
+ "minify": {
12
+ "js": false,
13
+ "css": false,
14
+ "html": false
15
+ }
16
+ }
17
+ },
18
+ "dns_records": [
19
+ {
20
+ "type": "CNAME",
21
+ "name": "cdn",
22
+ "content": "cdn-ihooman-widget.r2.cloudflarestorage.com",
23
+ "proxied": true,
24
+ "comment": "CDN subdomain for widget distribution"
25
+ }
26
+ ],
27
+ "page_rules": [
28
+ {
29
+ "_comment": "Versioned URLs - Long cache with immutable",
30
+ "targets": [
31
+ {
32
+ "target": "url",
33
+ "constraint": {
34
+ "operator": "matches",
35
+ "value": "cdn.ihooman.ai/widget/v*"
36
+ }
37
+ }
38
+ ],
39
+ "actions": [
40
+ {
41
+ "id": "cache_level",
42
+ "value": "cache_everything"
43
+ },
44
+ {
45
+ "id": "edge_cache_ttl",
46
+ "value": 31536000
47
+ },
48
+ {
49
+ "id": "browser_cache_ttl",
50
+ "value": 31536000
51
+ }
52
+ ],
53
+ "priority": 1,
54
+ "status": "active"
55
+ },
56
+ {
57
+ "_comment": "Latest URL - Short cache",
58
+ "targets": [
59
+ {
60
+ "target": "url",
61
+ "constraint": {
62
+ "operator": "matches",
63
+ "value": "cdn.ihooman.ai/widget/latest/*"
64
+ }
65
+ }
66
+ ],
67
+ "actions": [
68
+ {
69
+ "id": "cache_level",
70
+ "value": "cache_everything"
71
+ },
72
+ {
73
+ "id": "edge_cache_ttl",
74
+ "value": 300
75
+ },
76
+ {
77
+ "id": "browser_cache_ttl",
78
+ "value": 300
79
+ }
80
+ ],
81
+ "priority": 2,
82
+ "status": "active"
83
+ }
84
+ ],
85
+ "cache_rules": [
86
+ {
87
+ "name": "Widget Versioned Cache",
88
+ "description": "Cache versioned widget files for 1 year",
89
+ "expression": "(http.host eq \"cdn.ihooman.ai\" and starts_with(http.request.uri.path, \"/widget/v\"))",
90
+ "action": "set_cache_settings",
91
+ "action_parameters": {
92
+ "cache": true,
93
+ "edge_ttl": {
94
+ "mode": "override_origin",
95
+ "default": 31536000
96
+ },
97
+ "browser_ttl": {
98
+ "mode": "override_origin",
99
+ "default": 31536000
100
+ }
101
+ }
102
+ },
103
+ {
104
+ "name": "Widget Latest Cache",
105
+ "description": "Cache latest widget files for 5 minutes",
106
+ "expression": "(http.host eq \"cdn.ihooman.ai\" and starts_with(http.request.uri.path, \"/widget/latest/\"))",
107
+ "action": "set_cache_settings",
108
+ "action_parameters": {
109
+ "cache": true,
110
+ "edge_ttl": {
111
+ "mode": "override_origin",
112
+ "default": 300
113
+ },
114
+ "browser_ttl": {
115
+ "mode": "override_origin",
116
+ "default": 300
117
+ }
118
+ }
119
+ }
120
+ ],
121
+ "transform_rules": {
122
+ "response_headers": [
123
+ {
124
+ "name": "Widget CORS Headers",
125
+ "description": "Add CORS headers for widget requests",
126
+ "expression": "(http.host eq \"cdn.ihooman.ai\" and starts_with(http.request.uri.path, \"/widget/\"))",
127
+ "action": "set",
128
+ "action_parameters": {
129
+ "headers": [
130
+ {
131
+ "name": "Access-Control-Allow-Origin",
132
+ "value": "*"
133
+ },
134
+ {
135
+ "name": "Access-Control-Allow-Methods",
136
+ "value": "GET, HEAD, OPTIONS"
137
+ },
138
+ {
139
+ "name": "Access-Control-Allow-Headers",
140
+ "value": "Content-Type, Accept, Origin"
141
+ },
142
+ {
143
+ "name": "Access-Control-Max-Age",
144
+ "value": "86400"
145
+ },
146
+ {
147
+ "name": "X-Content-Type-Options",
148
+ "value": "nosniff"
149
+ },
150
+ {
151
+ "name": "X-Frame-Options",
152
+ "value": "DENY"
153
+ },
154
+ {
155
+ "name": "Referrer-Policy",
156
+ "value": "strict-origin-when-cross-origin"
157
+ }
158
+ ]
159
+ }
160
+ },
161
+ {
162
+ "name": "Widget Versioned Cache Headers",
163
+ "description": "Add immutable cache header for versioned files",
164
+ "expression": "(http.host eq \"cdn.ihooman.ai\" and starts_with(http.request.uri.path, \"/widget/v\") and not starts_with(http.request.uri.path, \"/widget/latest/\"))",
165
+ "action": "set",
166
+ "action_parameters": {
167
+ "headers": [
168
+ {
169
+ "name": "Cache-Control",
170
+ "value": "public, max-age=31536000, immutable"
171
+ }
172
+ ]
173
+ }
174
+ },
175
+ {
176
+ "name": "Widget Latest Cache Headers",
177
+ "description": "Add short cache header for latest files",
178
+ "expression": "(http.host eq \"cdn.ihooman.ai\" and starts_with(http.request.uri.path, \"/widget/latest/\"))",
179
+ "action": "set",
180
+ "action_parameters": {
181
+ "headers": [
182
+ {
183
+ "name": "Cache-Control",
184
+ "value": "public, max-age=300"
185
+ }
186
+ ]
187
+ }
188
+ }
189
+ ]
190
+ },
191
+ "r2_bucket": {
192
+ "name": "cdn-ihooman-widget",
193
+ "location": "auto",
194
+ "cors_rules": [
195
+ {
196
+ "allowed_origins": ["*"],
197
+ "allowed_methods": ["GET", "HEAD"],
198
+ "allowed_headers": ["*"],
199
+ "max_age_seconds": 86400
200
+ }
201
+ ]
202
+ }
203
+ }