tchao 0.1.2 → 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 CHANGED
@@ -4,8 +4,6 @@ JavaScript SDK for integrating the Tchao chat widget into your application.
4
4
 
5
5
  ## Installation
6
6
 
7
- ### Option 1: npm package
8
-
9
7
  ```bash
10
8
  npm install tchao
11
9
  # or
@@ -14,146 +12,191 @@ pnpm add tchao
14
12
  yarn add tchao
15
13
  ```
16
14
 
17
- ### Option 2: Script tag
15
+ ## Quick Start
18
16
 
19
- ```html
20
- <script src="https://tchao.app/widget.js" data-website-id="your-website-id"></script>
17
+ ### React (Recommended)
18
+
19
+ ```tsx
20
+ import { useTchao } from "tchao/react";
21
+
22
+ function App() {
23
+ const { isReady, open, identify } = useTchao({
24
+ websiteId: "your-website-id",
25
+ });
26
+
27
+ // Identify user when ready
28
+ useEffect(() => {
29
+ if (isReady && user) {
30
+ identify({ email: user.email, name: user.name });
31
+ }
32
+ }, [isReady, user, identify]);
33
+
34
+ return <button onClick={() => open()}>Chat with us</button>;
35
+ }
21
36
  ```
22
37
 
23
- ## Usage
38
+ ### React Provider (Simpler)
39
+
40
+ ```tsx
41
+ import { TchaoProvider } from "tchao/react";
42
+
43
+ function Layout({ children }) {
44
+ return (
45
+ <>
46
+ <TchaoProvider
47
+ websiteId="your-website-id"
48
+ visitor={{ email: user?.email, name: user?.name }}
49
+ />
50
+ {children}
51
+ </>
52
+ );
53
+ }
54
+ ```
24
55
 
25
- ### npm package
56
+ ### Vanilla JavaScript
26
57
 
27
58
  ```typescript
28
- import { Tchao } from 'tchao';
59
+ import { tchao } from "tchao";
29
60
 
30
- // Initialize the widget
31
- const widget = await Tchao.init({
32
- websiteId: 'your-website-id'
33
- });
61
+ // Initialize (call once)
62
+ await tchao.init({ websiteId: "your-website-id" });
34
63
 
35
- // Open the chat window
36
- widget.open();
64
+ // All methods are safe - no try/catch needed
65
+ tchao.identify({ email: "user@example.com" });
66
+ tchao.open();
37
67
  ```
38
68
 
39
- ### Script tag (global object)
69
+ ### Script Tag
40
70
 
41
71
  ```html
42
- <script src="https://tchao.app/widget.js" data-website-id="your-website-id"></script>
72
+ <script
73
+ src="https://tchao.app/widget.js"
74
+ data-website-id="your-website-id"
75
+ ></script>
43
76
  <script>
44
- // Widget auto-initializes, access via global object
45
- window.Tchao.open();
46
-
47
- // Listen for events
48
- window.Tchao.on('ready', () => {
49
- console.log('Widget ready!');
50
- });
77
+ // Widget auto-initializes
78
+ window.Tchao.identify({ email: "user@example.com" });
51
79
  </script>
52
80
  ```
53
81
 
54
82
  ## API Reference
55
83
 
56
- ### `Tchao.init(config)` (npm only)
57
-
58
- Initialize the Tchao widget programmatically.
59
-
60
- ```typescript
61
- const widget = await Tchao.init({
62
- websiteId: 'your-website-id', // Required
63
- host: 'https://tchao.app' // Optional, for self-hosted instances
64
- });
84
+ ### React Hook: `useTchao(config)`
85
+
86
+ ```tsx
87
+ import { useTchao } from "tchao/react";
88
+
89
+ const {
90
+ isReady, // boolean - widget is initialized
91
+ isLoading, // boolean - widget is loading
92
+ error, // Error | null - initialization error
93
+ show, // () => void
94
+ hide, // () => void
95
+ toggle, // () => void
96
+ open, // (message?: string) => void
97
+ identify, // (info: VisitorInfo) => void
98
+ config, // () => Partial<WidgetConfig>
99
+ on, // (event, callback) => void
100
+ off, // (event, callback) => void
101
+ } = useTchao({ websiteId: "..." });
65
102
  ```
66
103
 
67
- Returns a `Promise<TchaoInstance>`.
68
-
69
- ### Instance Methods
104
+ ### Safe API: `tchao`
70
105
 
71
- #### `widget.show()`
72
- Show the widget launcher button.
73
-
74
- #### `widget.hide()`
75
- Hide the widget launcher button.
76
-
77
- #### `widget.toggle()`
78
- Toggle the chat window open/closed.
79
-
80
- #### `widget.open()`
81
- Open the chat window.
82
-
83
- #### `widget.identify(info)`
84
- Identify the visitor with their information.
106
+ All methods are safe to call at any time - they will queue and execute when ready.
85
107
 
86
108
  ```typescript
87
- widget.identify({
88
- email: 'user@example.com',
89
- name: 'John Doe',
90
- avatar: 'https://example.com/avatar.jpg',
91
- metadata: {
92
- plan: 'pro',
93
- userId: '12345'
94
- }
109
+ import { tchao } from "tchao";
110
+
111
+ // Initialize
112
+ await tchao.init({ websiteId: "your-website-id" });
113
+
114
+ // Control methods (safe before/after init)
115
+ tchao.show();
116
+ tchao.hide();
117
+ tchao.toggle();
118
+ tchao.open();
119
+ tchao.open("I need help with...");
120
+
121
+ // Identify visitor
122
+ tchao.identify({
123
+ email: "user@example.com",
124
+ name: "John Doe",
125
+ avatar: "https://example.com/avatar.jpg",
126
+ metadata: { plan: "pro", userId: "123" },
95
127
  });
96
- ```
97
128
 
98
- #### `widget.config(options)`
99
- Update widget configuration.
129
+ // Events
130
+ tchao.on("message", (msg) => console.log(msg));
131
+ tchao.on("open", () => console.log("Opened"));
132
+ tchao.on("close", () => console.log("Closed"));
133
+ tchao.on("ready", () => console.log("Ready"));
100
134
 
101
- ```typescript
102
- widget.config({
103
- position: 'bottom-left', // 'bottom-right' | 'bottom-left'
104
- primaryColor: '#6366f1',
105
- themeMode: 'dark' // 'light' | 'dark' | 'system'
106
- });
135
+ // Cleanup
136
+ tchao.destroy();
137
+
138
+ // Status
139
+ tchao.isReady(); // boolean
107
140
  ```
108
141
 
109
- #### `widget.on(event, callback)`
110
- Subscribe to widget events.
142
+ ### Init Config
111
143
 
112
144
  ```typescript
113
- widget.on('message', (message) => {
114
- console.log('New message:', message.content);
115
- });
116
-
117
- widget.on('open', () => {
118
- console.log('Chat opened');
119
- });
120
-
121
- widget.on('close', () => {
122
- console.log('Chat closed');
123
- });
124
-
125
- widget.on('ready', () => {
126
- console.log('Widget ready');
145
+ tchao.init({
146
+ websiteId: "required",
147
+ host: "https://tchao.app", // optional, for self-hosted
148
+ position: "bottom-right", // "bottom-right" | "bottom-left"
149
+ primaryColor: "#6366f1",
150
+ themeMode: "system", // "light" | "dark" | "system"
151
+ widgetStyle: "bubble", // "bubble" | "name_line" | "question_cta"
152
+ agentName: "Support",
153
+ agentRole: "Customer Support",
154
+ agentImage: "https://...",
155
+ agentWelcomeMessage: "Hi! How can I help?",
156
+ hidePoweredBy: false,
127
157
  });
128
158
  ```
129
159
 
130
- #### `widget.off(event, callback)`
131
- Unsubscribe from widget events.
160
+ ### Events
132
161
 
133
- ```typescript
134
- const handleMessage = (message) => console.log(message);
135
- widget.on('message', handleMessage);
136
- widget.off('message', handleMessage);
137
- ```
162
+ | Event | Callback | Description |
163
+ |-------|----------|-------------|
164
+ | `message` | `(message: Message) => void` | New message received |
165
+ | `open` | `() => void` | Chat window opened |
166
+ | `close` | `() => void` | Chat window closed |
167
+ | `ready` | `() => void` | Widget initialized |
138
168
 
139
- #### `widget.destroy()` (npm only)
140
- Clean up and remove the widget from the page.
169
+ ### TypeScript
141
170
 
142
171
  ```typescript
143
- widget.destroy();
172
+ import type {
173
+ TchaoConfig,
174
+ TchaoInstance,
175
+ VisitorInfo,
176
+ Message,
177
+ WidgetConfig,
178
+ TchaoEvent,
179
+ TchaoEventMap,
180
+ } from "tchao";
181
+
182
+ // React types
183
+ import type { UseTchaoOptions, UseTchaoReturn } from "tchao/react";
144
184
  ```
145
185
 
146
- ## TypeScript
186
+ ## Migration from v0.1.3
147
187
 
148
- Full TypeScript support is included. Import types as needed:
188
+ The API is backward compatible. New additions:
149
189
 
150
190
  ```typescript
151
- import type {
152
- TchaoConfig,
153
- TchaoInstance,
154
- VisitorInfo,
155
- Message
156
- } from 'tchao';
191
+ // New: Safe API (no try/catch needed)
192
+ import { tchao } from "tchao";
193
+ tchao.identify({ email: "..." }); // Works before init!
194
+
195
+ // New: React hook
196
+ import { useTchao } from "tchao/react";
197
+
198
+ // New: React provider
199
+ import { TchaoProvider } from "tchao/react";
157
200
  ```
158
201
 
159
202
  ## License
package/dist/npm.d.mts CHANGED
@@ -1,97 +1,134 @@
1
- type SenderType = "VISITOR" | "AGENT" | "AI" | "SYSTEM";
2
- type ConversationStatus = "OPEN" | "IN_PROGRESS" | "CLOSED";
3
- type MessageStatus = "sending" | "sent" | "failed";
4
- type WidgetPosition = "bottom-right" | "bottom-left";
5
- type WidgetStyle = "bubble" | "name_line" | "question_cta";
6
- type ThemeMode = "light" | "dark" | "system";
7
1
  type VisitorInfo = {
8
2
  name?: string;
9
3
  email?: string;
10
4
  avatar?: string;
11
5
  metadata?: Record<string, unknown>;
12
6
  };
13
- type MessageReaction = {
14
- emoji: string;
15
- userIds: string[];
16
- };
17
- type Message = {
18
- id: string;
19
- content: string;
20
- senderType: SenderType;
21
- senderId: string;
22
- screenshot?: string | null;
23
- image?: string | null;
24
- timestamp: number;
25
- status?: MessageStatus;
26
- reactions?: MessageReaction[] | null;
27
- };
28
7
  type WidgetConfig = {
29
8
  websiteId: string;
30
- apiBaseUrl: string;
9
+ position?: "bottom-right" | "bottom-left";
10
+ primaryColor?: string;
11
+ widgetStyle?: "bubble" | "name_line" | "question_cta";
12
+ themeMode?: "light" | "dark" | "system";
13
+ agentName?: string;
14
+ agentRole?: string;
15
+ agentImage?: string;
16
+ agentWelcomeMessage?: string;
17
+ hidePoweredBy?: boolean;
18
+ bubbleIcon?: string;
19
+ };
20
+ type TchaoConfig = {
21
+ websiteId: string;
22
+ host?: string;
31
23
  convexUrl?: string;
32
- position?: WidgetPosition;
24
+ position?: "bottom-right" | "bottom-left";
33
25
  primaryColor?: string;
34
- widgetStyle?: WidgetStyle;
35
- themeMode?: ThemeMode;
26
+ widgetStyle?: "bubble" | "name_line" | "question_cta";
27
+ themeMode?: "light" | "dark" | "system";
28
+ agentName?: string;
29
+ agentRole?: string;
30
+ agentImage?: string;
31
+ agentWelcomeMessage?: string;
32
+ hidePoweredBy?: boolean;
33
+ bubbleIcon?: string;
36
34
  };
37
- type SDKEventMap = {
35
+ type Message = {
36
+ content: string;
37
+ sender: string;
38
+ timestamp: number;
39
+ };
40
+ type TchaoEventMap = {
38
41
  message: (message: Message) => void;
39
42
  open: () => void;
40
43
  close: () => void;
41
44
  ready: () => void;
42
45
  };
43
- type SDKMethods = {
46
+ type TchaoEvent = keyof TchaoEventMap;
47
+ type TchaoInstance = {
44
48
  show: () => void;
45
49
  hide: () => void;
46
50
  toggle: () => void;
47
- open: () => void;
51
+ open: (message?: string) => void;
48
52
  identify: (info: VisitorInfo) => void;
49
- config: (opts: Partial<WidgetConfig>) => void;
50
- on: <K extends keyof SDKEventMap>(event: K, callback: SDKEventMap[K]) => void;
51
- off: <K extends keyof SDKEventMap>(event: K, callback: SDKEventMap[K]) => void;
53
+ config: () => Partial<WidgetConfig>;
54
+ on: <E extends TchaoEvent>(event: E, callback: TchaoEventMap[E]) => void;
55
+ off: <E extends TchaoEvent>(event: E, callback: TchaoEventMap[E]) => void;
56
+ destroy: () => void;
57
+ isReady: () => boolean;
52
58
  };
53
-
54
- declare class TchaoSDK implements SDKMethods {
55
- private readonly listeners;
56
- private showCallback;
57
- private hideCallback;
58
- private toggleCallback;
59
- private openCallback;
60
- private identifyCallback;
61
- private configCallback;
62
- setCallbacks(callbacks: {
63
- show: () => void;
64
- hide: () => void;
65
- toggle: () => void;
66
- open: () => void;
67
- identify: (info: VisitorInfo) => void;
68
- config: (opts: Partial<WidgetConfig>) => void;
69
- }): void;
70
- show(): void;
71
- hide(): void;
72
- toggle(): void;
73
- open(): void;
74
- identify(info: VisitorInfo): void;
75
- config(opts: Partial<WidgetConfig>): void;
76
- on<K extends keyof SDKEventMap>(event: K, callback: SDKEventMap[K]): void;
77
- off<K extends keyof SDKEventMap>(event: K, callback: SDKEventMap[K]): void;
78
- emit<K extends keyof SDKEventMap>(event: K, ...args: Parameters<SDKEventMap[K]>): void;
79
- }
80
-
81
- type TchaoInitConfig = {
82
- websiteId: string;
83
- host?: string;
59
+ type InternalTchaoInstance = {
60
+ show: () => void;
61
+ hide: () => void;
62
+ toggle: () => void;
63
+ open: (message?: string) => void;
64
+ identify: (info: VisitorInfo) => void;
65
+ config: () => Partial<WidgetConfig>;
66
+ on: (event: string, callback: (...args: unknown[]) => void) => void;
67
+ off: (event: string, callback: (...args: unknown[]) => void) => void;
84
68
  };
85
-
86
- type TchaoConfig = TchaoInitConfig;
87
- type TchaoInstance = SDKMethods & {
69
+ declare global {
70
+ interface Window {
71
+ Tchao?: InternalTchaoInstance;
72
+ __TCHAO_CONFIG__?: TchaoConfig;
73
+ }
74
+ }
75
+ declare function init(config: TchaoConfig): Promise<TchaoInstance>;
76
+ /**
77
+ * Safe API that works before initialization.
78
+ * Calls are queued and executed once the widget is ready.
79
+ */
80
+ declare const tchao: {
81
+ /**
82
+ * Initialize the widget. Returns a promise that resolves with the instance.
83
+ */
84
+ init: typeof init;
85
+ /**
86
+ * Show the widget launcher. Safe to call before init.
87
+ */
88
+ show: () => void;
89
+ /**
90
+ * Hide the widget launcher. Safe to call before init.
91
+ */
92
+ hide: () => void;
93
+ /**
94
+ * Toggle the chat window. Safe to call before init.
95
+ */
96
+ toggle: () => void;
97
+ /**
98
+ * Open the chat window. Safe to call before init.
99
+ */
100
+ open: (message?: string) => void;
101
+ /**
102
+ * Identify the visitor. Safe to call before init.
103
+ */
104
+ identify: (info: VisitorInfo) => void;
105
+ /**
106
+ * Get the current widget configuration.
107
+ */
108
+ config: () => Partial<WidgetConfig>;
109
+ /**
110
+ * Subscribe to widget events. Safe to call before init.
111
+ */
112
+ on: <E extends TchaoEvent>(event: E, callback: TchaoEventMap[E]) => void;
113
+ /**
114
+ * Unsubscribe from widget events.
115
+ */
116
+ off: <E extends TchaoEvent>(event: E, callback: TchaoEventMap[E]) => void;
117
+ /**
118
+ * Destroy the widget and clean up resources.
119
+ */
88
120
  destroy: () => void;
121
+ /**
122
+ * Check if the widget is ready.
123
+ */
124
+ isReady: () => boolean;
125
+ /**
126
+ * Get the current instance (null if not initialized).
127
+ */
128
+ getInstance: () => TchaoInstance | null;
89
129
  };
90
- type TchaoEvents = SDKEventMap;
91
-
92
- declare function init(config: TchaoConfig): Promise<TchaoInstance>;
93
130
  declare const Tchao: {
94
131
  init: typeof init;
95
132
  };
96
133
 
97
- export { type ConversationStatus, type Message, type MessageReaction, type MessageStatus, type SenderType, Tchao, type TchaoConfig, type TchaoEvents, type TchaoInstance, TchaoSDK, type ThemeMode, type VisitorInfo, type WidgetConfig, type WidgetPosition, type WidgetStyle, Tchao as default, init };
134
+ export { type Message, Tchao, type TchaoConfig, type TchaoEvent, type TchaoEventMap, type TchaoInstance, type VisitorInfo, type WidgetConfig, Tchao as default, init, tchao };