@bootdesk/js-web-adapter-core 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client/HttpClient.ts","../src/events/base/ChatEvent.ts","../src/events/MessagePostedEvent.ts","../src/events/MessageEditedEvent.ts","../src/events/MessageDeletedEvent.ts","../src/events/ReactionAddedEvent.ts","../src/events/ReactionRemovedEvent.ts","../src/events/TypingStartedEvent.ts","../src/events/StreamingChunkEvent.ts","../src/events/DMRequestedEvent.ts","../src/events/ChatEventFactory.ts","../src/utils/eventIdGenerator.ts","../src/client/WebChatClient.ts","../src/client/PusherBroadcastClient.ts","../src/client/LaravelEchoBroadcastClient.ts","../src/push/PushManager.ts","../src/push/PushSubscriptionManager.ts"],"sourcesContent":["export interface HttpClientConfig {\n apiUrl: string;\n headers?: Record<string, string>;\n timeout?: number;\n verifyToken?: string;\n}\n\nexport interface ChatResponse {\n id: string;\n role: \"assistant\" | \"user\";\n text: string;\n attachments?: Array<{\n type: string;\n url: string;\n name?: string;\n mime_type?: string;\n size?: number;\n }>;\n events?: Array<Record<string, unknown>>;\n}\n\nexport class HttpClient {\n private config: Required<Pick<HttpClientConfig, \"apiUrl\" | \"timeout\">> & {\n headers: Record<string, string>;\n };\n\n constructor(config: HttpClientConfig) {\n const headers: Record<string, string> = { ...config.headers };\n if (config.verifyToken) {\n headers[\"X-Verify-Token\"] = config.verifyToken;\n }\n this.config = { apiUrl: config.apiUrl, timeout: config.timeout ?? 30000, headers };\n }\n\n async get(url: string, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"GET\",\n headers: this.config.headers,\n signal: combined,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async post(url: string, body: unknown, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.config.headers },\n signal: combined,\n body: JSON.stringify(body),\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async delete(url: string, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"DELETE\",\n headers: this.config.headers,\n signal: combined,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n const text = await response.text();\n return text ? JSON.parse(text) : undefined;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async sendMessage(\n messages: Array<{\n id: string;\n role: string;\n text: string;\n attachments?: Array<{ url: string; name?: string; mime_type?: string; size?: number }>;\n }>,\n endpoint: string = \"/api/webhooks/web\",\n conversationId?: string,\n ): Promise<ChatResponse> {\n return this.post(endpoint, { id: conversationId, messages }) as Promise<ChatResponse>;\n }\n\n async sendAction(\n actionId: string,\n value: string,\n messageId: string,\n conversationId: string,\n endpoint: string = \"/api/webhooks/web\",\n ): Promise<Record<string, unknown>> {\n return this.post(endpoint, {\n id: conversationId,\n action: { actionId, value, messageId },\n }) as Promise<Record<string, unknown>>;\n }\n\n async editMessage(\n messageId: string,\n newText: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/edit\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.post(url, { text: newText });\n }\n\n async deleteMessage(\n messageId: string,\n endpointTemplate: string = \"/api/chat/messages/{id}\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.delete(url);\n }\n\n async addReaction(\n messageId: string,\n emoji: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/reactions\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.post(url, { emoji });\n }\n\n async removeReaction(\n messageId: string,\n emoji: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/reactions/{emoji}\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId, emoji });\n await this.delete(url);\n }\n\n private resolve(url: string): string {\n return /^https?:\\/\\//.test(url) ? url : `${this.config.apiUrl}${url}`;\n }\n\n private expandTemplate(template: string, params: Record<string, string>): string {\n let url = template;\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`{${key}}`, encodeURIComponent(value));\n }\n return this.resolve(url);\n }\n}\n","export abstract class ChatEvent {\n readonly type: string;\n readonly threadId: string;\n readonly timestamp: number;\n\n constructor(type: string, threadId: string, timestamp: number) {\n this.type = type;\n this.threadId = threadId;\n this.timestamp = timestamp;\n }\n\n static fromJSON: ((json: Record<string, unknown>) => ChatEvent) | undefined;\n}\n\nexport class UnknownEvent extends ChatEvent {\n readonly data: Record<string, unknown>;\n\n constructor(type: string, threadId: string, data: Record<string, unknown>, timestamp: number) {\n super(type, threadId, timestamp);\n this.data = data;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User, Card } from \"../types\";\n\nexport class MessagePostedEvent extends ChatEvent {\n readonly messageId: string;\n readonly text: string;\n readonly author: User;\n readonly card?: Card;\n readonly attachments?: Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>;\n\n constructor(\n threadId: string,\n messageId: string,\n text: string,\n author: User,\n card?: Card,\n attachments?: Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>,\n timestamp?: number,\n ) {\n super(\"message.posted\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.text = text;\n this.author = author;\n this.card = card;\n this.attachments = attachments;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { Card } from \"../types\";\n\nexport class MessageEditedEvent extends ChatEvent {\n readonly messageId: string;\n readonly newText: string;\n readonly card?: Card;\n\n constructor(\n threadId: string,\n messageId: string,\n newText: string,\n card?: Card,\n timestamp?: number,\n ) {\n super(\"message.edited\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.newText = newText;\n this.card = card;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class MessageDeletedEvent extends ChatEvent {\n readonly messageId: string;\n\n constructor(threadId: string, messageId: string, timestamp?: number) {\n super(\"message.deleted\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User } from \"../types\";\n\nexport class ReactionAddedEvent extends ChatEvent {\n readonly messageId: string;\n readonly emoji: string;\n readonly user: User;\n\n constructor(threadId: string, messageId: string, emoji: string, user: User, timestamp?: number) {\n super(\"reaction.added\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.emoji = emoji;\n this.user = user;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User } from \"../types\";\n\nexport class ReactionRemovedEvent extends ChatEvent {\n readonly messageId: string;\n readonly emoji: string;\n readonly user: User;\n\n constructor(threadId: string, messageId: string, emoji: string, user: User, timestamp?: number) {\n super(\"reaction.removed\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.emoji = emoji;\n this.user = user;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class TypingStartedEvent extends ChatEvent {\n readonly userId: string;\n\n constructor(threadId: string, userId: string, timestamp?: number) {\n super(\"typing.started\", threadId, timestamp ?? Date.now());\n this.userId = userId;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class StreamingChunkEvent extends ChatEvent {\n readonly messageId: string;\n readonly chunk: string;\n readonly isFinal: boolean;\n\n constructor(\n threadId: string,\n messageId: string,\n chunk: string,\n isFinal: boolean,\n timestamp?: number,\n ) {\n super(\"streaming.chunk\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.chunk = chunk;\n this.isFinal = isFinal;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class DMRequestedEvent extends ChatEvent {\n readonly userId: string;\n\n constructor(threadId: string, userId: string, timestamp?: number) {\n super(\"dm.requested\", threadId, timestamp ?? Date.now());\n this.userId = userId;\n }\n}\n","import { ChatEvent, UnknownEvent } from \"./base/ChatEvent\";\nimport type { Card, User } from \"../types\";\nimport { MessagePostedEvent } from \"./MessagePostedEvent\";\nimport { MessageEditedEvent } from \"./MessageEditedEvent\";\nimport { MessageDeletedEvent } from \"./MessageDeletedEvent\";\nimport { ReactionAddedEvent } from \"./ReactionAddedEvent\";\nimport { ReactionRemovedEvent } from \"./ReactionRemovedEvent\";\nimport { TypingStartedEvent } from \"./TypingStartedEvent\";\nimport { StreamingChunkEvent } from \"./StreamingChunkEvent\";\nimport { DMRequestedEvent } from \"./DMRequestedEvent\";\n\nfunction parseCard(value: unknown): Card | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const obj = value as Record<string, unknown>;\n if (typeof obj.type !== \"string\") return undefined;\n return obj as unknown as Card;\n}\n\nexport function parseChatEvent(json: Record<string, unknown>): ChatEvent {\n const type = json.type as string;\n const threadId = json.threadId as string;\n const timestamp = json.timestamp as number;\n const data = (json.data ?? {}) as Record<string, unknown>;\n\n switch (type) {\n case \"message.posted\":\n return new MessagePostedEvent(\n threadId,\n data.messageId as string,\n data.text as string,\n data.author as User,\n parseCard(data.card),\n data.attachments as Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>,\n timestamp,\n );\n case \"message.edited\":\n return new MessageEditedEvent(\n threadId,\n data.messageId as string,\n data.newText as string,\n parseCard(data.card),\n timestamp,\n );\n case \"message.deleted\":\n return new MessageDeletedEvent(threadId, data.messageId as string, timestamp);\n case \"reaction.added\":\n return new ReactionAddedEvent(\n threadId,\n data.messageId as string,\n data.emoji as string,\n data.user as User,\n timestamp,\n );\n case \"reaction.removed\":\n return new ReactionRemovedEvent(\n threadId,\n data.messageId as string,\n data.emoji as string,\n data.user as User,\n timestamp,\n );\n case \"typing.started\":\n return new TypingStartedEvent(threadId, data.userId as string, timestamp);\n case \"streaming.chunk\":\n return new StreamingChunkEvent(\n threadId,\n data.messageId as string,\n data.chunk as string,\n data.isFinal as boolean,\n timestamp,\n );\n case \"dm.requested\":\n return new DMRequestedEvent(threadId, data.userId as string, timestamp);\n default:\n return new UnknownEvent(type, threadId, data, timestamp);\n }\n}\n\n// Wire up the static method\nChatEvent.fromJSON = parseChatEvent;\n","export function generateId(): string {\n return `msg-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\nexport function generateConversationId(): string {\n return `conv-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n","import { HttpClient } from \"./HttpClient\";\nimport type { BroadcastClient, EventHandlers, Unsubscribe } from \"./BroadcastClient\";\nimport type { Message } from \"../types\";\nimport { ChatEvent } from \"../events/base/ChatEvent\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport { generateId, generateConversationId } from \"../utils/eventIdGenerator\";\n\nexport interface WebChatClientConfig {\n apiUrl: string;\n userId: string;\n userName: string;\n broadcastClient?: BroadcastClient;\n headers?: Record<string, string>;\n verifyToken?: string;\n conversationId?: string;\n endpoints?: {\n sendMessage?: string;\n loadMessages?: string;\n editMessage?: string;\n deleteMessage?: string;\n addReaction?: string;\n removeReaction?: string;\n };\n features?: {\n editMessages?: boolean;\n deleteMessages?: boolean;\n reactions?: boolean;\n };\n}\n\ninterface StreamingState {\n messageId: string;\n accumulatedText: string;\n isComplete: boolean;\n}\n\nexport interface LoadMessagesOptions {\n limit?: number;\n before?: number;\n after?: number;\n skipStateSeed?: boolean;\n}\n\nexport interface LoadMessagesResult {\n messages: Message[];\n hasMore: boolean;\n nextCursor?: number;\n prevCursor?: number;\n}\n\nexport class WebChatClient {\n private config: WebChatClientConfig;\n private httpClient: HttpClient;\n private broadcastClient?: BroadcastClient;\n private conversationId: string;\n private messages: Message[] = [];\n private currentUserId: string;\n private eventHandlers: EventHandlers = {};\n private streamingMessages: Map<string, StreamingState> = new Map();\n private pendingTyping: ReturnType<typeof setTimeout> | null = null;\n private subscribers: Map<string, Array<(event: any) => void>> = new Map();\n private unsubscribeUserChannel?: Unsubscribe;\n\n constructor(config: WebChatClientConfig) {\n this.config = config;\n this.httpClient = new HttpClient({\n apiUrl: config.apiUrl,\n headers: {\n \"X-User-Id\": config.userId,\n \"X-User-Name\": config.userName,\n ...(config.headers ?? {}),\n },\n verifyToken: config.verifyToken,\n });\n this.broadcastClient = config.broadcastClient;\n this.conversationId = config.conversationId ?? generateConversationId();\n this.currentUserId = config.userId;\n }\n\n async connect(): Promise<void> {\n if (this.broadcastClient) {\n this.broadcastClient.connect();\n\n const threadId = this.getThreadId();\n const threadEvents: EventHandlers = {\n onMessagePosted: (event) => this.handleMessagePosted(event),\n };\n\n if (this.config.features?.editMessages) {\n threadEvents.onMessageEdited = (event) => this.handleMessageEdited(event);\n }\n if (this.config.features?.deleteMessages) {\n threadEvents.onMessageDeleted = (event) => this.handleMessageDeleted(event);\n }\n if (this.config.features?.reactions) {\n threadEvents.onReactionAdded = (event) => this.handleReactionAdded(event);\n threadEvents.onReactionRemoved = (event) => this.handleReactionRemoved(event);\n }\n\n this.broadcastClient.subscribe(threadId, threadEvents);\n\n this.unsubscribeUserChannel = this.broadcastClient.subscribeToUser(\n threadId,\n this.currentUserId,\n {\n onTypingStarted: (event) => this.handleTypingStarted(event),\n onStreamingChunk: (event) => this.handleStreamingChunk(event),\n onDMRequested: (event) => this.handleDMRequested(event),\n },\n );\n }\n }\n\n disconnect(): void {\n this.unsubscribeUserChannel?.();\n this.unsubscribeUserChannel = undefined;\n this.broadcastClient?.disconnect();\n this.streamingMessages.clear();\n }\n\n async loadMessages(\n options?: LoadMessagesOptions,\n signal?: AbortSignal,\n ): Promise<LoadMessagesResult> {\n const endpoint = this.config.endpoints?.loadMessages ?? \"/api/chat/messages\";\n const threadId = this.getThreadId();\n const params = new URLSearchParams({\n threadId,\n limit: String(options?.limit ?? 50),\n });\n if (options?.before) params.set(\"before\", String(options.before));\n if (options?.after) params.set(\"after\", String(options.after));\n\n const response = (await this.httpClient.get(\n `${endpoint}?${params.toString()}`,\n signal,\n )) as Record<string, unknown>;\n const messages: Message[] = ((response.messages as any[]) || []).map((msg) => ({\n id: msg.id,\n threadId,\n content: { text: msg.text, cards: msg.card ? [msg.card] : undefined },\n author: {\n id: msg.author.id,\n name: msg.author.name,\n isBot: msg.author.isBot ?? false,\n isMe: msg.author.id === this.currentUserId,\n },\n timestamp: msg.timestamp,\n attachments: msg.attachments?.map((a: any) => ({\n id: `att-${msg.id}-${a.url}`,\n url: a.url,\n name: a.name,\n type: a.type,\n mimeType: a.mime_type,\n size: a.size,\n })),\n reactions: msg.reactions ?? [],\n }));\n\n if (!options?.before && !options?.after && !options?.skipStateSeed) {\n this.messages = messages;\n this.notifySubscribers(\"messages:loaded\", messages);\n }\n\n return {\n messages,\n hasMore: (response.hasMore as boolean) ?? false,\n nextCursor: response.nextCursor as number | undefined,\n prevCursor: response.prevCursor as number | undefined,\n };\n }\n\n async sendMessage(text: string, attachments: any[] = []): Promise<void> {\n const messageId = generateId();\n\n const userMessage: Message = {\n id: messageId,\n threadId: this.getThreadId(),\n content: { text },\n author: { id: this.currentUserId, name: this.config.userName, isMe: true },\n timestamp: Date.now(),\n attachments:\n attachments.length > 0\n ? attachments.map((a, i) => ({\n id: `att-${messageId}-${i}`,\n name: a.name || \"\",\n url: a.url,\n size: a.size,\n mimeType: a.mimeType,\n }))\n : undefined,\n };\n\n this.messages.push(userMessage);\n this.notifySubscribers(\"message:added\", userMessage);\n\n const endpoint = this.config.endpoints?.sendMessage ?? \"/api/webhooks/web\";\n const response = await this.httpClient.sendMessage(\n [\n {\n id: messageId,\n role: \"user\",\n text,\n attachments: attachments?.map((a: any) => ({\n url: a.url,\n name: a.name,\n mime_type: a.mimeType,\n size: a.size,\n })),\n },\n ],\n endpoint,\n this.conversationId,\n );\n\n if (response.events) {\n response.events.forEach((eventData) => {\n const event = parseChatEvent(eventData);\n this.dispatchEvent(event);\n });\n }\n\n if (response.text && !response.events?.some((e: any) => e.type === \"message.posted\")) {\n const assistantMessage: Message = {\n id: response.id || generateId(),\n threadId: this.getThreadId(),\n content: { text: response.text },\n author: { id: \"assistant\", name: \"Assistant\", isBot: true },\n timestamp: Date.now(),\n attachments: (response.attachments as any[])?.map((a, i) => ({\n id: `att-${response.id || \"msg\"}-${i}`,\n name: a.name || \"\",\n url: a.url || \"\",\n type: a.type,\n mimeType: a.mime_type,\n size: a.size,\n })),\n };\n this.messages.push(assistantMessage);\n this.notifySubscribers(\"message:added\", assistantMessage);\n }\n }\n\n async sendAction(messageId: string, actionId: string, value: string): Promise<void> {\n const endpoint = this.config.endpoints?.sendMessage ?? \"/api/webhooks/web\";\n const response = await this.httpClient.sendAction(\n actionId,\n value,\n messageId,\n this.conversationId,\n endpoint,\n );\n\n if (response.events) {\n (response.events as any[]).forEach((eventData) => {\n const event = parseChatEvent(eventData);\n this.dispatchEvent(event);\n });\n }\n }\n\n async editMessage(messageId: string, newText: string): Promise<void> {\n if (!this.config.features?.editMessages) {\n throw new Error(\"Edit messages not enabled. Set features.editMessages = true in config.\");\n }\n const endpoint = this.config.endpoints?.editMessage ?? \"/api/chat/messages/{id}/edit\";\n await this.httpClient.editMessage(messageId, newText, endpoint);\n }\n\n async deleteMessage(messageId: string): Promise<void> {\n if (!this.config.features?.deleteMessages) {\n throw new Error(\"Delete messages not enabled. Set features.deleteMessages = true in config.\");\n }\n const endpoint = this.config.endpoints?.deleteMessage ?? \"/api/chat/messages/{id}\";\n await this.httpClient.deleteMessage(messageId, endpoint);\n }\n\n async addReaction(messageId: string, emoji: string): Promise<void> {\n if (!this.config.features?.reactions) {\n throw new Error(\"Reactions not enabled. Set features.reactions = true in config.\");\n }\n const endpoint = this.config.endpoints?.addReaction ?? \"/api/chat/messages/{id}/reactions\";\n await this.httpClient.addReaction(messageId, emoji, endpoint);\n }\n\n async removeReaction(messageId: string, emoji: string): Promise<void> {\n if (!this.config.features?.reactions) {\n throw new Error(\"Reactions not enabled. Set features.reactions = true in config.\");\n }\n const endpoint =\n this.config.endpoints?.removeReaction ?? \"/api/chat/messages/{id}/reactions/{emoji}\";\n await this.httpClient.removeReaction(messageId, emoji, endpoint);\n }\n\n onMessagePosted(\n handler: (event: import(\"../events/MessagePostedEvent\").MessagePostedEvent) => void,\n ): Unsubscribe {\n return this.addEventListener(\"message.posted\", handler);\n }\n\n onStreamingChunk(\n handler: (event: import(\"../events/StreamingChunkEvent\").StreamingChunkEvent) => void,\n ): Unsubscribe {\n return this.addEventListener(\"streaming.chunk\", handler);\n }\n\n onTypingStarted(\n handler: (event: import(\"../events/TypingStartedEvent\").TypingStartedEvent) => void,\n ): Unsubscribe {\n return this.addEventListener(\"typing.started\", handler);\n }\n\n getConversationId(): string {\n return this.conversationId;\n }\n getMessages(): Message[] {\n return [...this.messages];\n }\n getThreadId(): string {\n return `web:${this.currentUserId}:${this.conversationId}`;\n }\n getCurrentUserId(): string {\n return this.currentUserId;\n }\n getFeatures(): NonNullable<WebChatClientConfig[\"features\"]> {\n return this.config.features ?? {};\n }\n getEndpoints(): NonNullable<WebChatClientConfig[\"endpoints\"]> {\n return this.config.endpoints ?? {};\n }\n getHttpClient(): HttpClient {\n return this.httpClient;\n }\n\n addEventListener(eventType: string, handler: (event: any) => void): Unsubscribe {\n if (!this.subscribers.has(eventType)) this.subscribers.set(eventType, []);\n this.subscribers.get(eventType)!.push(handler);\n return () => {\n const handlers = this.subscribers.get(eventType);\n if (handlers) {\n const index = handlers.indexOf(handler);\n if (index !== -1) handlers.splice(index, 1);\n }\n };\n }\n\n private handleMessagePosted(event: any): void {\n if (this.messages.some((m) => m.id === event.messageId)) return;\n if (this.streamingMessages.has(event.messageId)) return;\n\n const message: Message = {\n id: event.messageId,\n threadId: event.threadId,\n content: { text: event.text, cards: event.card ? [event.card] : undefined },\n author: event.author,\n timestamp: event.timestamp,\n attachments: event.attachments?.map((a: any) => ({\n id: `att-${event.messageId}-${Math.random().toString(36).slice(2, 8)}`,\n name: a.name || \"\",\n url: a.url || \"\",\n type: a.type,\n mimeType: a.mimeType,\n size: a.size,\n })),\n };\n this.messages.push(message);\n this.notifySubscribers(\"message:added\", message);\n this.notifySubscribers(\"message.posted\", event);\n }\n\n private handleMessageEdited(event: any): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (message?.content) {\n message.content.text = event.newText;\n this.notifySubscribers(\"message:edited\", {\n messageId: event.messageId,\n newText: event.newText,\n });\n }\n }\n\n private handleMessageDeleted(event: any): void {\n const index = this.messages.findIndex((m) => m.id === event.messageId);\n if (index !== -1) {\n this.messages.splice(index, 1);\n this.notifySubscribers(\"message:deleted\", { messageId: event.messageId });\n }\n }\n\n private handleReactionAdded(event: any): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (!message) return;\n if (!message.reactions) message.reactions = [];\n\n const existing = message.reactions.find((r) => r.emoji === event.emoji);\n if (existing) {\n existing.count++;\n existing.users.push(event.user.id);\n } else {\n message.reactions.push({ emoji: event.emoji, count: 1, users: [event.user.id] });\n }\n this.notifySubscribers(\"reaction:added\", { messageId: event.messageId, emoji: event.emoji });\n }\n\n private handleReactionRemoved(event: any): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (!message?.reactions) return;\n\n const index = message.reactions.findIndex((r) => r.emoji === event.emoji);\n if (index !== -1) {\n const reaction = message.reactions[index]!;\n reaction.count--;\n reaction.users = reaction.users.filter((id) => id !== event.user.id);\n if (reaction.count === 0) message.reactions.splice(index, 1);\n }\n this.notifySubscribers(\"reaction:removed\", { messageId: event.messageId, emoji: event.emoji });\n }\n\n private handleStreamingChunk(event: any): void {\n const { messageId, chunk, isFinal } = event;\n\n if (!this.streamingMessages.has(messageId)) {\n this.streamingMessages.set(messageId, { messageId, accumulatedText: \"\", isComplete: false });\n this.notifySubscribers(\"streaming:started\", { messageId });\n }\n\n const state = this.streamingMessages.get(messageId)!;\n state.accumulatedText += chunk;\n\n if (isFinal) {\n state.isComplete = true;\n if (!this.messages.some((m) => m.id === messageId)) {\n const message: Message = {\n id: messageId,\n threadId: event.threadId,\n content: { text: state.accumulatedText },\n author: { id: \"assistant\", name: \"Assistant\", isBot: true },\n timestamp: event.timestamp,\n };\n this.messages.push(message);\n this.notifySubscribers(\"message:added\", message);\n }\n this.streamingMessages.delete(messageId);\n this.notifySubscribers(\"streaming:complete\", { messageId, text: state.accumulatedText });\n } else {\n this.notifySubscribers(\"streaming:chunk\", {\n messageId,\n chunk,\n fullText: state.accumulatedText,\n });\n }\n this.notifySubscribers(\"streaming.chunk\", event);\n }\n\n private handleTypingStarted(event: any): void {\n if (this.pendingTyping) clearTimeout(this.pendingTyping);\n this.notifySubscribers(\"typing:started\", { userId: event.userId });\n this.pendingTyping = setTimeout(() => {\n this.notifySubscribers(\"typing:stopped\", { userId: event.userId });\n }, 3000);\n this.notifySubscribers(\"typing.started\", event);\n }\n\n private handleDMRequested(event: any): void {\n this.notifySubscribers(\"dm.requested\", { userId: event.userId, threadId: event.threadId });\n }\n\n private notifySubscribers(eventType: string, data: any): void {\n this.subscribers.get(eventType)?.forEach((handler) => handler(data));\n }\n\n private dispatchEvent(event: ChatEvent): void {\n switch (event.type) {\n case \"message.posted\":\n this.handleMessagePosted(event);\n break;\n case \"message.edited\":\n this.handleMessageEdited(event);\n break;\n case \"message.deleted\":\n this.handleMessageDeleted(event);\n break;\n case \"reaction.added\":\n this.handleReactionAdded(event);\n break;\n case \"reaction.removed\":\n this.handleReactionRemoved(event);\n break;\n case \"typing.started\":\n this.handleTypingStarted(event);\n break;\n case \"streaming.chunk\":\n this.handleStreamingChunk(event);\n break;\n case \"dm.requested\":\n this.handleDMRequested(event);\n break;\n }\n }\n}\n","import {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./BroadcastClient\";\nimport { ChatEvent } from \"../events/base/ChatEvent\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type Pusher from \"pusher-js\";\nimport type { Channel as PusherChannel } from \"pusher-js\";\n\nexport interface PusherConfig {\n key: string;\n cluster?: string;\n host?: string;\n port?: number;\n forceTLS?: boolean;\n authEndpoint?: string;\n}\n\nexport class PusherBroadcastClient implements BroadcastClient {\n private pusher: Pusher;\n private channelPrefix: string;\n private threadChannelType: \"public\" | \"private\" | \"presence\";\n private userChannelType: \"private\" | \"presence\";\n private subscriptions: Map<string, PusherChannel> = new Map();\n\n constructor(pusher: Pusher, channelPrefix?: string, channelTypes?: ChannelTypeConfig);\n constructor(config: PusherConfig, channelPrefix?: string, channelTypes?: ChannelTypeConfig);\n constructor(\n pusherOrConfig: Pusher | PusherConfig,\n channelPrefix: string = \"chat\",\n channelTypes?: ChannelTypeConfig,\n ) {\n this.channelPrefix = channelPrefix;\n this.threadChannelType = channelTypes?.threadChannel ?? \"public\";\n this.userChannelType = channelTypes?.userChannel ?? \"private\";\n\n if (\"key\" in pusherOrConfig) {\n const PusherCtor = (globalThis as any).Pusher ?? (globalThis as any).pusherJs;\n if (!PusherCtor) {\n throw new Error(\"pusher-js not found. Install it or pass a Pusher instance.\");\n }\n this.pusher = new PusherCtor((pusherOrConfig as PusherConfig).key, pusherOrConfig) as Pusher;\n } else {\n this.pusher = pusherOrConfig as Pusher;\n }\n }\n\n private buildChannelName(base: string, type: \"public\" | \"private\" | \"presence\"): string {\n switch (type) {\n case \"private\":\n return `private-${base}`;\n case \"presence\":\n return `presence-${base}`;\n default:\n return base;\n }\n }\n\n connect(): void {\n if (this.pusher.connection?.state !== \"connected\") {\n this.pusher.connect();\n }\n }\n\n disconnect(): void {\n this.subscriptions.forEach((channel) => channel.unbind_all?.() ?? channel.unsubscribe?.());\n this.subscriptions.clear();\n this.pusher.disconnect?.();\n }\n\n subscribe(threadId: string, handlers: EventHandlers): Unsubscribe {\n const baseName = `${this.channelPrefix}.${threadId}`;\n const channelName = this.buildChannelName(baseName, this.threadChannelType);\n const channel = this.pusher.subscribe(channelName);\n const key = `thread:${threadId}`;\n this.subscriptions.set(key, channel);\n\n const threadEvents = [\n \"message.posted\",\n \"message.edited\",\n \"message.deleted\",\n \"reaction.added\",\n \"reaction.removed\",\n ] as const;\n\n threadEvents.forEach((eventType) => {\n const eventName = `${this.channelPrefix}.${eventType}`;\n channel.bind(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n this.dispatchToHandler(event, handlers);\n });\n });\n\n return () => {\n channel.unbind_all?.();\n this.pusher.unsubscribe(channelName);\n this.subscriptions.delete(key);\n };\n }\n\n subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Unsubscribe {\n const baseName = `${this.channelPrefix}.${threadId}.${userId}`;\n const channelName = this.buildChannelName(baseName, this.userChannelType);\n const channel = this.pusher.subscribe(channelName);\n const key = `user:${threadId}:${userId}`;\n this.subscriptions.set(key, channel);\n\n const userEvents = [\"typing.started\", \"streaming.chunk\", \"dm.requested\"] as const;\n\n userEvents.forEach((eventType) => {\n const eventName = `${this.channelPrefix}.${eventType}`;\n channel.bind(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n this.dispatchToHandler(event, handlers);\n });\n });\n\n return () => {\n channel.unbind_all?.();\n this.pusher.unsubscribe(channelName);\n this.subscriptions.delete(key);\n };\n }\n\n isConnected(): boolean {\n return this.pusher.connection?.state === \"connected\";\n }\n\n private dispatchToHandler(event: ChatEvent, handlers: EventHandlers): void {\n switch (event.type) {\n case \"message.posted\":\n handlers.onMessagePosted?.(event as any);\n break;\n case \"message.edited\":\n handlers.onMessageEdited?.(event as any);\n break;\n case \"message.deleted\":\n handlers.onMessageDeleted?.(event as any);\n break;\n case \"reaction.added\":\n handlers.onReactionAdded?.(event as any);\n break;\n case \"reaction.removed\":\n handlers.onReactionRemoved?.(event as any);\n break;\n case \"typing.started\":\n handlers.onTypingStarted?.(event as any);\n break;\n case \"streaming.chunk\":\n handlers.onStreamingChunk?.(event as any);\n break;\n case \"dm.requested\":\n handlers.onDMRequested?.(event as any);\n break;\n }\n }\n}\n","import {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./BroadcastClient\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type Echo from \"laravel-echo\";\n\ninterface EchoChannel {\n listen(event: string, callback: (data: unknown) => void): this;\n unsubscribe(): void;\n stopListening(event?: string, callback?: (data: unknown) => void): this;\n}\n\nexport class LaravelEchoBroadcastClient implements BroadcastClient {\n private echo: Echo<any>;\n private channelPrefix: string;\n private threadChannelType: \"public\" | \"private\" | \"presence\";\n private userChannelType: \"private\" | \"presence\";\n private subscriptions: Map<string, EchoChannel> = new Map();\n\n constructor(echo: Echo<any>, channelPrefix: string = \"chat\", channelTypes?: ChannelTypeConfig) {\n this.echo = echo;\n this.channelPrefix = channelPrefix;\n this.threadChannelType = channelTypes?.threadChannel ?? \"public\";\n this.userChannelType = channelTypes?.userChannel ?? \"private\";\n }\n\n private subscribeToEcho(name: string, type: \"public\" | \"private\" | \"presence\"): EchoChannel {\n switch (type) {\n case \"private\":\n return this.echo.private(name) as unknown as EchoChannel;\n case \"presence\":\n return this.echo.join(name) as unknown as EchoChannel;\n default:\n return this.echo.channel(name) as unknown as EchoChannel;\n }\n }\n\n connect(): void | Promise<void> {\n return Promise.resolve();\n }\n\n disconnect(): void {\n this.subscriptions.forEach((channel) => {\n channel.unsubscribe?.();\n channel.stopListening?.();\n });\n this.subscriptions.clear();\n }\n\n subscribe(threadId: string, handlers: EventHandlers): Unsubscribe {\n const channelName = `${this.channelPrefix}.${threadId}`;\n const channel = this.subscribeToEcho(channelName, this.threadChannelType);\n const key = `thread:${threadId}`;\n this.subscriptions.set(key, channel);\n\n const threadEvents: Array<{ type: string; handler: keyof EventHandlers }> = [\n { type: \"message.posted\", handler: \"onMessagePosted\" },\n { type: \"message.edited\", handler: \"onMessageEdited\" },\n { type: \"message.deleted\", handler: \"onMessageDeleted\" },\n { type: \"reaction.added\", handler: \"onReactionAdded\" },\n { type: \"reaction.removed\", handler: \"onReactionRemoved\" },\n ];\n\n threadEvents.forEach(({ type, handler }) => {\n const eventName = `.${this.channelPrefix}.${type}`;\n channel.listen(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n (handlers[handler] as any)?.(event);\n });\n });\n\n return () => {\n channel.unsubscribe?.();\n this.subscriptions.delete(key);\n };\n }\n\n subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Unsubscribe {\n const channelName = `${this.channelPrefix}.${threadId}.${userId}`;\n const channel = this.subscribeToEcho(channelName, this.userChannelType);\n const key = `user:${threadId}:${userId}`;\n this.subscriptions.set(key, channel);\n\n const userEvents: Array<{ type: string; handler: keyof EventHandlers }> = [\n { type: \"typing.started\", handler: \"onTypingStarted\" },\n { type: \"streaming.chunk\", handler: \"onStreamingChunk\" },\n { type: \"dm.requested\", handler: \"onDMRequested\" },\n ];\n\n userEvents.forEach(({ type, handler }) => {\n const eventName = `.${this.channelPrefix}.${type}`;\n channel.listen(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n (handlers[handler] as any)?.(event);\n });\n });\n\n return () => {\n channel.unsubscribe?.();\n this.subscriptions.delete(key);\n };\n }\n\n isConnected(): boolean {\n try {\n const connector = (this.echo as any).connector;\n if (!connector) return false;\n\n if (connector.pusher?.connection?.state === \"connected\") return true;\n if (connector.socket?.connected) return true;\n\n return false;\n } catch {\n return false;\n }\n }\n}\n","import type { PushConfig, PushSubscriptionStatus, PushEventData } from \"./types\";\n\nexport class PushManager {\n private config: PushConfig;\n private registration: ServiceWorkerRegistration | null = null;\n private status: PushSubscriptionStatus = \"unsupported\";\n private statusListeners: Set<(status: PushSubscriptionStatus) => void> = new Set();\n private messageListeners: Set<(data: PushEventData) => void> = new Set();\n\n constructor(config: PushConfig) {\n this.config = config;\n }\n\n static isSupported(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n \"serviceWorker\" in navigator &&\n \"PushManager\" in window &&\n \"Notification\" in window\n );\n }\n\n getStatus(): PushSubscriptionStatus {\n return this.status;\n }\n\n onStatusChange(listener: (status: PushSubscriptionStatus) => void): () => void {\n this.statusListeners.add(listener);\n return () => {\n this.statusListeners.delete(listener);\n };\n }\n\n onMessage(listener: (data: PushEventData) => void): () => void {\n this.messageListeners.add(listener);\n return () => {\n this.messageListeners.delete(listener);\n };\n }\n\n async initialize(): Promise<void> {\n if (!PushManager.isSupported()) {\n this.setStatus(\"unsupported\");\n return;\n }\n if (Notification.permission === \"denied\") {\n this.setStatus(\"denied\");\n return;\n }\n\n try {\n this.registration = await navigator.serviceWorker.register(\n this.config.serviceWorkerUrl || \"/chat-service-worker.js\",\n { scope: this.config.serviceWorkerScope || \"/\" },\n );\n await navigator.serviceWorker.ready;\n\n const subscription = await this.registration.pushManager.getSubscription();\n this.setStatus(subscription ? \"subscribed\" : \"default\");\n } catch {\n this.setStatus(\"error\");\n }\n }\n\n async subscribe(): Promise<void> {\n if (!this.registration)\n throw new Error(\"PushManager not initialized. Call initialize() first.\");\n\n this.setStatus(\"subscribing\");\n\n try {\n let subscription = await this.registration.pushManager.getSubscription();\n\n if (!subscription) {\n const permission = await Notification.requestPermission();\n if (permission !== \"granted\") {\n this.setStatus(permission === \"denied\" ? \"denied\" : \"default\");\n return;\n }\n\n const vapidPublicKey = await this.config.getVapidPublicKey();\n const convertedKey = this.urlBase64ToUint8Array(vapidPublicKey);\n subscription = await this.registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: convertedKey.buffer as ArrayBuffer,\n });\n }\n\n await this.config.onSubscribe(subscription.toJSON());\n this.setStatus(\"subscribed\");\n } catch {\n this.setStatus(\"error\");\n throw new Error(\"Push subscription failed\");\n }\n }\n\n async unsubscribe(): Promise<void> {\n if (!this.registration) return;\n\n try {\n const subscription = await this.registration.pushManager.getSubscription();\n if (subscription) {\n await this.config.onUnsubscribe(subscription.toJSON());\n await subscription.unsubscribe();\n }\n this.setStatus(\"default\");\n } catch {\n this.setStatus(\"error\");\n throw new Error(\"Push unsubscription failed\");\n }\n }\n\n private urlBase64ToUint8Array(base64String: string): Uint8Array {\n const padding = \"=\".repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding).replace(/-/g, \"+\").replace(/_/g, \"/\");\n const rawData = atob(base64);\n return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0)));\n }\n\n private setStatus(status: PushSubscriptionStatus): void {\n this.status = status;\n this.statusListeners.forEach((listener) => listener(status));\n }\n}\n","import { HttpClient } from \"../client/HttpClient\";\nimport type { PushConfig } from \"./types\";\n\nexport function createPushSubscriptionHandlers(\n httpClient: HttpClient,\n userId: string,\n): Pick<PushConfig, \"onSubscribe\" | \"onUnsubscribe\"> {\n return {\n onSubscribe: async (subscription: PushSubscriptionJSON) => {\n await httpClient.post(\"/api/push/subscriptions\", {\n userId,\n subscription,\n userAgent: navigator.userAgent,\n });\n },\n onUnsubscribe: async (subscription: PushSubscriptionJSON) => {\n await httpClient.delete(\n `/api/push/subscriptions?userId=${encodeURIComponent(userId)}&endpoint=${encodeURIComponent(subscription.endpoint || \"\")}`,\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@bootdesk/js-web-adapter-core",
3
+ "version": "0.1.0",
4
+ "description": "Core JavaScript SDK for BootDesk Chat SDK WebAdapter",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "test": "vitest run",
22
+ "test:ui": "vitest --ui",
23
+ "lint": "eslint src",
24
+ "format": "prettier --write \"src/**/*.ts\"",
25
+ "format:check": "prettier --check \"src/**/*.ts\"",
26
+ "typecheck": "tsc --noEmit",
27
+ "docs": "typedoc --out ../../docs/_build/js/core src"
28
+ },
29
+ "peerDependencies": {
30
+ "laravel-echo": "^2.0.0",
31
+ "pusher-js": "^8.0.0"
32
+ },
33
+ "peerDependenciesMeta": {
34
+ "pusher-js": {
35
+ "optional": true
36
+ },
37
+ "laravel-echo": {
38
+ "optional": true
39
+ }
40
+ },
41
+ "devDependencies": {
42
+ "@eslint/js": "^10.0.1",
43
+ "eslint": "^10.4.0",
44
+ "eslint-config-prettier": "^10.1.8",
45
+ "laravel-echo": "^2.3.4",
46
+ "prettier": "^3.8.3",
47
+ "pusher-js": "^8.5.0",
48
+ "tsup": "^8.0.0",
49
+ "typescript": "^5.0.0",
50
+ "typescript-eslint": "^8.59.4",
51
+ "vitest": "^1.0.0"
52
+ }
53
+ }