@tinkrapp/widget 1.1.3 → 1.3.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/dist/index.cjs CHANGED
@@ -60,10 +60,13 @@ var WidgetAPI = class {
60
60
  return response;
61
61
  }
62
62
  async sendMessage(sessionId, content) {
63
- const response = await this.request(`/sessions/${sessionId}/messages`, {
64
- method: "POST",
65
- body: JSON.stringify({ content })
66
- });
63
+ const response = await this.request(
64
+ `/sessions/${sessionId}/messages`,
65
+ {
66
+ method: "POST",
67
+ body: JSON.stringify({ content })
68
+ }
69
+ );
67
70
  return response;
68
71
  }
69
72
  async getHistory(sessionId) {
@@ -91,7 +94,7 @@ var WidgetAPI = class {
91
94
  ...options,
92
95
  headers: {
93
96
  "Content-Type": "application/json",
94
- "Authorization": `Bearer ${this.config.apiKey}`,
97
+ Authorization: `Bearer ${this.config.apiKey}`,
95
98
  ...options.headers
96
99
  }
97
100
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/events.ts","../src/core/api.ts","../src/core/client.ts"],"names":[],"mappings":";;;AAEO,IAAM,oBAAN,MAAiE;AAAA,EAAjE,WAAA,GAAA;AACL,IAAA,IAAA,CAAQ,SAAA,uBAAgB,GAAA,EAAsC;AAAA,EAAA;AAAA,EAE9D,EAAA,CACE,OACA,OAAA,EACY;AACZ,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9B,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAA,kBAAO,IAAI,KAAK,CAAA;AAAA,IACrC;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,CAAG,IAAI,OAAuB,CAAA;AAGtD,IAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;AAAA,EACtC;AAAA,EAEA,GAAA,CACE,OACA,OAAA,EACM;AACN,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,EAAG,OAAO,OAAuB,CAAA;AAAA,EAC3D;AAAA,EAEA,IAAA,CAA8B,OAAU,OAAA,EAA2B;AACjE,IAAA,IAAA,CAAK,UAAU,GAAA,CAAI,KAAK,CAAA,EAAG,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9C,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,OAAO,CAAA;AAAA,MACjB,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,MAAM,CAAA,SAAA,EAAY,MAAA,CAAO,KAAK,CAAC,aAAa,KAAK,CAAA;AAAA,MAC3D;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AAAA,EAEA,mBAAmB,KAAA,EAA6B;AAC9C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,KAAK,CAAA;AAAA,IAC7B,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,IACvB;AAAA,EACF;AACF;;;AC5CO,IAAM,YAAN,MAAgB;AAAA,EAGrB,YAAY,MAAA,EAAsB;AAChC,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,OAAA,EAAS,uBAAA;AAAA,MACT,MAAA,EAAQ,EAAA;AAAA,MACR,KAAA,EAAO,KAAA;AAAA,MACP,aAAa,MAAA,CAAO,MAAA;AAAA;AAAA,MACpB,GAAG;AAAA,KACL;AAAA,EACF;AAAA,EAEA,MAAM,aAAA,GAAsC;AAC1C,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAqB,WAAA,EAAa;AAAA,MAC5D,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA;AAAA,QAEnB,WAAA,EAAa,KAAK,MAAA,CAAO,MAAA;AAAA,QACzB,MAAA,EAAQ,KAAK,MAAA,CAAO;AAAA,OACrB;AAAA,KACF,CAAA;AACD,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,MAAM,WAAA,CAAY,SAAA,EAAmB,OAAA,EAAmC;AACtE,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,OAAA,CAAiB,CAAA,UAAA,EAAa,SAAS,CAAA,SAAA,CAAA,EAAa;AAAA,MAC9E,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,SAAS;AAAA,KACjC,CAAA;AACD,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,SAAA,EAAuC;AACtD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAmB,CAAA,UAAA,EAAa,SAAS,CAAA,SAAA,CAAW,CAAA;AAAA,EAClE;AAAA,EAEA,MAAM,WAAA,GAAsC;AAC1C,IAAA,OAAO,IAAA,CAAK,QAAuB,WAAW,CAAA;AAAA,EAChD;AAAA,EAEA,MAAM,YAAA,GAAoC;AACxC,IAAA,OAAO,IAAA,CAAK,QAAoB,YAAY,CAAA;AAAA,EAC9C;AAAA,EAEA,MAAM,YAAY,EAAA,EAA+B;AAC/C,IAAA,OAAO,IAAA,CAAK,OAAA,CAAkB,CAAA,WAAA,EAAc,EAAE,CAAA,CAAE,CAAA;AAAA,EAClD;AAAA,EAEA,MAAM,eAAe,QAAA,EAA+E;AAClG,IAAA,OAAO,IAAA,CAAK,QAAkB,YAAA,EAAc;AAAA,MAC1C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,QAAQ;AAAA,KAC9B,CAAA;AAAA,EACH;AAAA,EAEA,MAAc,OAAA,CACZ,QAAA,EACA,OAAA,GAAuB,EAAC,EACZ;AACZ,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,OAAO,GAAG,QAAQ,CAAA,CAAA;AAE7C,IAAA,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,GAAA,EAAK,OAAO,CAAA;AAEjC,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAChC,GAAG,OAAA;AAAA,MACH,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,eAAA,EAAiB,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,QAC7C,GAAG,OAAA,CAAQ;AAAA;AACb,KACD,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AACpD,MAAA,MAAM,IAAI,KAAA,CAAM,KAAA,CAAM,WAAW,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IAC5D;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AAAA,EAEQ,OAAO,IAAA,EAAuB;AACpC,IAAA,IAAI,IAAA,CAAK,OAAO,KAAA,EAAO;AACrB,MAAA,OAAA,CAAQ,GAAA,CAAI,YAAA,EAAc,GAAG,IAAI,CAAA;AAAA,IACnC;AAAA,EACF;AACF;;;AC9EO,IAAM,eAAN,MAAmB;AAAA,EAMxB,YAAY,MAAA,EAAsB;AAJlC,IAAA,IAAA,CAAQ,KAAA,GAAqB,EAAE,MAAA,EAAQ,MAAA,EAAO;AAC9C,IAAA,IAAA,CAAQ,MAAA,GAAS,IAAI,iBAAA,EAAgC;AAInD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,GAAA,GAAM,IAAI,SAAA,CAAU,MAAM,CAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,MAAA,EAAQ;AAChC,MAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,IAC9C;AAEA,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,cAAA,EAAgB,CAAA;AAExC,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,GAAA,CAAI,aAAA,EAAc;AAC7C,MAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AAC1C,MAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,iBAAA,EAAmB,EAAE,SAAS,CAAA;AAAA,IACjD,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,WAAA,GAAc;AAAA,QAClB,IAAA,EAAM,aAAA;AAAA,QACN,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AAAA,QAClD,OAAA,EAAS;AAAA,OACX;AACA,MAAA,IAAA,CAAK,SAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAO,aAAa,CAAA;AACrD,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,OAAA,EAAS,EAAE,KAAA,EAAO,aAAa,CAAA;AAChD,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,OAAA,EAAmC;AACnD,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,OAAA,EAAS;AACjC,MAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,IAC9D;AAEA,IAAA,MAAM,WAAA,GAAuB;AAAA,MAC3B,EAAA,EAAI,OAAO,UAAA,EAAW;AAAA,MACtB,IAAA,EAAM,MAAA;AAAA,MACN,OAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA;AAAI,KACtB;AAGA,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,GAAG,KAAK,KAAA,CAAM,OAAA;AAAA,MACd,UAAU,CAAC,GAAG,KAAK,KAAA,CAAM,OAAA,CAAQ,UAAU,WAAW;AAAA,KACxD;AACA,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AAC1C,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,cAAA,EAAgB,EAAE,OAAA,EAAS,aAAa,CAAA;AAGzD,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,SAAA,EAAW,CAAA;AAEnC,IAAA,IAAI;AACF,MAAA,MAAM,gBAAA,GAAmB,MAAM,IAAA,CAAK,GAAA,CAAI,WAAA;AAAA,QACtC,OAAA,CAAQ,EAAA;AAAA,QACR;AAAA,OACF;AAEA,MAAA,MAAM,cAAA,GAAiB;AAAA,QACrB,GAAG,OAAA;AAAA,QACH,QAAA,EAAU,CAAC,GAAG,OAAA,CAAQ,UAAU,gBAAgB;AAAA,OAClD;AAEA,MAAA,IAAA,CAAK,SAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAS,gBAAgB,CAAA;AAC1D,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,kBAAA,EAAoB,EAAE,OAAA,EAAS,kBAAkB,CAAA;AAElE,MAAA,OAAO,gBAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,WAAA,GAAc;AAAA,QAClB,IAAA,EAAM,qBAAA;AAAA,QACN,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,wBAAA;AAAA,QAClD,OAAA,EAAS;AAAA,OACX;AAGA,MAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AAC1C,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,OAAA,EAAS,EAAE,KAAA,EAAO,aAAa,CAAA;AAChD,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAwB;AACtB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,GAAoB;AAClB,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,EAAA,CACE,OACA,OAAA,EACY;AACZ,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,KAAA,EAAO,OAAO,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CACE,OACA,OAAA,EACM;AACN,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAClB,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,MAAA,EAAQ,CAAA;AAAA,EAClC;AAAA,EAEQ,SAAS,QAAA,EAA6B;AAC5C,IAAA,MAAM,WAAW,IAAA,CAAK,KAAA;AACtB,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAA;AACb,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,cAAA,EAAgB,EAAE,QAAA,EAAU,OAAA,EAAS,UAAU,CAAA;AAAA,EAClE;AACF","file":"index.cjs","sourcesContent":["type EventHandler<T = unknown> = (payload: T) => void;\n\nexport class TypedEventEmitter<TEvents extends Record<string, unknown>> {\n private listeners = new Map<keyof TEvents, Set<EventHandler>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): void {\n this.listeners.get(event)?.delete(handler as EventHandler);\n }\n\n emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n console.error(`Error in ${String(event)} handler:`, error);\n }\n });\n }\n\n clear(): void {\n this.listeners.clear();\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n\n","import type { WidgetConfig, Message, ChatSession, Artifact } from './types';\n\nexport class WidgetAPI {\n private config: Required<WidgetConfig>;\n\n constructor(config: WidgetConfig) {\n this.config = {\n baseUrl: process.env.WIDGET_API_URL || 'http://localhost:3000',\n userId: '',\n debug: false,\n assistantId: config.apiKey, // Default to apiKey for backwards compatibility\n ...config,\n };\n }\n\n async createSession(): Promise<ChatSession> {\n const response = await this.request<ChatSession>('/sessions', {\n method: 'POST',\n body: JSON.stringify({\n // apiKey IS the assistantId\n assistantId: this.config.apiKey,\n userId: this.config.userId,\n }),\n });\n return response;\n }\n\n async sendMessage(sessionId: string, content: string): Promise<Message> {\n const response = await this.request<Message>(`/sessions/${sessionId}/messages`, {\n method: 'POST',\n body: JSON.stringify({ content }),\n });\n return response;\n }\n\n async getHistory(sessionId: string): Promise<Message[]> {\n return this.request<Message[]>(`/sessions/${sessionId}/messages`);\n }\n\n async getSessions(): Promise<ChatSession[]> {\n return this.request<ChatSession[]>('/sessions');\n }\n\n async getArtifacts(): Promise<Artifact[]> {\n return this.request<Artifact[]>('/artifacts');\n }\n\n async getArtifact(id: string): Promise<Artifact> {\n return this.request<Artifact>(`/artifacts/${id}`);\n }\n\n async createArtifact(artifact: Omit<Artifact, 'id' | 'createdAt' | 'updatedAt'>): Promise<Artifact> {\n return this.request<Artifact>('/artifacts', {\n method: 'POST',\n body: JSON.stringify(artifact),\n });\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n \n this.log('Request:', url, options);\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.message || `HTTP ${response.status}`);\n }\n\n return response.json();\n }\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[CourseAI]', ...args);\n }\n }\n}\n\n","import { TypedEventEmitter } from './events';\nimport { WidgetAPI } from './api';\nimport type {\n WidgetConfig,\n WidgetState,\n WidgetEvents,\n Message,\n ChatSession,\n} from './types';\n\nexport class WidgetClient {\n private config: WidgetConfig;\n private state: WidgetState = { status: 'idle' };\n private events = new TypedEventEmitter<WidgetEvents>();\n private api: WidgetAPI;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.api = new WidgetAPI(config);\n }\n\n /**\n * Initialize the widget and create a chat session\n */\n async initialize(): Promise<void> {\n if (this.state.status !== 'idle') {\n throw new Error('Widget already initialized');\n }\n\n this.setState({ status: 'initializing' });\n\n try {\n const session = await this.api.createSession();\n this.setState({ status: 'ready', session });\n this.events.emit('session:created', { session });\n } catch (error) {\n const widgetError = {\n code: 'INIT_FAILED',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n };\n this.setState({ status: 'error', error: widgetError });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Send a message to the AI assistant\n */\n async sendMessage(content: string): Promise<Message> {\n if (this.state.status !== 'ready') {\n throw new Error('Widget not ready. Call initialize() first.');\n }\n\n const userMessage: Message = {\n id: crypto.randomUUID(),\n role: 'user',\n content,\n timestamp: Date.now(),\n };\n\n // Optimistically add user message\n const session = {\n ...this.state.session,\n messages: [...this.state.session.messages, userMessage],\n };\n this.setState({ status: 'ready', session });\n this.events.emit('message:sent', { message: userMessage });\n\n // Set loading state\n this.setState({ status: 'loading' });\n\n try {\n const assistantMessage = await this.api.sendMessage(\n session.id,\n content\n );\n\n const updatedSession = {\n ...session,\n messages: [...session.messages, assistantMessage],\n };\n\n this.setState({ status: 'ready', session: updatedSession });\n this.events.emit('message:received', { message: assistantMessage });\n\n return assistantMessage;\n } catch (error) {\n const widgetError = {\n code: 'SEND_MESSAGE_FAILED',\n message: error instanceof Error ? error.message : 'Failed to send message',\n details: error,\n };\n \n // Revert to previous state with user message still included\n this.setState({ status: 'ready', session });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return this.state;\n }\n\n /**\n * Get the API instance for direct calls\n */\n getAPI(): WidgetAPI {\n return this.api;\n }\n\n /**\n * Get the widget configuration\n */\n getConfig(): WidgetConfig {\n return this.config;\n }\n\n /**\n * Subscribe to events\n */\n on<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): () => void {\n return this.events.on(event, handler);\n }\n\n /**\n * Unsubscribe from events\n */\n off<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): void {\n this.events.off(event, handler);\n }\n\n /**\n * Clean up resources\n */\n destroy(): void {\n this.events.clear();\n this.setState({ status: 'idle' });\n }\n\n private setState(newState: WidgetState): void {\n const previous = this.state;\n this.state = newState;\n this.events.emit('state:change', { previous, current: newState });\n }\n}\n\n"]}
1
+ {"version":3,"sources":["../src/core/events.ts","../src/core/api.ts","../src/core/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["type EventHandler<T = unknown> = (payload: T) => void;\n\nexport class TypedEventEmitter<TEvents extends Record<string, unknown>> {\n private listeners = new Map<keyof TEvents, Set<EventHandler>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): void {\n this.listeners.get(event)?.delete(handler as EventHandler);\n }\n\n emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n console.error(`Error in ${String(event)} handler:`, error);\n }\n });\n }\n\n clear(): void {\n this.listeners.clear();\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n\n","import type { Artifact, ChatSession, Message, WidgetConfig } from './types'\n\n/**\n * Resolved config with required core fields but optional context fields\n */\ntype ResolvedConfig = Required<\n Pick<WidgetConfig, 'apiKey' | 'assistantId' | 'baseUrl' | 'userId' | 'debug'>\n> &\n Pick<WidgetConfig, 'userContext' | 'lessonContext'>\n\nexport class WidgetAPI {\n private config: ResolvedConfig\n\n constructor(config: WidgetConfig) {\n this.config = {\n baseUrl: process.env.APP_URL || 'http://localhost:3000',\n userId: '',\n debug: false,\n assistantId: config.apiKey, // Default to apiKey for backwards compatibility\n ...config,\n }\n }\n\n async createSession(): Promise<ChatSession> {\n const response = await this.request<ChatSession>('/sessions', {\n method: 'POST',\n body: JSON.stringify({\n // apiKey IS the assistantId\n assistantId: this.config.apiKey,\n userId: this.config.userId,\n }),\n })\n return response\n }\n\n async sendMessage(sessionId: string, content: string): Promise<Message> {\n const response = await this.request<Message>(\n `/sessions/${sessionId}/messages`,\n {\n method: 'POST',\n body: JSON.stringify({ content }),\n },\n )\n return response\n }\n\n async getHistory(sessionId: string): Promise<Message[]> {\n return this.request<Message[]>(`/sessions/${sessionId}/messages`)\n }\n\n async getSessions(): Promise<ChatSession[]> {\n return this.request<ChatSession[]>('/sessions')\n }\n\n async getArtifacts(): Promise<Artifact[]> {\n return this.request<Artifact[]>('/artifacts')\n }\n\n async getArtifact(id: string): Promise<Artifact> {\n return this.request<Artifact>(`/artifacts/${id}`)\n }\n\n async createArtifact(\n artifact: Omit<Artifact, 'id' | 'createdAt' | 'updatedAt'>,\n ): Promise<Artifact> {\n return this.request<Artifact>('/artifacts', {\n method: 'POST',\n body: JSON.stringify(artifact),\n })\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`\n\n this.log('Request:', url, options)\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.config.apiKey}`,\n ...options.headers,\n },\n })\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}))\n throw new Error(error.message || `HTTP ${response.status}`)\n }\n\n return response.json()\n }\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[CourseAI]', ...args)\n }\n }\n}\n","import { TypedEventEmitter } from './events';\nimport { WidgetAPI } from './api';\nimport type {\n WidgetConfig,\n WidgetState,\n WidgetEvents,\n Message,\n ChatSession,\n} from './types';\n\nexport class WidgetClient {\n private config: WidgetConfig;\n private state: WidgetState = { status: 'idle' };\n private events = new TypedEventEmitter<WidgetEvents>();\n private api: WidgetAPI;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.api = new WidgetAPI(config);\n }\n\n /**\n * Initialize the widget and create a chat session\n */\n async initialize(): Promise<void> {\n if (this.state.status !== 'idle') {\n throw new Error('Widget already initialized');\n }\n\n this.setState({ status: 'initializing' });\n\n try {\n const session = await this.api.createSession();\n this.setState({ status: 'ready', session });\n this.events.emit('session:created', { session });\n } catch (error) {\n const widgetError = {\n code: 'INIT_FAILED',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n };\n this.setState({ status: 'error', error: widgetError });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Send a message to the AI assistant\n */\n async sendMessage(content: string): Promise<Message> {\n if (this.state.status !== 'ready') {\n throw new Error('Widget not ready. Call initialize() first.');\n }\n\n const userMessage: Message = {\n id: crypto.randomUUID(),\n role: 'user',\n content,\n timestamp: Date.now(),\n };\n\n // Optimistically add user message\n const session = {\n ...this.state.session,\n messages: [...this.state.session.messages, userMessage],\n };\n this.setState({ status: 'ready', session });\n this.events.emit('message:sent', { message: userMessage });\n\n // Set loading state\n this.setState({ status: 'loading' });\n\n try {\n const assistantMessage = await this.api.sendMessage(\n session.id,\n content\n );\n\n const updatedSession = {\n ...session,\n messages: [...session.messages, assistantMessage],\n };\n\n this.setState({ status: 'ready', session: updatedSession });\n this.events.emit('message:received', { message: assistantMessage });\n\n return assistantMessage;\n } catch (error) {\n const widgetError = {\n code: 'SEND_MESSAGE_FAILED',\n message: error instanceof Error ? error.message : 'Failed to send message',\n details: error,\n };\n \n // Revert to previous state with user message still included\n this.setState({ status: 'ready', session });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return this.state;\n }\n\n /**\n * Get the API instance for direct calls\n */\n getAPI(): WidgetAPI {\n return this.api;\n }\n\n /**\n * Get the widget configuration\n */\n getConfig(): WidgetConfig {\n return this.config;\n }\n\n /**\n * Subscribe to events\n */\n on<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): () => void {\n return this.events.on(event, handler);\n }\n\n /**\n * Unsubscribe from events\n */\n off<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): void {\n this.events.off(event, handler);\n }\n\n /**\n * Clean up resources\n */\n destroy(): void {\n this.events.clear();\n this.setState({ status: 'idle' });\n }\n\n private setState(newState: WidgetState): void {\n const previous = this.state;\n this.state = newState;\n this.events.emit('state:change', { previous, current: newState });\n }\n}\n\n"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Artifact, f as ArtifactCategory, C as ChatSession, M as Message, a as WidgetAPI, W as WidgetClient, b as WidgetConfig, e as WidgetError, d as WidgetEvents, c as WidgetState } from './client-CExUGn7b.cjs';
1
+ export { A as Artifact, f as ArtifactCategory, C as ChatSession, M as Message, a as WidgetAPI, W as WidgetClient, b as WidgetConfig, e as WidgetError, d as WidgetEvents, c as WidgetState } from './client-BFcAYuri.cjs';
2
2
 
3
3
  type EventHandler<T = unknown> = (payload: T) => void;
4
4
  declare class TypedEventEmitter<TEvents extends Record<string, unknown>> {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Artifact, f as ArtifactCategory, C as ChatSession, M as Message, a as WidgetAPI, W as WidgetClient, b as WidgetConfig, e as WidgetError, d as WidgetEvents, c as WidgetState } from './client-CExUGn7b.js';
1
+ export { A as Artifact, f as ArtifactCategory, C as ChatSession, M as Message, a as WidgetAPI, W as WidgetClient, b as WidgetConfig, e as WidgetError, d as WidgetEvents, c as WidgetState } from './client-BFcAYuri.js';
2
2
 
3
3
  type EventHandler<T = unknown> = (payload: T) => void;
4
4
  declare class TypedEventEmitter<TEvents extends Record<string, unknown>> {
package/dist/index.js CHANGED
@@ -58,10 +58,13 @@ var WidgetAPI = class {
58
58
  return response;
59
59
  }
60
60
  async sendMessage(sessionId, content) {
61
- const response = await this.request(`/sessions/${sessionId}/messages`, {
62
- method: "POST",
63
- body: JSON.stringify({ content })
64
- });
61
+ const response = await this.request(
62
+ `/sessions/${sessionId}/messages`,
63
+ {
64
+ method: "POST",
65
+ body: JSON.stringify({ content })
66
+ }
67
+ );
65
68
  return response;
66
69
  }
67
70
  async getHistory(sessionId) {
@@ -89,7 +92,7 @@ var WidgetAPI = class {
89
92
  ...options,
90
93
  headers: {
91
94
  "Content-Type": "application/json",
92
- "Authorization": `Bearer ${this.config.apiKey}`,
95
+ Authorization: `Bearer ${this.config.apiKey}`,
93
96
  ...options.headers
94
97
  }
95
98
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/events.ts","../src/core/api.ts","../src/core/client.ts"],"names":[],"mappings":";AAEO,IAAM,oBAAN,MAAiE;AAAA,EAAjE,WAAA,GAAA;AACL,IAAA,IAAA,CAAQ,SAAA,uBAAgB,GAAA,EAAsC;AAAA,EAAA;AAAA,EAE9D,EAAA,CACE,OACA,OAAA,EACY;AACZ,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9B,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAA,kBAAO,IAAI,KAAK,CAAA;AAAA,IACrC;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,CAAG,IAAI,OAAuB,CAAA;AAGtD,IAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;AAAA,EACtC;AAAA,EAEA,GAAA,CACE,OACA,OAAA,EACM;AACN,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,EAAG,OAAO,OAAuB,CAAA;AAAA,EAC3D;AAAA,EAEA,IAAA,CAA8B,OAAU,OAAA,EAA2B;AACjE,IAAA,IAAA,CAAK,UAAU,GAAA,CAAI,KAAK,CAAA,EAAG,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9C,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,OAAO,CAAA;AAAA,MACjB,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,MAAM,CAAA,SAAA,EAAY,MAAA,CAAO,KAAK,CAAC,aAAa,KAAK,CAAA;AAAA,MAC3D;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AAAA,EAEA,mBAAmB,KAAA,EAA6B;AAC9C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,KAAK,CAAA;AAAA,IAC7B,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,IACvB;AAAA,EACF;AACF;;;AC5CO,IAAM,YAAN,MAAgB;AAAA,EAGrB,YAAY,MAAA,EAAsB;AAChC,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,OAAA,EAAS,uBAAA;AAAA,MACT,MAAA,EAAQ,EAAA;AAAA,MACR,KAAA,EAAO,KAAA;AAAA,MACP,aAAa,MAAA,CAAO,MAAA;AAAA;AAAA,MACpB,GAAG;AAAA,KACL;AAAA,EACF;AAAA,EAEA,MAAM,aAAA,GAAsC;AAC1C,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAqB,WAAA,EAAa;AAAA,MAC5D,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA;AAAA,QAEnB,WAAA,EAAa,KAAK,MAAA,CAAO,MAAA;AAAA,QACzB,MAAA,EAAQ,KAAK,MAAA,CAAO;AAAA,OACrB;AAAA,KACF,CAAA;AACD,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,MAAM,WAAA,CAAY,SAAA,EAAmB,OAAA,EAAmC;AACtE,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,OAAA,CAAiB,CAAA,UAAA,EAAa,SAAS,CAAA,SAAA,CAAA,EAAa;AAAA,MAC9E,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,SAAS;AAAA,KACjC,CAAA;AACD,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,SAAA,EAAuC;AACtD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAmB,CAAA,UAAA,EAAa,SAAS,CAAA,SAAA,CAAW,CAAA;AAAA,EAClE;AAAA,EAEA,MAAM,WAAA,GAAsC;AAC1C,IAAA,OAAO,IAAA,CAAK,QAAuB,WAAW,CAAA;AAAA,EAChD;AAAA,EAEA,MAAM,YAAA,GAAoC;AACxC,IAAA,OAAO,IAAA,CAAK,QAAoB,YAAY,CAAA;AAAA,EAC9C;AAAA,EAEA,MAAM,YAAY,EAAA,EAA+B;AAC/C,IAAA,OAAO,IAAA,CAAK,OAAA,CAAkB,CAAA,WAAA,EAAc,EAAE,CAAA,CAAE,CAAA;AAAA,EAClD;AAAA,EAEA,MAAM,eAAe,QAAA,EAA+E;AAClG,IAAA,OAAO,IAAA,CAAK,QAAkB,YAAA,EAAc;AAAA,MAC1C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,QAAQ;AAAA,KAC9B,CAAA;AAAA,EACH;AAAA,EAEA,MAAc,OAAA,CACZ,QAAA,EACA,OAAA,GAAuB,EAAC,EACZ;AACZ,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,OAAO,GAAG,QAAQ,CAAA,CAAA;AAE7C,IAAA,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,GAAA,EAAK,OAAO,CAAA;AAEjC,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAChC,GAAG,OAAA;AAAA,MACH,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,eAAA,EAAiB,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,QAC7C,GAAG,OAAA,CAAQ;AAAA;AACb,KACD,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AACpD,MAAA,MAAM,IAAI,KAAA,CAAM,KAAA,CAAM,WAAW,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IAC5D;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AAAA,EAEQ,OAAO,IAAA,EAAuB;AACpC,IAAA,IAAI,IAAA,CAAK,OAAO,KAAA,EAAO;AACrB,MAAA,OAAA,CAAQ,GAAA,CAAI,YAAA,EAAc,GAAG,IAAI,CAAA;AAAA,IACnC;AAAA,EACF;AACF;;;AC9EO,IAAM,eAAN,MAAmB;AAAA,EAMxB,YAAY,MAAA,EAAsB;AAJlC,IAAA,IAAA,CAAQ,KAAA,GAAqB,EAAE,MAAA,EAAQ,MAAA,EAAO;AAC9C,IAAA,IAAA,CAAQ,MAAA,GAAS,IAAI,iBAAA,EAAgC;AAInD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,GAAA,GAAM,IAAI,SAAA,CAAU,MAAM,CAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,MAAA,EAAQ;AAChC,MAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,IAC9C;AAEA,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,cAAA,EAAgB,CAAA;AAExC,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,GAAA,CAAI,aAAA,EAAc;AAC7C,MAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AAC1C,MAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,iBAAA,EAAmB,EAAE,SAAS,CAAA;AAAA,IACjD,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,WAAA,GAAc;AAAA,QAClB,IAAA,EAAM,aAAA;AAAA,QACN,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AAAA,QAClD,OAAA,EAAS;AAAA,OACX;AACA,MAAA,IAAA,CAAK,SAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAO,aAAa,CAAA;AACrD,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,OAAA,EAAS,EAAE,KAAA,EAAO,aAAa,CAAA;AAChD,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,OAAA,EAAmC;AACnD,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,OAAA,EAAS;AACjC,MAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,IAC9D;AAEA,IAAA,MAAM,WAAA,GAAuB;AAAA,MAC3B,EAAA,EAAI,OAAO,UAAA,EAAW;AAAA,MACtB,IAAA,EAAM,MAAA;AAAA,MACN,OAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA;AAAI,KACtB;AAGA,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,GAAG,KAAK,KAAA,CAAM,OAAA;AAAA,MACd,UAAU,CAAC,GAAG,KAAK,KAAA,CAAM,OAAA,CAAQ,UAAU,WAAW;AAAA,KACxD;AACA,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AAC1C,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,cAAA,EAAgB,EAAE,OAAA,EAAS,aAAa,CAAA;AAGzD,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,SAAA,EAAW,CAAA;AAEnC,IAAA,IAAI;AACF,MAAA,MAAM,gBAAA,GAAmB,MAAM,IAAA,CAAK,GAAA,CAAI,WAAA;AAAA,QACtC,OAAA,CAAQ,EAAA;AAAA,QACR;AAAA,OACF;AAEA,MAAA,MAAM,cAAA,GAAiB;AAAA,QACrB,GAAG,OAAA;AAAA,QACH,QAAA,EAAU,CAAC,GAAG,OAAA,CAAQ,UAAU,gBAAgB;AAAA,OAClD;AAEA,MAAA,IAAA,CAAK,SAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAS,gBAAgB,CAAA;AAC1D,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,kBAAA,EAAoB,EAAE,OAAA,EAAS,kBAAkB,CAAA;AAElE,MAAA,OAAO,gBAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,WAAA,GAAc;AAAA,QAClB,IAAA,EAAM,qBAAA;AAAA,QACN,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,wBAAA;AAAA,QAClD,OAAA,EAAS;AAAA,OACX;AAGA,MAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AAC1C,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,OAAA,EAAS,EAAE,KAAA,EAAO,aAAa,CAAA;AAChD,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAwB;AACtB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,GAAoB;AAClB,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,EAAA,CACE,OACA,OAAA,EACY;AACZ,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,KAAA,EAAO,OAAO,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CACE,OACA,OAAA,EACM;AACN,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAClB,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,MAAA,EAAQ,CAAA;AAAA,EAClC;AAAA,EAEQ,SAAS,QAAA,EAA6B;AAC5C,IAAA,MAAM,WAAW,IAAA,CAAK,KAAA;AACtB,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAA;AACb,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,cAAA,EAAgB,EAAE,QAAA,EAAU,OAAA,EAAS,UAAU,CAAA;AAAA,EAClE;AACF","file":"index.js","sourcesContent":["type EventHandler<T = unknown> = (payload: T) => void;\n\nexport class TypedEventEmitter<TEvents extends Record<string, unknown>> {\n private listeners = new Map<keyof TEvents, Set<EventHandler>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): void {\n this.listeners.get(event)?.delete(handler as EventHandler);\n }\n\n emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n console.error(`Error in ${String(event)} handler:`, error);\n }\n });\n }\n\n clear(): void {\n this.listeners.clear();\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n\n","import type { WidgetConfig, Message, ChatSession, Artifact } from './types';\n\nexport class WidgetAPI {\n private config: Required<WidgetConfig>;\n\n constructor(config: WidgetConfig) {\n this.config = {\n baseUrl: process.env.WIDGET_API_URL || 'http://localhost:3000',\n userId: '',\n debug: false,\n assistantId: config.apiKey, // Default to apiKey for backwards compatibility\n ...config,\n };\n }\n\n async createSession(): Promise<ChatSession> {\n const response = await this.request<ChatSession>('/sessions', {\n method: 'POST',\n body: JSON.stringify({\n // apiKey IS the assistantId\n assistantId: this.config.apiKey,\n userId: this.config.userId,\n }),\n });\n return response;\n }\n\n async sendMessage(sessionId: string, content: string): Promise<Message> {\n const response = await this.request<Message>(`/sessions/${sessionId}/messages`, {\n method: 'POST',\n body: JSON.stringify({ content }),\n });\n return response;\n }\n\n async getHistory(sessionId: string): Promise<Message[]> {\n return this.request<Message[]>(`/sessions/${sessionId}/messages`);\n }\n\n async getSessions(): Promise<ChatSession[]> {\n return this.request<ChatSession[]>('/sessions');\n }\n\n async getArtifacts(): Promise<Artifact[]> {\n return this.request<Artifact[]>('/artifacts');\n }\n\n async getArtifact(id: string): Promise<Artifact> {\n return this.request<Artifact>(`/artifacts/${id}`);\n }\n\n async createArtifact(artifact: Omit<Artifact, 'id' | 'createdAt' | 'updatedAt'>): Promise<Artifact> {\n return this.request<Artifact>('/artifacts', {\n method: 'POST',\n body: JSON.stringify(artifact),\n });\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {}\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n \n this.log('Request:', url, options);\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n ...options.headers,\n },\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new Error(error.message || `HTTP ${response.status}`);\n }\n\n return response.json();\n }\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[CourseAI]', ...args);\n }\n }\n}\n\n","import { TypedEventEmitter } from './events';\nimport { WidgetAPI } from './api';\nimport type {\n WidgetConfig,\n WidgetState,\n WidgetEvents,\n Message,\n ChatSession,\n} from './types';\n\nexport class WidgetClient {\n private config: WidgetConfig;\n private state: WidgetState = { status: 'idle' };\n private events = new TypedEventEmitter<WidgetEvents>();\n private api: WidgetAPI;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.api = new WidgetAPI(config);\n }\n\n /**\n * Initialize the widget and create a chat session\n */\n async initialize(): Promise<void> {\n if (this.state.status !== 'idle') {\n throw new Error('Widget already initialized');\n }\n\n this.setState({ status: 'initializing' });\n\n try {\n const session = await this.api.createSession();\n this.setState({ status: 'ready', session });\n this.events.emit('session:created', { session });\n } catch (error) {\n const widgetError = {\n code: 'INIT_FAILED',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n };\n this.setState({ status: 'error', error: widgetError });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Send a message to the AI assistant\n */\n async sendMessage(content: string): Promise<Message> {\n if (this.state.status !== 'ready') {\n throw new Error('Widget not ready. Call initialize() first.');\n }\n\n const userMessage: Message = {\n id: crypto.randomUUID(),\n role: 'user',\n content,\n timestamp: Date.now(),\n };\n\n // Optimistically add user message\n const session = {\n ...this.state.session,\n messages: [...this.state.session.messages, userMessage],\n };\n this.setState({ status: 'ready', session });\n this.events.emit('message:sent', { message: userMessage });\n\n // Set loading state\n this.setState({ status: 'loading' });\n\n try {\n const assistantMessage = await this.api.sendMessage(\n session.id,\n content\n );\n\n const updatedSession = {\n ...session,\n messages: [...session.messages, assistantMessage],\n };\n\n this.setState({ status: 'ready', session: updatedSession });\n this.events.emit('message:received', { message: assistantMessage });\n\n return assistantMessage;\n } catch (error) {\n const widgetError = {\n code: 'SEND_MESSAGE_FAILED',\n message: error instanceof Error ? error.message : 'Failed to send message',\n details: error,\n };\n \n // Revert to previous state with user message still included\n this.setState({ status: 'ready', session });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return this.state;\n }\n\n /**\n * Get the API instance for direct calls\n */\n getAPI(): WidgetAPI {\n return this.api;\n }\n\n /**\n * Get the widget configuration\n */\n getConfig(): WidgetConfig {\n return this.config;\n }\n\n /**\n * Subscribe to events\n */\n on<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): () => void {\n return this.events.on(event, handler);\n }\n\n /**\n * Unsubscribe from events\n */\n off<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): void {\n this.events.off(event, handler);\n }\n\n /**\n * Clean up resources\n */\n destroy(): void {\n this.events.clear();\n this.setState({ status: 'idle' });\n }\n\n private setState(newState: WidgetState): void {\n const previous = this.state;\n this.state = newState;\n this.events.emit('state:change', { previous, current: newState });\n }\n}\n\n"]}
1
+ {"version":3,"sources":["../src/core/events.ts","../src/core/api.ts","../src/core/client.ts"],"names":[],"mappings":";AAEO,IAAM,oBAAN,MAAiE;AAAA,EAAjE,WAAA,GAAA;AACL,IAAA,IAAA,CAAQ,SAAA,uBAAgB,GAAA,EAAsC;AAAA,EAAA;AAAA,EAE9D,EAAA,CACE,OACA,OAAA,EACY;AACZ,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9B,MAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAA,kBAAO,IAAI,KAAK,CAAA;AAAA,IACrC;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,CAAG,IAAI,OAAuB,CAAA;AAGtD,IAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;AAAA,EACtC;AAAA,EAEA,GAAA,CACE,OACA,OAAA,EACM;AACN,IAAA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,EAAG,OAAO,OAAuB,CAAA;AAAA,EAC3D;AAAA,EAEA,IAAA,CAA8B,OAAU,OAAA,EAA2B;AACjE,IAAA,IAAA,CAAK,UAAU,GAAA,CAAI,KAAK,CAAA,EAAG,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9C,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,OAAO,CAAA;AAAA,MACjB,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,MAAM,CAAA,SAAA,EAAY,MAAA,CAAO,KAAK,CAAC,aAAa,KAAK,CAAA;AAAA,MAC3D;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AAAA,EAEA,mBAAmB,KAAA,EAA6B;AAC9C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,KAAK,CAAA;AAAA,IAC7B,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,IACvB;AAAA,EACF;AACF;;;ACpCO,IAAM,YAAN,MAAgB;AAAA,EAGrB,YAAY,MAAA,EAAsB;AAChC,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,OAAA,EAAS,uBAAA;AAAA,MACT,MAAA,EAAQ,EAAA;AAAA,MACR,KAAA,EAAO,KAAA;AAAA,MACP,aAAa,MAAA,CAAO,MAAA;AAAA;AAAA,MACpB,GAAG;AAAA,KACL;AAAA,EACF;AAAA,EAEA,MAAM,aAAA,GAAsC;AAC1C,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAqB,WAAA,EAAa;AAAA,MAC5D,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA;AAAA,QAEnB,WAAA,EAAa,KAAK,MAAA,CAAO,MAAA;AAAA,QACzB,MAAA,EAAQ,KAAK,MAAA,CAAO;AAAA,OACrB;AAAA,KACF,CAAA;AACD,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,MAAM,WAAA,CAAY,SAAA,EAAmB,OAAA,EAAmC;AACtE,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA;AAAA,MAC1B,aAAa,SAAS,CAAA,SAAA,CAAA;AAAA,MACtB;AAAA,QACE,MAAA,EAAQ,MAAA;AAAA,QACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,SAAS;AAAA;AAClC,KACF;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,SAAA,EAAuC;AACtD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAmB,CAAA,UAAA,EAAa,SAAS,CAAA,SAAA,CAAW,CAAA;AAAA,EAClE;AAAA,EAEA,MAAM,WAAA,GAAsC;AAC1C,IAAA,OAAO,IAAA,CAAK,QAAuB,WAAW,CAAA;AAAA,EAChD;AAAA,EAEA,MAAM,YAAA,GAAoC;AACxC,IAAA,OAAO,IAAA,CAAK,QAAoB,YAAY,CAAA;AAAA,EAC9C;AAAA,EAEA,MAAM,YAAY,EAAA,EAA+B;AAC/C,IAAA,OAAO,IAAA,CAAK,OAAA,CAAkB,CAAA,WAAA,EAAc,EAAE,CAAA,CAAE,CAAA;AAAA,EAClD;AAAA,EAEA,MAAM,eACJ,QAAA,EACmB;AACnB,IAAA,OAAO,IAAA,CAAK,QAAkB,YAAA,EAAc;AAAA,MAC1C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,QAAQ;AAAA,KAC9B,CAAA;AAAA,EACH;AAAA,EAEA,MAAc,OAAA,CACZ,QAAA,EACA,OAAA,GAAuB,EAAC,EACZ;AACZ,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,OAAO,GAAG,QAAQ,CAAA,CAAA;AAE7C,IAAA,IAAA,CAAK,GAAA,CAAI,UAAA,EAAY,GAAA,EAAK,OAAO,CAAA;AAEjC,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAChC,GAAG,OAAA;AAAA,MACH,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,QAC3C,GAAG,OAAA,CAAQ;AAAA;AACb,KACD,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AACpD,MAAA,MAAM,IAAI,KAAA,CAAM,KAAA,CAAM,WAAW,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IAC5D;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AAAA,EAEQ,OAAO,IAAA,EAAuB;AACpC,IAAA,IAAI,IAAA,CAAK,OAAO,KAAA,EAAO;AACrB,MAAA,OAAA,CAAQ,GAAA,CAAI,YAAA,EAAc,GAAG,IAAI,CAAA;AAAA,IACnC;AAAA,EACF;AACF;;;AC3FO,IAAM,eAAN,MAAmB;AAAA,EAMxB,YAAY,MAAA,EAAsB;AAJlC,IAAA,IAAA,CAAQ,KAAA,GAAqB,EAAE,MAAA,EAAQ,MAAA,EAAO;AAC9C,IAAA,IAAA,CAAQ,MAAA,GAAS,IAAI,iBAAA,EAAgC;AAInD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,GAAA,GAAM,IAAI,SAAA,CAAU,MAAM,CAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,MAAA,EAAQ;AAChC,MAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,IAC9C;AAEA,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,cAAA,EAAgB,CAAA;AAExC,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,GAAA,CAAI,aAAA,EAAc;AAC7C,MAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AAC1C,MAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,iBAAA,EAAmB,EAAE,SAAS,CAAA;AAAA,IACjD,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,WAAA,GAAc;AAAA,QAClB,IAAA,EAAM,aAAA;AAAA,QACN,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AAAA,QAClD,OAAA,EAAS;AAAA,OACX;AACA,MAAA,IAAA,CAAK,SAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAO,aAAa,CAAA;AACrD,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,OAAA,EAAS,EAAE,KAAA,EAAO,aAAa,CAAA;AAChD,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,OAAA,EAAmC;AACnD,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,OAAA,EAAS;AACjC,MAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,IAC9D;AAEA,IAAA,MAAM,WAAA,GAAuB;AAAA,MAC3B,EAAA,EAAI,OAAO,UAAA,EAAW;AAAA,MACtB,IAAA,EAAM,MAAA;AAAA,MACN,OAAA;AAAA,MACA,SAAA,EAAW,KAAK,GAAA;AAAI,KACtB;AAGA,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,GAAG,KAAK,KAAA,CAAM,OAAA;AAAA,MACd,UAAU,CAAC,GAAG,KAAK,KAAA,CAAM,OAAA,CAAQ,UAAU,WAAW;AAAA,KACxD;AACA,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AAC1C,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,cAAA,EAAgB,EAAE,OAAA,EAAS,aAAa,CAAA;AAGzD,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,SAAA,EAAW,CAAA;AAEnC,IAAA,IAAI;AACF,MAAA,MAAM,gBAAA,GAAmB,MAAM,IAAA,CAAK,GAAA,CAAI,WAAA;AAAA,QACtC,OAAA,CAAQ,EAAA;AAAA,QACR;AAAA,OACF;AAEA,MAAA,MAAM,cAAA,GAAiB;AAAA,QACrB,GAAG,OAAA;AAAA,QACH,QAAA,EAAU,CAAC,GAAG,OAAA,CAAQ,UAAU,gBAAgB;AAAA,OAClD;AAEA,MAAA,IAAA,CAAK,SAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAS,gBAAgB,CAAA;AAC1D,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,kBAAA,EAAoB,EAAE,OAAA,EAAS,kBAAkB,CAAA;AAElE,MAAA,OAAO,gBAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,WAAA,GAAc;AAAA,QAClB,IAAA,EAAM,qBAAA;AAAA,QACN,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,wBAAA;AAAA,QAClD,OAAA,EAAS;AAAA,OACX;AAGA,MAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,CAAA;AAC1C,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,OAAA,EAAS,EAAE,KAAA,EAAO,aAAa,CAAA;AAChD,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAwB;AACtB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAA,GAAoB;AAClB,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,EAAA,CACE,OACA,OAAA,EACY;AACZ,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,KAAA,EAAO,OAAO,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CACE,OACA,OAAA,EACM;AACN,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAClB,IAAA,IAAA,CAAK,QAAA,CAAS,EAAE,MAAA,EAAQ,MAAA,EAAQ,CAAA;AAAA,EAClC;AAAA,EAEQ,SAAS,QAAA,EAA6B;AAC5C,IAAA,MAAM,WAAW,IAAA,CAAK,KAAA;AACtB,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAA;AACb,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,cAAA,EAAgB,EAAE,QAAA,EAAU,OAAA,EAAS,UAAU,CAAA;AAAA,EAClE;AACF","file":"index.js","sourcesContent":["type EventHandler<T = unknown> = (payload: T) => void;\n\nexport class TypedEventEmitter<TEvents extends Record<string, unknown>> {\n private listeners = new Map<keyof TEvents, Set<EventHandler>>();\n\n on<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as EventHandler);\n\n // Return unsubscribe function\n return () => this.off(event, handler);\n }\n\n off<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): void {\n this.listeners.get(event)?.delete(handler as EventHandler);\n }\n\n emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n this.listeners.get(event)?.forEach((handler) => {\n try {\n handler(payload);\n } catch (error) {\n console.error(`Error in ${String(event)} handler:`, error);\n }\n });\n }\n\n clear(): void {\n this.listeners.clear();\n }\n\n removeAllListeners(event?: keyof TEvents): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n\n","import type { Artifact, ChatSession, Message, WidgetConfig } from './types'\n\n/**\n * Resolved config with required core fields but optional context fields\n */\ntype ResolvedConfig = Required<\n Pick<WidgetConfig, 'apiKey' | 'assistantId' | 'baseUrl' | 'userId' | 'debug'>\n> &\n Pick<WidgetConfig, 'userContext' | 'lessonContext'>\n\nexport class WidgetAPI {\n private config: ResolvedConfig\n\n constructor(config: WidgetConfig) {\n this.config = {\n baseUrl: process.env.APP_URL || 'http://localhost:3000',\n userId: '',\n debug: false,\n assistantId: config.apiKey, // Default to apiKey for backwards compatibility\n ...config,\n }\n }\n\n async createSession(): Promise<ChatSession> {\n const response = await this.request<ChatSession>('/sessions', {\n method: 'POST',\n body: JSON.stringify({\n // apiKey IS the assistantId\n assistantId: this.config.apiKey,\n userId: this.config.userId,\n }),\n })\n return response\n }\n\n async sendMessage(sessionId: string, content: string): Promise<Message> {\n const response = await this.request<Message>(\n `/sessions/${sessionId}/messages`,\n {\n method: 'POST',\n body: JSON.stringify({ content }),\n },\n )\n return response\n }\n\n async getHistory(sessionId: string): Promise<Message[]> {\n return this.request<Message[]>(`/sessions/${sessionId}/messages`)\n }\n\n async getSessions(): Promise<ChatSession[]> {\n return this.request<ChatSession[]>('/sessions')\n }\n\n async getArtifacts(): Promise<Artifact[]> {\n return this.request<Artifact[]>('/artifacts')\n }\n\n async getArtifact(id: string): Promise<Artifact> {\n return this.request<Artifact>(`/artifacts/${id}`)\n }\n\n async createArtifact(\n artifact: Omit<Artifact, 'id' | 'createdAt' | 'updatedAt'>,\n ): Promise<Artifact> {\n return this.request<Artifact>('/artifacts', {\n method: 'POST',\n body: JSON.stringify(artifact),\n })\n }\n\n private async request<T>(\n endpoint: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`\n\n this.log('Request:', url, options)\n\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.config.apiKey}`,\n ...options.headers,\n },\n })\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}))\n throw new Error(error.message || `HTTP ${response.status}`)\n }\n\n return response.json()\n }\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[CourseAI]', ...args)\n }\n }\n}\n","import { TypedEventEmitter } from './events';\nimport { WidgetAPI } from './api';\nimport type {\n WidgetConfig,\n WidgetState,\n WidgetEvents,\n Message,\n ChatSession,\n} from './types';\n\nexport class WidgetClient {\n private config: WidgetConfig;\n private state: WidgetState = { status: 'idle' };\n private events = new TypedEventEmitter<WidgetEvents>();\n private api: WidgetAPI;\n\n constructor(config: WidgetConfig) {\n this.config = config;\n this.api = new WidgetAPI(config);\n }\n\n /**\n * Initialize the widget and create a chat session\n */\n async initialize(): Promise<void> {\n if (this.state.status !== 'idle') {\n throw new Error('Widget already initialized');\n }\n\n this.setState({ status: 'initializing' });\n\n try {\n const session = await this.api.createSession();\n this.setState({ status: 'ready', session });\n this.events.emit('session:created', { session });\n } catch (error) {\n const widgetError = {\n code: 'INIT_FAILED',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error,\n };\n this.setState({ status: 'error', error: widgetError });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Send a message to the AI assistant\n */\n async sendMessage(content: string): Promise<Message> {\n if (this.state.status !== 'ready') {\n throw new Error('Widget not ready. Call initialize() first.');\n }\n\n const userMessage: Message = {\n id: crypto.randomUUID(),\n role: 'user',\n content,\n timestamp: Date.now(),\n };\n\n // Optimistically add user message\n const session = {\n ...this.state.session,\n messages: [...this.state.session.messages, userMessage],\n };\n this.setState({ status: 'ready', session });\n this.events.emit('message:sent', { message: userMessage });\n\n // Set loading state\n this.setState({ status: 'loading' });\n\n try {\n const assistantMessage = await this.api.sendMessage(\n session.id,\n content\n );\n\n const updatedSession = {\n ...session,\n messages: [...session.messages, assistantMessage],\n };\n\n this.setState({ status: 'ready', session: updatedSession });\n this.events.emit('message:received', { message: assistantMessage });\n\n return assistantMessage;\n } catch (error) {\n const widgetError = {\n code: 'SEND_MESSAGE_FAILED',\n message: error instanceof Error ? error.message : 'Failed to send message',\n details: error,\n };\n \n // Revert to previous state with user message still included\n this.setState({ status: 'ready', session });\n this.events.emit('error', { error: widgetError });\n throw error;\n }\n }\n\n /**\n * Get current state\n */\n getState(): WidgetState {\n return this.state;\n }\n\n /**\n * Get the API instance for direct calls\n */\n getAPI(): WidgetAPI {\n return this.api;\n }\n\n /**\n * Get the widget configuration\n */\n getConfig(): WidgetConfig {\n return this.config;\n }\n\n /**\n * Subscribe to events\n */\n on<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): () => void {\n return this.events.on(event, handler);\n }\n\n /**\n * Unsubscribe from events\n */\n off<K extends keyof WidgetEvents>(\n event: K,\n handler: (payload: WidgetEvents[K]) => void\n ): void {\n this.events.off(event, handler);\n }\n\n /**\n * Clean up resources\n */\n destroy(): void {\n this.events.clear();\n this.setState({ status: 'idle' });\n }\n\n private setState(newState: WidgetState): void {\n const previous = this.state;\n this.state = newState;\n this.events.emit('state:change', { previous, current: newState });\n }\n}\n\n"]}