@happiest-team/ai-chat-core 1.0.1

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,56 @@
1
+ # @happiest-team/ai-chat-core
2
+
3
+ [![NPM Version](https://img.shields.io/npm/v/@happiest-team/ai-chat-core.svg?style=flat-square)](https://www.npmjs.com/package/@happiest-team/ai-chat-core)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Strict-blue.svg?style=flat-square)](https://www.typescriptlang.org/)
6
+
7
+ The low-level, headless API client and state management engine for **Happiest Chat**.
8
+
9
+ This package contains **zero UI** and is framework-agnostic. It is the underlying engine powering `@happiest-team/ai-chat` and `@happiest-team/ai-chat-native`. Use this package if you are building an integration for Vue, Angular, Svelte, or Vanilla JS.
10
+
11
+ ## 🚀 Features
12
+
13
+ - **Framework Agnostic:** Runs in browser environments, Node.js, edge workers, and mobile architectures.
14
+ - **Pure State Management:** Exposes reactive session initialization, message sending, and token validation logic.
15
+ - **Zero Dependencies:** Tiny footprint to keep your bundle sizes heavily optimized.
16
+
17
+ ## 📦 Installation
18
+
19
+ ```bash
20
+ npm install @happiest-team/ai-chat-core
21
+ ```
22
+
23
+ ## 🛠 API Reference
24
+
25
+ ### `createHappiestClient(clubId, config?)`
26
+
27
+ Initializes the core client that manages network interactions.
28
+
29
+ ```typescript
30
+ import { createHappiestClient } from '@happiest-team/ai-chat-core';
31
+
32
+ const client = createHappiestClient('YOUR_CLUB_ID', {
33
+ integrationId: 'OPTIONAL_INTEGRATION_ID',
34
+ theme: { primary: '#000000' }
35
+ });
36
+ ```
37
+
38
+ ### Session Management
39
+
40
+ ```typescript
41
+ // 1. Initialize the session & fetch widget config
42
+ const { token, config } = await client.initSession({
43
+ userId: 'usr_123',
44
+ metadata: { plan: 'pro' }
45
+ });
46
+
47
+ // 2. Send a message to the AI agent
48
+ const reply = await client.sendMessage('What are your opening hours?', {
49
+ onStream: (chunk) => {
50
+ console.log("Streaming response...", chunk);
51
+ }
52
+ });
53
+ ```
54
+
55
+ ## 📄 License
56
+ MIT © Happiest
@@ -0,0 +1,43 @@
1
+ interface HappiestConfig {
2
+ publishableKey: string;
3
+ gatewayUrl?: string;
4
+ }
5
+ interface ChatMessage {
6
+ id: string;
7
+ text: string;
8
+ isUser: boolean;
9
+ createdAt: number;
10
+ status?: 'sending' | 'delivered' | 'failed';
11
+ }
12
+ interface HappiestState {
13
+ status: 'idle' | 'connecting' | 'connected' | 'error';
14
+ isTyping: boolean;
15
+ messages: ChatMessage[];
16
+ sessionToken: string | null;
17
+ widgetConfig: Record<string, any>;
18
+ error: string | null;
19
+ }
20
+ type EventCallback = (state: HappiestState) => void;
21
+
22
+ declare class HappiestClient {
23
+ private config;
24
+ private state;
25
+ private listeners;
26
+ private apiUrl;
27
+ private conversationId?;
28
+ constructor(config: HappiestConfig);
29
+ private updateState;
30
+ subscribe(callback: EventCallback): () => void;
31
+ private notifyListeners;
32
+ getState(): HappiestState;
33
+ private getCacheKey;
34
+ private getCache;
35
+ private setCache;
36
+ clearSession(): void;
37
+ initSession(): Promise<void>;
38
+ sendMessage(text: string): Promise<void>;
39
+ retryMessage(id: string): Promise<void>;
40
+ private _sendToNetwork;
41
+ }
42
+
43
+ export { type ChatMessage, type EventCallback, HappiestClient, type HappiestConfig, type HappiestState };
@@ -0,0 +1,43 @@
1
+ interface HappiestConfig {
2
+ publishableKey: string;
3
+ gatewayUrl?: string;
4
+ }
5
+ interface ChatMessage {
6
+ id: string;
7
+ text: string;
8
+ isUser: boolean;
9
+ createdAt: number;
10
+ status?: 'sending' | 'delivered' | 'failed';
11
+ }
12
+ interface HappiestState {
13
+ status: 'idle' | 'connecting' | 'connected' | 'error';
14
+ isTyping: boolean;
15
+ messages: ChatMessage[];
16
+ sessionToken: string | null;
17
+ widgetConfig: Record<string, any>;
18
+ error: string | null;
19
+ }
20
+ type EventCallback = (state: HappiestState) => void;
21
+
22
+ declare class HappiestClient {
23
+ private config;
24
+ private state;
25
+ private listeners;
26
+ private apiUrl;
27
+ private conversationId?;
28
+ constructor(config: HappiestConfig);
29
+ private updateState;
30
+ subscribe(callback: EventCallback): () => void;
31
+ private notifyListeners;
32
+ getState(): HappiestState;
33
+ private getCacheKey;
34
+ private getCache;
35
+ private setCache;
36
+ clearSession(): void;
37
+ initSession(): Promise<void>;
38
+ sendMessage(text: string): Promise<void>;
39
+ retryMessage(id: string): Promise<void>;
40
+ private _sendToNetwork;
41
+ }
42
+
43
+ export { type ChatMessage, type EventCallback, HappiestClient, type HappiestConfig, type HappiestState };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ 'use strict';var c=class{config;state;listeners=new Set;apiUrl;conversationId;constructor(e){this.config=e,this.apiUrl=e.gatewayUrl||"https://www.happiest.team/api";let t=this.getCache("token"),s=this.getCache("messages")||[];this.state={status:t?"connected":"idle",isTyping:false,messages:s,sessionToken:t,widgetConfig:{},error:null};}updateState(e){this.state={...this.state,...e},this.notifyListeners();}subscribe(e){return this.listeners.add(e),e(this.state),()=>this.listeners.delete(e)}notifyListeners(){this.listeners.forEach(e=>e(this.state));}getState(){return this.state}getCacheKey(e){return `happiest_${e}_${this.config.publishableKey}`}getCache(e){if(typeof window>"u")return null;try{let t=localStorage.getItem(this.getCacheKey(e));return t?JSON.parse(t):null}catch{return null}}setCache(e,t){if(!(typeof window>"u"))try{localStorage.setItem(this.getCacheKey(e),JSON.stringify(t));}catch(s){console.warn("[Happiest] Failed to persist state",s);}}clearSession(){typeof window<"u"&&(localStorage.removeItem(this.getCacheKey("token")),localStorage.removeItem(this.getCacheKey("messages"))),this.updateState({status:"idle",sessionToken:null,messages:[],error:null}),this.conversationId=void 0;}async initSession(){if(!(this.state.status==="connected"&&this.state.sessionToken)){this.updateState({status:"connecting",error:null});try{let e=await fetch(`${this.apiUrl}/widget/v1/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({publishableKey:this.config.publishableKey})}),t=await e.json();if(!e.ok)throw new Error(t.error||"Failed to initialize session");let s=t.sessionToken||t.embedToken,a=t.widgetConfig||t.config||{};this.setCache("token",s),this.updateState({status:"connected",sessionToken:s,widgetConfig:a});}catch(e){let t=e instanceof Error?e.message:"Network error";this.updateState({status:"error",error:t});}}}async sendMessage(e){let t=e.trim();if(!t||!this.state.sessionToken)return;let s={id:Date.now().toString(),text:t,isUser:true,createdAt:Date.now(),status:"sending"},a=[...this.state.messages,s];this.setCache("messages",a),this.updateState({messages:a,isTyping:true,error:null}),await this._sendToNetwork(s.id,t);}async retryMessage(e){let t=this.state.messages.find(a=>a.id===e);if(!t||t.status!=="failed")return;let s=this.state.messages.map(a=>a.id===e?{...a,status:"sending"}:a);this.setCache("messages",s),this.updateState({messages:s,isTyping:true,error:null}),await this._sendToNetwork(e,t.text);}async _sendToNetwork(e,t){try{let s=await fetch(`${this.apiUrl}/widget/v1/chat`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.state.sessionToken}`},body:JSON.stringify({message:t,conversationId:this.conversationId})}),a=await s.json();if(!s.ok)throw new Error(a.error||"Failed to send message");a.conversationId&&(this.conversationId=a.conversationId);let i={id:(Date.now()+1).toString(),text:a.message||a.reply||"Thanks for your message.",isUser:!1,createdAt:Date.now()},o=[...this.state.messages.map(r=>r.id===e?{...r,status:"delivered"}:r),i];this.setCache("messages",o),this.updateState({messages:o,isTyping:!1});}catch(s){let a=s instanceof Error?s.message:"Message failed",i=this.state.messages.map(n=>n.id===e?{...n,status:"failed"}:n);this.setCache("messages",i),this.updateState({messages:i,isTyping:false,error:a});}}};
2
+ exports.HappiestClient=c;//# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"names":["HappiestClient","config","cachedToken","cachedMessages","newState","callback","listener","type","val","value","e","res","data","token","err","message","text","trimmed","userMsg","newMessages","id","msg","m","msgId","agentMsg","finalMessages","currentMessages"],"mappings":"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","file":"index.js","sourcesContent":["import { HappiestConfig, HappiestState, ChatMessage, EventCallback } from './types';\n\nexport class HappiestClient {\n private config: HappiestConfig;\n private state: HappiestState;\n private listeners: Set<EventCallback> = new Set();\n private apiUrl: string;\n private conversationId?: string;\n\n constructor(config: HappiestConfig) {\n this.config = config;\n this.apiUrl = config.gatewayUrl || 'https://www.happiest.team/api';\n \n // Load cached session if available\n const cachedToken = this.getCache('token');\n const cachedMessages = this.getCache('messages') || [];\n\n this.state = {\n status: cachedToken ? 'connected' : 'idle',\n isTyping: false,\n messages: cachedMessages,\n sessionToken: cachedToken,\n widgetConfig: {},\n error: null\n };\n }\n\n // --- Pub/Sub State Management ---\n \n private updateState(newState: Partial<HappiestState>) {\n this.state = { ...this.state, ...newState };\n this.notifyListeners();\n }\n\n public subscribe(callback: EventCallback): () => void {\n this.listeners.add(callback);\n callback(this.state); // Trigger immediately with current state\n return () => this.listeners.delete(callback);\n }\n\n private notifyListeners() {\n this.listeners.forEach(listener => listener(this.state));\n }\n\n public getState(): HappiestState {\n return this.state;\n }\n\n // --- Persistence ---\n\n private getCacheKey(type: 'token' | 'messages') {\n return `happiest_${type}_${this.config.publishableKey}`;\n }\n\n private getCache(type: 'token' | 'messages'): any {\n if (typeof window === 'undefined') return null;\n try {\n const val = localStorage.getItem(this.getCacheKey(type));\n return val ? JSON.parse(val) : null;\n } catch {\n return null;\n }\n }\n\n private setCache(type: 'token' | 'messages', value: any) {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(this.getCacheKey(type), JSON.stringify(value));\n } catch (e) {\n console.warn('[Happiest] Failed to persist state', e);\n }\n }\n\n public clearSession() {\n if (typeof window !== 'undefined') {\n localStorage.removeItem(this.getCacheKey('token'));\n localStorage.removeItem(this.getCacheKey('messages'));\n }\n this.updateState({\n status: 'idle',\n sessionToken: null,\n messages: [],\n error: null\n });\n this.conversationId = undefined;\n }\n\n // --- Network Actions ---\n\n public async initSession(): Promise<void> {\n if (this.state.status === 'connected' && this.state.sessionToken) {\n return; // Already initialized\n }\n\n this.updateState({ status: 'connecting', error: null });\n \n try {\n const res = await fetch(`${this.apiUrl}/widget/v1/init`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publishableKey: this.config.publishableKey })\n });\n \n const data = await res.json();\n \n if (!res.ok) {\n throw new Error(data.error || 'Failed to initialize session');\n }\n\n const token = data.sessionToken || data.embedToken;\n const config = data.widgetConfig || data.config || {};\n\n this.setCache('token', token);\n\n this.updateState({\n status: 'connected',\n sessionToken: token,\n widgetConfig: config,\n });\n\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Network error';\n this.updateState({ status: 'error', error: message });\n }\n }\n\n public async sendMessage(text: string): Promise<void> {\n const trimmed = text.trim();\n if (!trimmed || !this.state.sessionToken) return;\n\n // Optimistic update\n const userMsg: ChatMessage = {\n id: Date.now().toString(),\n text: trimmed,\n isUser: true,\n createdAt: Date.now(),\n status: 'sending'\n };\n\n const newMessages = [...this.state.messages, userMsg];\n this.setCache('messages', newMessages);\n \n this.updateState({\n messages: newMessages,\n isTyping: true,\n error: null\n });\n\n await this._sendToNetwork(userMsg.id, trimmed);\n }\n\n public async retryMessage(id: string): Promise<void> {\n const msg = this.state.messages.find(m => m.id === id);\n if (!msg || msg.status !== 'failed') return;\n \n // Optimistically set to sending again\n const newMessages = this.state.messages.map(m => m.id === id ? { ...m, status: 'sending' as const } : m);\n this.setCache('messages', newMessages);\n this.updateState({ messages: newMessages, isTyping: true, error: null });\n\n await this._sendToNetwork(id, msg.text);\n }\n\n private async _sendToNetwork(msgId: string, text: string): Promise<void> {\n try {\n const res = await fetch(`${this.apiUrl}/widget/v1/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.state.sessionToken}`\n },\n body: JSON.stringify({\n message: text,\n conversationId: this.conversationId\n })\n });\n\n const data = await res.json();\n \n if (!res.ok) {\n throw new Error(data.error || 'Failed to send message');\n }\n\n if (data.conversationId) {\n this.conversationId = data.conversationId;\n }\n\n const agentMsg: ChatMessage = {\n id: (Date.now() + 1).toString(),\n text: data.message || data.reply || 'Thanks for your message.',\n isUser: false,\n createdAt: Date.now()\n };\n\n // Find the user message and update its status to delivered\n const currentMessages = this.state.messages.map(m => m.id === msgId ? { ...m, status: 'delivered' as const } : m);\n const finalMessages = [...currentMessages, agentMsg];\n \n this.setCache('messages', finalMessages);\n this.updateState({\n messages: finalMessages,\n isTyping: false\n });\n\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Message failed';\n \n // Update user message status to failed\n const currentMessages = this.state.messages.map(m => m.id === msgId ? { ...m, status: 'failed' as const } : m);\n \n this.setCache('messages', currentMessages);\n this.updateState({ \n messages: currentMessages,\n isTyping: false, \n error: message \n });\n }\n }\n}\n"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+ var c=class{config;state;listeners=new Set;apiUrl;conversationId;constructor(e){this.config=e,this.apiUrl=e.gatewayUrl||"https://www.happiest.team/api";let t=this.getCache("token"),s=this.getCache("messages")||[];this.state={status:t?"connected":"idle",isTyping:false,messages:s,sessionToken:t,widgetConfig:{},error:null};}updateState(e){this.state={...this.state,...e},this.notifyListeners();}subscribe(e){return this.listeners.add(e),e(this.state),()=>this.listeners.delete(e)}notifyListeners(){this.listeners.forEach(e=>e(this.state));}getState(){return this.state}getCacheKey(e){return `happiest_${e}_${this.config.publishableKey}`}getCache(e){if(typeof window>"u")return null;try{let t=localStorage.getItem(this.getCacheKey(e));return t?JSON.parse(t):null}catch{return null}}setCache(e,t){if(!(typeof window>"u"))try{localStorage.setItem(this.getCacheKey(e),JSON.stringify(t));}catch(s){console.warn("[Happiest] Failed to persist state",s);}}clearSession(){typeof window<"u"&&(localStorage.removeItem(this.getCacheKey("token")),localStorage.removeItem(this.getCacheKey("messages"))),this.updateState({status:"idle",sessionToken:null,messages:[],error:null}),this.conversationId=void 0;}async initSession(){if(!(this.state.status==="connected"&&this.state.sessionToken)){this.updateState({status:"connecting",error:null});try{let e=await fetch(`${this.apiUrl}/widget/v1/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({publishableKey:this.config.publishableKey})}),t=await e.json();if(!e.ok)throw new Error(t.error||"Failed to initialize session");let s=t.sessionToken||t.embedToken,a=t.widgetConfig||t.config||{};this.setCache("token",s),this.updateState({status:"connected",sessionToken:s,widgetConfig:a});}catch(e){let t=e instanceof Error?e.message:"Network error";this.updateState({status:"error",error:t});}}}async sendMessage(e){let t=e.trim();if(!t||!this.state.sessionToken)return;let s={id:Date.now().toString(),text:t,isUser:true,createdAt:Date.now(),status:"sending"},a=[...this.state.messages,s];this.setCache("messages",a),this.updateState({messages:a,isTyping:true,error:null}),await this._sendToNetwork(s.id,t);}async retryMessage(e){let t=this.state.messages.find(a=>a.id===e);if(!t||t.status!=="failed")return;let s=this.state.messages.map(a=>a.id===e?{...a,status:"sending"}:a);this.setCache("messages",s),this.updateState({messages:s,isTyping:true,error:null}),await this._sendToNetwork(e,t.text);}async _sendToNetwork(e,t){try{let s=await fetch(`${this.apiUrl}/widget/v1/chat`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.state.sessionToken}`},body:JSON.stringify({message:t,conversationId:this.conversationId})}),a=await s.json();if(!s.ok)throw new Error(a.error||"Failed to send message");a.conversationId&&(this.conversationId=a.conversationId);let i={id:(Date.now()+1).toString(),text:a.message||a.reply||"Thanks for your message.",isUser:!1,createdAt:Date.now()},o=[...this.state.messages.map(r=>r.id===e?{...r,status:"delivered"}:r),i];this.setCache("messages",o),this.updateState({messages:o,isTyping:!1});}catch(s){let a=s instanceof Error?s.message:"Message failed",i=this.state.messages.map(n=>n.id===e?{...n,status:"failed"}:n);this.setCache("messages",i),this.updateState({messages:i,isTyping:false,error:a});}}};
2
+ export{c as HappiestClient};//# sourceMappingURL=index.mjs.map
3
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"names":["HappiestClient","config","cachedToken","cachedMessages","newState","callback","listener","type","val","value","e","res","data","token","err","message","text","trimmed","userMsg","newMessages","id","msg","m","msgId","agentMsg","finalMessages","currentMessages"],"mappings":"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","file":"index.mjs","sourcesContent":["import { HappiestConfig, HappiestState, ChatMessage, EventCallback } from './types';\n\nexport class HappiestClient {\n private config: HappiestConfig;\n private state: HappiestState;\n private listeners: Set<EventCallback> = new Set();\n private apiUrl: string;\n private conversationId?: string;\n\n constructor(config: HappiestConfig) {\n this.config = config;\n this.apiUrl = config.gatewayUrl || 'https://www.happiest.team/api';\n \n // Load cached session if available\n const cachedToken = this.getCache('token');\n const cachedMessages = this.getCache('messages') || [];\n\n this.state = {\n status: cachedToken ? 'connected' : 'idle',\n isTyping: false,\n messages: cachedMessages,\n sessionToken: cachedToken,\n widgetConfig: {},\n error: null\n };\n }\n\n // --- Pub/Sub State Management ---\n \n private updateState(newState: Partial<HappiestState>) {\n this.state = { ...this.state, ...newState };\n this.notifyListeners();\n }\n\n public subscribe(callback: EventCallback): () => void {\n this.listeners.add(callback);\n callback(this.state); // Trigger immediately with current state\n return () => this.listeners.delete(callback);\n }\n\n private notifyListeners() {\n this.listeners.forEach(listener => listener(this.state));\n }\n\n public getState(): HappiestState {\n return this.state;\n }\n\n // --- Persistence ---\n\n private getCacheKey(type: 'token' | 'messages') {\n return `happiest_${type}_${this.config.publishableKey}`;\n }\n\n private getCache(type: 'token' | 'messages'): any {\n if (typeof window === 'undefined') return null;\n try {\n const val = localStorage.getItem(this.getCacheKey(type));\n return val ? JSON.parse(val) : null;\n } catch {\n return null;\n }\n }\n\n private setCache(type: 'token' | 'messages', value: any) {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(this.getCacheKey(type), JSON.stringify(value));\n } catch (e) {\n console.warn('[Happiest] Failed to persist state', e);\n }\n }\n\n public clearSession() {\n if (typeof window !== 'undefined') {\n localStorage.removeItem(this.getCacheKey('token'));\n localStorage.removeItem(this.getCacheKey('messages'));\n }\n this.updateState({\n status: 'idle',\n sessionToken: null,\n messages: [],\n error: null\n });\n this.conversationId = undefined;\n }\n\n // --- Network Actions ---\n\n public async initSession(): Promise<void> {\n if (this.state.status === 'connected' && this.state.sessionToken) {\n return; // Already initialized\n }\n\n this.updateState({ status: 'connecting', error: null });\n \n try {\n const res = await fetch(`${this.apiUrl}/widget/v1/init`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ publishableKey: this.config.publishableKey })\n });\n \n const data = await res.json();\n \n if (!res.ok) {\n throw new Error(data.error || 'Failed to initialize session');\n }\n\n const token = data.sessionToken || data.embedToken;\n const config = data.widgetConfig || data.config || {};\n\n this.setCache('token', token);\n\n this.updateState({\n status: 'connected',\n sessionToken: token,\n widgetConfig: config,\n });\n\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Network error';\n this.updateState({ status: 'error', error: message });\n }\n }\n\n public async sendMessage(text: string): Promise<void> {\n const trimmed = text.trim();\n if (!trimmed || !this.state.sessionToken) return;\n\n // Optimistic update\n const userMsg: ChatMessage = {\n id: Date.now().toString(),\n text: trimmed,\n isUser: true,\n createdAt: Date.now(),\n status: 'sending'\n };\n\n const newMessages = [...this.state.messages, userMsg];\n this.setCache('messages', newMessages);\n \n this.updateState({\n messages: newMessages,\n isTyping: true,\n error: null\n });\n\n await this._sendToNetwork(userMsg.id, trimmed);\n }\n\n public async retryMessage(id: string): Promise<void> {\n const msg = this.state.messages.find(m => m.id === id);\n if (!msg || msg.status !== 'failed') return;\n \n // Optimistically set to sending again\n const newMessages = this.state.messages.map(m => m.id === id ? { ...m, status: 'sending' as const } : m);\n this.setCache('messages', newMessages);\n this.updateState({ messages: newMessages, isTyping: true, error: null });\n\n await this._sendToNetwork(id, msg.text);\n }\n\n private async _sendToNetwork(msgId: string, text: string): Promise<void> {\n try {\n const res = await fetch(`${this.apiUrl}/widget/v1/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.state.sessionToken}`\n },\n body: JSON.stringify({\n message: text,\n conversationId: this.conversationId\n })\n });\n\n const data = await res.json();\n \n if (!res.ok) {\n throw new Error(data.error || 'Failed to send message');\n }\n\n if (data.conversationId) {\n this.conversationId = data.conversationId;\n }\n\n const agentMsg: ChatMessage = {\n id: (Date.now() + 1).toString(),\n text: data.message || data.reply || 'Thanks for your message.',\n isUser: false,\n createdAt: Date.now()\n };\n\n // Find the user message and update its status to delivered\n const currentMessages = this.state.messages.map(m => m.id === msgId ? { ...m, status: 'delivered' as const } : m);\n const finalMessages = [...currentMessages, agentMsg];\n \n this.setCache('messages', finalMessages);\n this.updateState({\n messages: finalMessages,\n isTyping: false\n });\n\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Message failed';\n \n // Update user message status to failed\n const currentMessages = this.state.messages.map(m => m.id === msgId ? { ...m, status: 'failed' as const } : m);\n \n this.setCache('messages', currentMessages);\n this.updateState({ \n messages: currentMessages,\n isTyping: false, \n error: message \n });\n }\n }\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@happiest-team/ai-chat-core",
3
+ "version": "1.0.1",
4
+ "description": "Headless API Client and State Manager for Happiest Chat",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsup",
17
+ "dev": "tsup --watch"
18
+ },
19
+ "keywords": [
20
+ "happiest",
21
+ "chat",
22
+ "ai",
23
+ "agent",
24
+ "headless",
25
+ "core"
26
+ ],
27
+ "author": "Happiest",
28
+ "license": "MIT",
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "README.md",
35
+ "package.json"
36
+ ],
37
+ "type": "commonjs",
38
+ "devDependencies": {
39
+ "@types/node": "^22.0.0",
40
+ "tsup": "^8.0.0",
41
+ "typescript": "^5.5.0"
42
+ }
43
+ }