@gigabuddy/chat-sdk 0.1.20 → 0.1.21
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/index.js +21 -0
- package/index.js.map +2 -2
- package/package.json +1 -1
- package/src/index.d.ts +1 -1
- package/src/lib/GigabuddyChat.d.ts +8 -1
- package/src/lib/types.d.ts +7 -0
package/index.js
CHANGED
|
@@ -1104,6 +1104,27 @@ var GigabuddyChat = class {
|
|
|
1104
1104
|
return { totalUnread: data.totalUnread ?? 0, totalMentions: data.totalMentions ?? 0 };
|
|
1105
1105
|
}
|
|
1106
1106
|
// ===========================================================================
|
|
1107
|
+
// User stats
|
|
1108
|
+
// ===========================================================================
|
|
1109
|
+
/**
|
|
1110
|
+
* Get per-user conversation statistics.
|
|
1111
|
+
* Optionally filter to a single user by contextInstanceId.
|
|
1112
|
+
*/
|
|
1113
|
+
async getUserStats(opts) {
|
|
1114
|
+
const headers = await this.buildHeaders();
|
|
1115
|
+
const response = await fetch(`${this.config.apiUrl}/chat/user-stats`, {
|
|
1116
|
+
method: "POST",
|
|
1117
|
+
headers,
|
|
1118
|
+
body: JSON.stringify(opts ?? {})
|
|
1119
|
+
});
|
|
1120
|
+
if (!response.ok) {
|
|
1121
|
+
const body = await response.text();
|
|
1122
|
+
throw new Error(`Failed to get user stats: ${response.status} ${body}`);
|
|
1123
|
+
}
|
|
1124
|
+
const data = await response.json();
|
|
1125
|
+
return data.users ?? [];
|
|
1126
|
+
}
|
|
1127
|
+
// ===========================================================================
|
|
1107
1128
|
// Lifecycle
|
|
1108
1129
|
// ===========================================================================
|
|
1109
1130
|
closeConversation(conversationId) {
|
package/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../libs/chat-sdk/src/lib/Conversation.ts", "../../../libs/chat-sdk/src/lib/SSEClient.ts", "../../../libs/chat-sdk/src/lib/GigabuddyChat.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Conversation\n *\n * Represents an active conversation. Events are received via the\n * parent GigabuddyChat's user stream \u2014 filtered by conversationId.\n * connect()/disconnect() are no-ops (kept for backward compat).\n */\n\nimport type {\n ChatEventBus,\n ChannelEvent,\n ConversationEventMap,\n GigabuddyChatConfig,\n Message,\n MessageContent,\n} from './types.js';\n\nexport class Conversation {\n readonly conversationId: string;\n private config: GigabuddyChatConfig;\n private eventBus: ChatEventBus | null;\n private unsubscribes: (() => void)[] = [];\n\n constructor(conversationId: string, config: GigabuddyChatConfig, eventBus?: ChatEventBus) {\n this.conversationId = conversationId;\n this.config = config;\n this.eventBus = eventBus ?? null;\n }\n\n private async buildHeaders(): Promise<Record<string, string>> {\n const token = await this.config.getToken();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n };\n if (this.config.userId) {\n headers['X-Chat-User-Id'] = this.config.userId;\n }\n return headers;\n }\n\n // ===========================================================================\n // Messages\n // ===========================================================================\n\n async sendMessage(content: string | MessageContent): Promise<void> {\n const headers = await this.buildHeaders();\n\n const body: Record<string, unknown> = {\n conversationId: this.conversationId,\n };\n\n if (typeof content === 'string') {\n body['text'] = content;\n } else {\n body['content'] = content;\n }\n\n const response = await fetch(`${this.config.apiUrl}/chat/send-message`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const responseBody = await response.text();\n throw new Error(`Failed to send message: ${response.status} ${responseBody}`);\n }\n }\n\n async replyTo(messageId: string, content: string | MessageContent): Promise<void> {\n const headers = await this.buildHeaders();\n\n const body: Record<string, unknown> = {\n conversationId: this.conversationId,\n parentMessageId: messageId,\n };\n\n if (typeof content === 'string') {\n body['text'] = content;\n } else {\n body['content'] = content;\n }\n\n const response = await fetch(`${this.config.apiUrl}/chat/reply-to-message`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const responseBody = await response.text();\n throw new Error(`Failed to reply to message: ${response.status} ${responseBody}`);\n }\n }\n\n async editMessage(messageId: string, content: string | MessageContent): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/edit-message`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n messageId,\n content,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to edit message: ${response.status} ${body}`);\n }\n }\n\n async deleteMessage(messageId: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/delete-message`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n messageId,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to delete message: ${response.status} ${body}`);\n }\n }\n\n async sendEphemeralMessage(targetUserId: string, content: string | MessageContent): Promise<void> {\n const headers = await this.buildHeaders();\n\n const body: Record<string, unknown> = {\n conversationId: this.conversationId,\n targetUserId,\n };\n\n if (typeof content === 'string') {\n body['text'] = content;\n } else {\n body['content'] = content;\n }\n\n const response = await fetch(`${this.config.apiUrl}/chat/send-ephemeral-message`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const responseBody = await response.text();\n throw new Error(`Failed to send ephemeral message: ${response.status} ${responseBody}`);\n }\n }\n\n // ===========================================================================\n // Reactions\n // ===========================================================================\n\n async addReaction(messageId: string, emoji: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/add-reaction`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n messageId,\n emoji,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to add reaction: ${response.status} ${body}`);\n }\n }\n\n async removeReaction(messageId: string, emoji: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/remove-reaction`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n messageId,\n emoji,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to remove reaction: ${response.status} ${body}`);\n }\n }\n\n // ===========================================================================\n // Read state & metadata\n // ===========================================================================\n\n async markRead(messageId?: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/mark-read`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n ...(messageId ? { messageId } : {}),\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to mark read: ${response.status} ${body}`);\n }\n }\n\n async updateTopic(topic: string): Promise<void> {\n return this.updateChannel({ topic });\n }\n\n async updateChannel(fields: {\n name?: string;\n description?: string;\n topic?: string;\n pictureUrl?: string;\n }): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/update-channel`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n ...fields,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to update channel: ${response.status} ${body}`);\n }\n }\n\n // ===========================================================================\n // Participants\n // ===========================================================================\n\n async addParticipant(userId: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/invite-to-channel`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n userId,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to add participant: ${response.status} ${body}`);\n }\n }\n\n async removeParticipant(userId: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/remove-participant`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n userId,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to remove participant: ${response.status} ${body}`);\n }\n }\n\n async leave(): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/leave-conversation`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to leave conversation: ${response.status} ${body}`);\n }\n }\n\n // ===========================================================================\n // Message history\n // ===========================================================================\n\n async getMessages(opts?: { limit?: number; before?: string }): Promise<Message[]> {\n const headers = await this.buildHeaders();\n const response = await fetch(`${this.config.apiUrl}/chat/get-messages`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n ...(opts?.limit ? { limit: opts.limit } : {}),\n ...(opts?.before ? { before: opts.before } : {}),\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get messages: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { messages?: Message[] };\n return data.messages ?? [];\n }\n\n async getThreadReplies(parentMessageId: string, opts?: { limit?: number; before?: string }): Promise<Message[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-thread-replies`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n parentMessageId,\n ...(opts?.limit ? { limit: opts.limit } : {}),\n ...(opts?.before ? { before: opts.before } : {}),\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get thread replies: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { messages?: Message[] };\n return data.messages ?? [];\n }\n\n // ===========================================================================\n // Event listeners \u2014 route through parent user stream\n // ===========================================================================\n\n /**\n * Register an event handler filtered to this conversation.\n * Events are received from the parent GigabuddyChat's user stream.\n * Returns an unsubscribe function.\n */\n on<T extends keyof ConversationEventMap>(event: T, handler: ConversationEventMap[T]): () => void {\n if (this.eventBus) {\n const unsub = this.eventBus.addConversationListener(\n this.conversationId,\n event,\n handler as (...args: unknown[]) => void,\n );\n this.unsubscribes.push(unsub);\n return unsub;\n }\n // No event bus \u2014 listener is a no-op\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }\n\n // ===========================================================================\n // SSE lifecycle \u2014 no-ops (stream managed by GigabuddyChat)\n // ===========================================================================\n\n /** @deprecated No-op \u2014 SSE is managed by GigabuddyChat.connect() */\n async connect(): Promise<void> {\n // No-op: user stream is managed at the GigabuddyChat level\n }\n\n /** @deprecated No-op \u2014 SSE is managed by GigabuddyChat.disconnect() */\n disconnect(): void {\n // Clean up any registered listeners\n for (const unsub of this.unsubscribes) {\n unsub();\n }\n this.unsubscribes = [];\n }\n}\n", "/**\n * SSE Client\n *\n * Uses fetch() + ReadableStream instead of native EventSource\n * to support Authorization headers. Handles reconnection with\n * exponential backoff.\n */\n\nimport type { ChannelEvent, ChannelEventType } from './types.js';\n\nexport type SSEEventHandler = (event: ChannelEvent) => void;\nexport type SSEConnectionHandler = () => void;\n\ninterface SSEClientConfig {\n url: string;\n getToken: () => Promise<string> | string;\n onEvent: SSEEventHandler;\n onConnected: SSEConnectionHandler;\n onDisconnected: SSEConnectionHandler;\n}\n\nconst MAX_RECONNECT_ATTEMPTS = 10;\nconst INITIAL_BACKOFF_MS = 1_000;\nconst MAX_BACKOFF_MS = 30_000;\n\nexport class SSEClient {\n private config: SSEClientConfig;\n private abortController: AbortController | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private reconnectAttempt = 0;\n private stopped = false;\n\n constructor(config: SSEClientConfig) {\n this.config = config;\n }\n\n async connect(): Promise<void> {\n this.stopped = false;\n this.reconnectAttempt = 0;\n await this.startStream();\n }\n\n disconnect(): void {\n this.stopped = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n }\n\n async updateToken(newToken: string): Promise<void> {\n // Store the new token getter for reconnections\n const originalGetToken = this.config.getToken;\n this.config.getToken = () => newToken;\n\n // Reconnect with new token\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n this.reconnectAttempt = 0;\n await this.startStream();\n }\n\n // Restore the dynamic getter for future reconnections\n this.config.getToken = originalGetToken;\n }\n\n private async startStream(): Promise<void> {\n if (this.stopped) return;\n\n try {\n const token = await this.config.getToken();\n this.abortController = new AbortController();\n\n const response = await fetch(this.config.url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'text/event-stream',\n },\n signal: this.abortController.signal,\n });\n\n if (!response.ok) {\n throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body');\n }\n\n this.reconnectAttempt = 0;\n // Read stream in background \u2014 don't await (readStream blocks until stream ends)\n this.readStream(response.body);\n } catch (error) {\n if (this.stopped) return;\n if (error instanceof DOMException && error.name === 'AbortError') return;\n\n this.config.onDisconnected();\n this.scheduleReconnect();\n }\n }\n\n private async readStream(body: ReadableStream<Uint8Array>): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete SSE messages (terminated by \\n\\n)\n const messages = buffer.split('\\n\\n');\n buffer = messages.pop() ?? '';\n\n for (const message of messages) {\n this.parseSSEMessage(message);\n }\n }\n } catch (error) {\n if (this.stopped) return;\n if (error instanceof DOMException && error.name === 'AbortError') return;\n } finally {\n reader.releaseLock();\n }\n\n // Stream ended \u2014 reconnect if not explicitly stopped\n if (!this.stopped) {\n this.config.onDisconnected();\n this.scheduleReconnect();\n }\n }\n\n private parseSSEMessage(message: string): void {\n // Skip heartbeat comments\n if (message.trim().startsWith(':')) return;\n\n let eventType = 'message';\n let data = '';\n\n for (const line of message.split('\\n')) {\n if (line.startsWith('event: ')) {\n eventType = line.slice(7).trim();\n } else if (line.startsWith('data: ')) {\n data = line.slice(6);\n } else if (line.startsWith('data:')) {\n data = line.slice(5);\n }\n }\n\n if (eventType === 'connected') {\n this.config.onConnected();\n return;\n }\n\n if (!data) return;\n\n try {\n const parsed = JSON.parse(data) as ChannelEvent;\n // Ensure type field matches event type\n if (!parsed.type) {\n parsed.type = eventType as ChannelEventType;\n }\n this.config.onEvent(parsed);\n } catch {\n // Ignore malformed events\n }\n }\n\n private scheduleReconnect(): void {\n if (this.stopped) return;\n if (this.reconnectAttempt >= MAX_RECONNECT_ATTEMPTS) return;\n\n const backoff = Math.min(INITIAL_BACKOFF_MS * Math.pow(2, this.reconnectAttempt), MAX_BACKOFF_MS);\n this.reconnectAttempt++;\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.startStream();\n }, backoff);\n }\n}\n", "/**\n * GigabuddyChat\n *\n * Main entry point for the Chat SDK. Manages a single user-level SSE\n * connection and routes events to conversation-level listeners.\n */\n\nimport { Conversation } from './Conversation.js';\nimport { SSEClient } from './SSEClient.js';\nimport type {\n ChatEventBus,\n ChatUser,\n ChannelEvent,\n ConversationInfo,\n ConversationType,\n ConversationVisibility,\n CreateGadgetInput,\n CreateStatefulGadgetInput,\n FileUploadResult,\n GadgetDetail,\n GadgetInfo,\n GadgetVersionDetail,\n GadgetVersionInfo,\n GigabuddyChatConfig,\n StatefulGadgetResult,\n StatefulGadgetSpec,\n UpdateGadgetInput,\n UserProfile,\n} from './types.js';\n\nexport class GigabuddyChat implements ChatEventBus {\n private config: GigabuddyChatConfig;\n private conversations = new Map<string, Conversation>();\n\n // User stream SSE\n private sseClient: SSEClient | null = null;\n private tokenRefreshTimer: ReturnType<typeof setInterval> | null = null;\n private _connected = false;\n\n // Global event listeners (across all conversations)\n private globalListeners = new Map<string, Set<(...args: unknown[]) => void>>();\n\n // Per-conversation event listeners\n private conversationListeners = new Map<string, Map<string, Set<(...args: unknown[]) => void>>>();\n\n // Derived URL parts\n private baseUrl: string;\n private projectId: string;\n\n constructor(config: GigabuddyChatConfig) {\n this.config = config;\n const url = new URL(config.apiUrl);\n this.baseUrl = url.origin;\n const pathParts = url.pathname.split('/').filter(Boolean);\n this.projectId = pathParts[pathParts.length - 1];\n }\n\n // ===========================================================================\n // User stream connection\n // ===========================================================================\n\n /**\n * Connect the user stream SSE. Call once after auth.\n */\n connect(): void {\n if (this.sseClient) return;\n\n this.sseClient = new SSEClient({\n url: `${this.baseUrl}/ext/stream/user?projectId=${encodeURIComponent(this.projectId)}`,\n getToken: this.config.getToken,\n onEvent: (event: ChannelEvent) => this.handleStreamEvent(event),\n onConnected: () => {\n this._connected = true;\n this.emitGlobal('connected');\n },\n onDisconnected: () => {\n this._connected = false;\n this.emitGlobal('disconnected');\n },\n });\n\n void this.sseClient.connect();\n\n // Refresh token every 50 minutes\n this.tokenRefreshTimer = setInterval(\n async () => {\n if (this.sseClient) {\n const newToken = await this.config.getToken();\n await this.sseClient.updateToken(newToken);\n }\n },\n 50 * 60 * 1_000,\n );\n }\n\n /**\n * Returns true if the user stream is connected.\n */\n isConnected(): boolean {\n return this._connected;\n }\n\n /**\n * Disconnect the user stream and clean up all listeners.\n */\n disconnect(): void {\n if (this.tokenRefreshTimer) {\n clearInterval(this.tokenRefreshTimer);\n this.tokenRefreshTimer = null;\n }\n if (this.sseClient) {\n this.sseClient.disconnect();\n this.sseClient = null;\n }\n this._connected = false;\n }\n\n // ===========================================================================\n // Global event listeners\n // ===========================================================================\n\n /**\n * Listen for events across all conversations.\n * Returns an unsubscribe function.\n */\n on(event: string, handler: (...args: unknown[]) => void): () => void {\n if (!this.globalListeners.has(event)) {\n this.globalListeners.set(event, new Set());\n }\n this.globalListeners.get(event)!.add(handler);\n return () => {\n this.globalListeners.get(event)?.delete(handler);\n };\n }\n\n /**\n * Remove a global event listener.\n */\n off(event: string, handler: (...args: unknown[]) => void): void {\n this.globalListeners.get(event)?.delete(handler);\n }\n\n // ===========================================================================\n // ChatEventBus: per-conversation listeners (used by Conversation)\n // ===========================================================================\n\n addConversationListener(conversationId: string, event: string, handler: (...args: unknown[]) => void): () => void {\n if (!this.conversationListeners.has(conversationId)) {\n this.conversationListeners.set(conversationId, new Map());\n }\n const convMap = this.conversationListeners.get(conversationId)!;\n if (!convMap.has(event)) {\n convMap.set(event, new Set());\n }\n convMap.get(event)!.add(handler);\n\n return () => {\n convMap.get(event)?.delete(handler);\n };\n }\n\n // ===========================================================================\n // Internal event routing\n // ===========================================================================\n\n private handleStreamEvent(event: ChannelEvent): void {\n const eventType = event.type;\n const conversationId = event.conversationId;\n // Dispatch to global listeners\n this.emitGlobal(eventType, event);\n\n // Dispatch to conversation-specific listeners\n if (conversationId) {\n const convMap = this.conversationListeners.get(conversationId);\n if (convMap) {\n const handlers = convMap.get(eventType);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(event);\n } catch {\n // Don't let listener errors break the stream\n }\n }\n }\n }\n }\n }\n\n private emitGlobal(event: string, ...args: unknown[]): void {\n const handlers = this.globalListeners.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(...args);\n } catch {\n // Don't let listener errors break the stream\n }\n }\n }\n }\n\n // ===========================================================================\n // API helpers\n // ===========================================================================\n\n private async buildHeaders(): Promise<Record<string, string>> {\n const token = await this.config.getToken();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n };\n if (this.config.userId) {\n headers['X-Chat-User-Id'] = this.config.userId;\n }\n return headers;\n }\n\n private extractConversationId(data: Record<string, unknown>): string {\n let conversationId = data['conversationId'] as string | undefined;\n if (!conversationId && data['conversation']) {\n let conv = data['conversation'];\n if (typeof conv === 'string') {\n try {\n conv = JSON.parse(conv);\n } catch {\n // not JSON\n }\n }\n if (conv && typeof conv === 'object' && 'id' in conv) {\n conversationId = (conv as { id: string }).id;\n }\n }\n if (!conversationId) {\n throw new Error('No conversationId returned from API');\n }\n return conversationId;\n }\n\n private trackConversation(conversationId: string): Conversation {\n const existing = this.conversations.get(conversationId);\n if (existing) return existing;\n const conversation = new Conversation(conversationId, this.config, this);\n this.conversations.set(conversationId, conversation);\n return conversation;\n }\n\n /**\n * Get or create a Conversation handle for a known conversationId.\n * Does not make any API calls \u2014 just returns a local wrapper.\n */\n getConversation(conversationId: string): Conversation {\n return this.trackConversation(conversationId);\n }\n\n // ===========================================================================\n // Conversation creation (v1 compat)\n // ===========================================================================\n\n async openConversation(\n options: {\n topic?: string;\n buddyId?: string;\n buddyProjectId?: string;\n userName?: string;\n } = {},\n ): Promise<Conversation> {\n const headers = await this.buildHeaders();\n\n const createResponse = await fetch(`${this.config.apiUrl}/chat/create-conversation`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n ...(options.topic ? { topic: options.topic } : {}),\n ...(options.userName ? { userName: options.userName } : {}),\n }),\n });\n\n if (!createResponse.ok) {\n const body = await createResponse.text();\n throw new Error(`Failed to create conversation: ${createResponse.status} ${body}`);\n }\n\n const createData = (await createResponse.json()) as Record<string, unknown>;\n const conversationId = this.extractConversationId(createData);\n\n if (options.buddyId) {\n const attachResponse = await fetch(`${this.config.apiUrl}/chat/attach-buddy`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId,\n buddyId: options.buddyId,\n ...(options.buddyProjectId ? { buddyProjectId: options.buddyProjectId } : {}),\n }),\n });\n\n if (!attachResponse.ok) {\n const body = await attachResponse.text();\n throw new Error(`Failed to attach buddy: ${attachResponse.status} ${body}`);\n }\n }\n\n return this.trackConversation(conversationId);\n }\n\n // ===========================================================================\n // v2: Channel management\n // ===========================================================================\n\n async createChannel(opts: {\n name: string;\n visibility?: ConversationVisibility;\n description?: string;\n topic?: string;\n }): Promise<Conversation> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/create-channel`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to create channel: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const conversationId = this.extractConversationId(data);\n return this.trackConversation(conversationId);\n }\n\n async joinChannel(conversationId: string): Promise<Conversation> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/join-channel`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ conversationId }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to join channel: ${response.status} ${body}`);\n }\n\n return this.trackConversation(conversationId);\n }\n\n async listChannels(opts?: { visibility?: ConversationVisibility; search?: string }): Promise<ConversationInfo[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/list-channels`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts ?? {}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to list channels: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { conversations?: ConversationInfo[] };\n return data.conversations ?? [];\n }\n\n // ===========================================================================\n // v2: DMs\n // ===========================================================================\n\n async openDM(userId: string): Promise<Conversation> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/create-dm`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ participantId: userId }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to open DM: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const conversationId = this.extractConversationId(data);\n return this.trackConversation(conversationId);\n }\n\n async openGroupDM(userIds: string[]): Promise<Conversation> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/create-group-dm`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ participantIds: userIds }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to open group DM: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const conversationId = this.extractConversationId(data);\n return this.trackConversation(conversationId);\n }\n\n // ===========================================================================\n // v2: List conversations (all types)\n // ===========================================================================\n\n async listConversations(opts?: {\n type?: ConversationType;\n status?: string;\n visibility?: ConversationVisibility;\n limit?: number;\n offset?: number;\n }): Promise<{ conversations: ConversationInfo[]; myContextInstanceId?: string }> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/list-conversations`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts ?? {}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to list conversations: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { conversations?: ConversationInfo[]; myContextInstanceId?: string };\n return { conversations: data.conversations ?? [], myContextInstanceId: data.myContextInstanceId };\n }\n\n // ===========================================================================\n // User search\n // ===========================================================================\n\n async searchUsers(opts?: { search?: string; limit?: number }): Promise<ChatUser[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/search-users`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts ?? {}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to search users: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { users?: ChatUser[] };\n return data.users ?? [];\n }\n\n // ===========================================================================\n // User profile\n // ===========================================================================\n\n async getProfile(): Promise<UserProfile & { contextInstanceId?: string }> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-profile`, {\n method: 'POST',\n headers,\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get profile: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { profile?: UserProfile; contextInstanceId?: string };\n return { ...(data.profile ?? {}), contextInstanceId: data.contextInstanceId };\n }\n\n async getProfiles(contextInstanceIds: string[]): Promise<Record<string, UserProfile>> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-profiles`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ contextInstanceIds }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get profiles: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { profiles?: Record<string, UserProfile> };\n return data.profiles ?? {};\n }\n\n async updateProfile(profile: {\n name?: string;\n avatarUrl?: string;\n handle?: string;\n notificationPreference?: 'all' | 'mentions' | 'nothing';\n }): Promise<UserProfile> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/update-profile`, {\n method: 'POST',\n headers,\n body: JSON.stringify(profile),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to update profile: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { profile?: UserProfile };\n return data.profile ?? {};\n }\n\n // ===========================================================================\n // Gadget management\n // ===========================================================================\n\n async listGadgets(): Promise<GadgetInfo[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/list-gadgets`, {\n method: 'POST',\n headers,\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to list gadgets: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { entities?: GadgetInfo[] };\n return data.entities ?? [];\n }\n\n async getGadget(gadgetId: string): Promise<GadgetDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetDetail;\n }\n\n async createGadget(input: CreateGadgetInput): Promise<GadgetDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/create-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to create gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetDetail;\n }\n\n async updateGadget(input: UpdateGadgetInput): Promise<GadgetDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/update-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to update gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetDetail;\n }\n\n async deleteGadget(gadgetId: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/delete-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to delete gadget: ${response.status} ${body}`);\n }\n }\n\n async duplicateGadget(gadgetId: string, newName?: string): Promise<GadgetDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/duplicate-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId, newName }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to duplicate gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetDetail;\n }\n\n async getGadgetVersions(gadgetId: string): Promise<GadgetVersionInfo[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-gadget-versions`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get gadget versions: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { versions?: GadgetVersionInfo[] };\n return data.versions ?? [];\n }\n\n async getGadgetVersion(gadgetId: string, version: number): Promise<GadgetVersionDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-gadget-version`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId, version }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get gadget version: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetVersionDetail;\n }\n\n async revertGadgetVersion(gadgetId: string, version: number): Promise<GadgetDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/revert-gadget-version`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId, version }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to revert gadget version: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetDetail;\n }\n\n async refineGadgetCode(\n gadgetId: string,\n feedback: string,\n ): Promise<{ componentCode: string; reducerCode?: string; commitMessage: string; changeType?: string }> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/refine-gadget-code`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId, feedback }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to refine gadget code: ${response.status} ${body}`);\n }\n\n return (await response.json()) as {\n componentCode: string;\n reducerCode?: string;\n commitMessage: string;\n changeType?: string;\n };\n }\n\n async generateStatefulGadget(intent: string, currentSpec?: Partial<StatefulGadgetSpec>): Promise<StatefulGadgetSpec> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/generate-stateful-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ intent, currentSpec }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to generate stateful gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as StatefulGadgetSpec;\n }\n\n async createStatefulGadget(input: CreateStatefulGadgetInput): Promise<StatefulGadgetResult> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/create-stateful-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to create stateful gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as StatefulGadgetResult;\n }\n\n // ===========================================================================\n // File uploads\n // ===========================================================================\n\n /**\n * Upload a file for use in chat messages.\n * Returns metadata that can be passed as `FileContent` to `conversation.sendMessage()`.\n */\n async uploadFile(conversationId: string, file: Blob, filename?: string): Promise<FileUploadResult> {\n const token = await this.config.getToken();\n const formData = new FormData();\n formData.append('file', file, filename);\n formData.append('conversationId', conversationId);\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n if (this.config.userId) {\n headers['X-Chat-User-Id'] = this.config.userId;\n }\n\n const response = await fetch(`${this.config.apiUrl}/chat/upload-file`, {\n method: 'POST',\n headers,\n body: formData,\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to upload file: ${response.status} ${body}`);\n }\n\n return (await response.json()) as FileUploadResult;\n }\n\n // ===========================================================================\n // Push notifications\n // ===========================================================================\n\n /**\n * Get the VAPID public key for subscribing to push notifications.\n * Returns null if push is not configured on the server.\n */\n async getVapidPublicKey(): Promise<string | null> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-vapid-key`, {\n method: 'POST',\n headers,\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n if (response.status === 503) return null;\n const body = await response.text();\n throw new Error(`Failed to get VAPID key: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { vapidPublicKey?: string };\n return data.vapidPublicKey ?? null;\n }\n\n /**\n * Register a push subscription for the current user.\n * Pass the PushSubscription from the browser's Push API.\n */\n async registerPushSubscription(subscription: PushSubscriptionJSON): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/register-push-subscription`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ subscription }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to register push subscription: ${response.status} ${body}`);\n }\n }\n\n /**\n * Unregister a push subscription by endpoint URL.\n */\n async unregisterPushSubscription(endpoint: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/unregister-push-subscription`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ endpoint }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to unregister push subscription: ${response.status} ${body}`);\n }\n }\n\n // ===========================================================================\n // Unread summary\n // ===========================================================================\n\n /**\n * Get unread message counts across all conversations for the current user.\n */\n async getUnreadSummary(): Promise<{ totalUnread: number; totalMentions: number }> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/unread-summary`, {\n method: 'POST',\n headers,\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get unread summary: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { totalUnread?: number; totalMentions?: number };\n return { totalUnread: data.totalUnread ?? 0, totalMentions: data.totalMentions ?? 0 };\n }\n\n // ===========================================================================\n // Lifecycle\n // ===========================================================================\n\n closeConversation(conversationId: string): void {\n const conversation = this.conversations.get(conversationId);\n if (conversation) {\n conversation.disconnect();\n this.conversations.delete(conversationId);\n }\n // Clean up conversation-specific listeners\n this.conversationListeners.delete(conversationId);\n }\n\n destroy(): void {\n this.disconnect();\n for (const [id] of this.conversations) {\n this.conversations.delete(id);\n }\n this.conversationListeners.clear();\n this.globalListeners.clear();\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Conversation\n *\n * Represents an active conversation. Events are received via the\n * parent GigabuddyChat's user stream \u2014 filtered by conversationId.\n * connect()/disconnect() are no-ops (kept for backward compat).\n */\n\nimport type {\n ChatEventBus,\n ChannelEvent,\n ConversationEventMap,\n GigabuddyChatConfig,\n Message,\n MessageContent,\n} from './types.js';\n\nexport class Conversation {\n readonly conversationId: string;\n private config: GigabuddyChatConfig;\n private eventBus: ChatEventBus | null;\n private unsubscribes: (() => void)[] = [];\n\n constructor(conversationId: string, config: GigabuddyChatConfig, eventBus?: ChatEventBus) {\n this.conversationId = conversationId;\n this.config = config;\n this.eventBus = eventBus ?? null;\n }\n\n private async buildHeaders(): Promise<Record<string, string>> {\n const token = await this.config.getToken();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n };\n if (this.config.userId) {\n headers['X-Chat-User-Id'] = this.config.userId;\n }\n return headers;\n }\n\n // ===========================================================================\n // Messages\n // ===========================================================================\n\n async sendMessage(content: string | MessageContent): Promise<void> {\n const headers = await this.buildHeaders();\n\n const body: Record<string, unknown> = {\n conversationId: this.conversationId,\n };\n\n if (typeof content === 'string') {\n body['text'] = content;\n } else {\n body['content'] = content;\n }\n\n const response = await fetch(`${this.config.apiUrl}/chat/send-message`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const responseBody = await response.text();\n throw new Error(`Failed to send message: ${response.status} ${responseBody}`);\n }\n }\n\n async replyTo(messageId: string, content: string | MessageContent): Promise<void> {\n const headers = await this.buildHeaders();\n\n const body: Record<string, unknown> = {\n conversationId: this.conversationId,\n parentMessageId: messageId,\n };\n\n if (typeof content === 'string') {\n body['text'] = content;\n } else {\n body['content'] = content;\n }\n\n const response = await fetch(`${this.config.apiUrl}/chat/reply-to-message`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const responseBody = await response.text();\n throw new Error(`Failed to reply to message: ${response.status} ${responseBody}`);\n }\n }\n\n async editMessage(messageId: string, content: string | MessageContent): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/edit-message`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n messageId,\n content,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to edit message: ${response.status} ${body}`);\n }\n }\n\n async deleteMessage(messageId: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/delete-message`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n messageId,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to delete message: ${response.status} ${body}`);\n }\n }\n\n async sendEphemeralMessage(targetUserId: string, content: string | MessageContent): Promise<void> {\n const headers = await this.buildHeaders();\n\n const body: Record<string, unknown> = {\n conversationId: this.conversationId,\n targetUserId,\n };\n\n if (typeof content === 'string') {\n body['text'] = content;\n } else {\n body['content'] = content;\n }\n\n const response = await fetch(`${this.config.apiUrl}/chat/send-ephemeral-message`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const responseBody = await response.text();\n throw new Error(`Failed to send ephemeral message: ${response.status} ${responseBody}`);\n }\n }\n\n // ===========================================================================\n // Reactions\n // ===========================================================================\n\n async addReaction(messageId: string, emoji: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/add-reaction`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n messageId,\n emoji,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to add reaction: ${response.status} ${body}`);\n }\n }\n\n async removeReaction(messageId: string, emoji: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/remove-reaction`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n messageId,\n emoji,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to remove reaction: ${response.status} ${body}`);\n }\n }\n\n // ===========================================================================\n // Read state & metadata\n // ===========================================================================\n\n async markRead(messageId?: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/mark-read`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n ...(messageId ? { messageId } : {}),\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to mark read: ${response.status} ${body}`);\n }\n }\n\n async updateTopic(topic: string): Promise<void> {\n return this.updateChannel({ topic });\n }\n\n async updateChannel(fields: {\n name?: string;\n description?: string;\n topic?: string;\n pictureUrl?: string;\n }): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/update-channel`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n ...fields,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to update channel: ${response.status} ${body}`);\n }\n }\n\n // ===========================================================================\n // Participants\n // ===========================================================================\n\n async addParticipant(userId: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/invite-to-channel`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n userId,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to add participant: ${response.status} ${body}`);\n }\n }\n\n async removeParticipant(userId: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/remove-participant`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n userId,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to remove participant: ${response.status} ${body}`);\n }\n }\n\n async leave(): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/leave-conversation`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to leave conversation: ${response.status} ${body}`);\n }\n }\n\n // ===========================================================================\n // Message history\n // ===========================================================================\n\n async getMessages(opts?: { limit?: number; before?: string }): Promise<Message[]> {\n const headers = await this.buildHeaders();\n const response = await fetch(`${this.config.apiUrl}/chat/get-messages`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n ...(opts?.limit ? { limit: opts.limit } : {}),\n ...(opts?.before ? { before: opts.before } : {}),\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get messages: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { messages?: Message[] };\n return data.messages ?? [];\n }\n\n async getThreadReplies(parentMessageId: string, opts?: { limit?: number; before?: string }): Promise<Message[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-thread-replies`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId: this.conversationId,\n parentMessageId,\n ...(opts?.limit ? { limit: opts.limit } : {}),\n ...(opts?.before ? { before: opts.before } : {}),\n }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get thread replies: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { messages?: Message[] };\n return data.messages ?? [];\n }\n\n // ===========================================================================\n // Event listeners \u2014 route through parent user stream\n // ===========================================================================\n\n /**\n * Register an event handler filtered to this conversation.\n * Events are received from the parent GigabuddyChat's user stream.\n * Returns an unsubscribe function.\n */\n on<T extends keyof ConversationEventMap>(event: T, handler: ConversationEventMap[T]): () => void {\n if (this.eventBus) {\n const unsub = this.eventBus.addConversationListener(\n this.conversationId,\n event,\n handler as (...args: unknown[]) => void,\n );\n this.unsubscribes.push(unsub);\n return unsub;\n }\n // No event bus \u2014 listener is a no-op\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n return () => {};\n }\n\n // ===========================================================================\n // SSE lifecycle \u2014 no-ops (stream managed by GigabuddyChat)\n // ===========================================================================\n\n /** @deprecated No-op \u2014 SSE is managed by GigabuddyChat.connect() */\n async connect(): Promise<void> {\n // No-op: user stream is managed at the GigabuddyChat level\n }\n\n /** @deprecated No-op \u2014 SSE is managed by GigabuddyChat.disconnect() */\n disconnect(): void {\n // Clean up any registered listeners\n for (const unsub of this.unsubscribes) {\n unsub();\n }\n this.unsubscribes = [];\n }\n}\n", "/**\n * SSE Client\n *\n * Uses fetch() + ReadableStream instead of native EventSource\n * to support Authorization headers. Handles reconnection with\n * exponential backoff.\n */\n\nimport type { ChannelEvent, ChannelEventType } from './types.js';\n\nexport type SSEEventHandler = (event: ChannelEvent) => void;\nexport type SSEConnectionHandler = () => void;\n\ninterface SSEClientConfig {\n url: string;\n getToken: () => Promise<string> | string;\n onEvent: SSEEventHandler;\n onConnected: SSEConnectionHandler;\n onDisconnected: SSEConnectionHandler;\n}\n\nconst MAX_RECONNECT_ATTEMPTS = 10;\nconst INITIAL_BACKOFF_MS = 1_000;\nconst MAX_BACKOFF_MS = 30_000;\n\nexport class SSEClient {\n private config: SSEClientConfig;\n private abortController: AbortController | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private reconnectAttempt = 0;\n private stopped = false;\n\n constructor(config: SSEClientConfig) {\n this.config = config;\n }\n\n async connect(): Promise<void> {\n this.stopped = false;\n this.reconnectAttempt = 0;\n await this.startStream();\n }\n\n disconnect(): void {\n this.stopped = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n }\n\n async updateToken(newToken: string): Promise<void> {\n // Store the new token getter for reconnections\n const originalGetToken = this.config.getToken;\n this.config.getToken = () => newToken;\n\n // Reconnect with new token\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n this.reconnectAttempt = 0;\n await this.startStream();\n }\n\n // Restore the dynamic getter for future reconnections\n this.config.getToken = originalGetToken;\n }\n\n private async startStream(): Promise<void> {\n if (this.stopped) return;\n\n try {\n const token = await this.config.getToken();\n this.abortController = new AbortController();\n\n const response = await fetch(this.config.url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'text/event-stream',\n },\n signal: this.abortController.signal,\n });\n\n if (!response.ok) {\n throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body');\n }\n\n this.reconnectAttempt = 0;\n // Read stream in background \u2014 don't await (readStream blocks until stream ends)\n this.readStream(response.body);\n } catch (error) {\n if (this.stopped) return;\n if (error instanceof DOMException && error.name === 'AbortError') return;\n\n this.config.onDisconnected();\n this.scheduleReconnect();\n }\n }\n\n private async readStream(body: ReadableStream<Uint8Array>): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete SSE messages (terminated by \\n\\n)\n const messages = buffer.split('\\n\\n');\n buffer = messages.pop() ?? '';\n\n for (const message of messages) {\n this.parseSSEMessage(message);\n }\n }\n } catch (error) {\n if (this.stopped) return;\n if (error instanceof DOMException && error.name === 'AbortError') return;\n } finally {\n reader.releaseLock();\n }\n\n // Stream ended \u2014 reconnect if not explicitly stopped\n if (!this.stopped) {\n this.config.onDisconnected();\n this.scheduleReconnect();\n }\n }\n\n private parseSSEMessage(message: string): void {\n // Skip heartbeat comments\n if (message.trim().startsWith(':')) return;\n\n let eventType = 'message';\n let data = '';\n\n for (const line of message.split('\\n')) {\n if (line.startsWith('event: ')) {\n eventType = line.slice(7).trim();\n } else if (line.startsWith('data: ')) {\n data = line.slice(6);\n } else if (line.startsWith('data:')) {\n data = line.slice(5);\n }\n }\n\n if (eventType === 'connected') {\n this.config.onConnected();\n return;\n }\n\n if (!data) return;\n\n try {\n const parsed = JSON.parse(data) as ChannelEvent;\n // Ensure type field matches event type\n if (!parsed.type) {\n parsed.type = eventType as ChannelEventType;\n }\n this.config.onEvent(parsed);\n } catch {\n // Ignore malformed events\n }\n }\n\n private scheduleReconnect(): void {\n if (this.stopped) return;\n if (this.reconnectAttempt >= MAX_RECONNECT_ATTEMPTS) return;\n\n const backoff = Math.min(INITIAL_BACKOFF_MS * Math.pow(2, this.reconnectAttempt), MAX_BACKOFF_MS);\n this.reconnectAttempt++;\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.startStream();\n }, backoff);\n }\n}\n", "/**\n * GigabuddyChat\n *\n * Main entry point for the Chat SDK. Manages a single user-level SSE\n * connection and routes events to conversation-level listeners.\n */\n\nimport { Conversation } from './Conversation.js';\nimport { SSEClient } from './SSEClient.js';\nimport type {\n ChatEventBus,\n ChatUser,\n ChannelEvent,\n ConversationInfo,\n ConversationType,\n ConversationVisibility,\n CreateGadgetInput,\n CreateStatefulGadgetInput,\n FileUploadResult,\n GadgetDetail,\n GadgetInfo,\n GadgetVersionDetail,\n GadgetVersionInfo,\n GigabuddyChatConfig,\n StatefulGadgetResult,\n StatefulGadgetSpec,\n UpdateGadgetInput,\n UserProfile,\n UserStat,\n} from './types.js';\n\nexport class GigabuddyChat implements ChatEventBus {\n private config: GigabuddyChatConfig;\n private conversations = new Map<string, Conversation>();\n\n // User stream SSE\n private sseClient: SSEClient | null = null;\n private tokenRefreshTimer: ReturnType<typeof setInterval> | null = null;\n private _connected = false;\n\n // Global event listeners (across all conversations)\n private globalListeners = new Map<string, Set<(...args: unknown[]) => void>>();\n\n // Per-conversation event listeners\n private conversationListeners = new Map<string, Map<string, Set<(...args: unknown[]) => void>>>();\n\n // Derived URL parts\n private baseUrl: string;\n private projectId: string;\n\n constructor(config: GigabuddyChatConfig) {\n this.config = config;\n const url = new URL(config.apiUrl);\n this.baseUrl = url.origin;\n const pathParts = url.pathname.split('/').filter(Boolean);\n this.projectId = pathParts[pathParts.length - 1];\n }\n\n // ===========================================================================\n // User stream connection\n // ===========================================================================\n\n /**\n * Connect the user stream SSE. Call once after auth.\n */\n connect(): void {\n if (this.sseClient) return;\n\n this.sseClient = new SSEClient({\n url: `${this.baseUrl}/ext/stream/user?projectId=${encodeURIComponent(this.projectId)}`,\n getToken: this.config.getToken,\n onEvent: (event: ChannelEvent) => this.handleStreamEvent(event),\n onConnected: () => {\n this._connected = true;\n this.emitGlobal('connected');\n },\n onDisconnected: () => {\n this._connected = false;\n this.emitGlobal('disconnected');\n },\n });\n\n void this.sseClient.connect();\n\n // Refresh token every 50 minutes\n this.tokenRefreshTimer = setInterval(\n async () => {\n if (this.sseClient) {\n const newToken = await this.config.getToken();\n await this.sseClient.updateToken(newToken);\n }\n },\n 50 * 60 * 1_000,\n );\n }\n\n /**\n * Returns true if the user stream is connected.\n */\n isConnected(): boolean {\n return this._connected;\n }\n\n /**\n * Disconnect the user stream and clean up all listeners.\n */\n disconnect(): void {\n if (this.tokenRefreshTimer) {\n clearInterval(this.tokenRefreshTimer);\n this.tokenRefreshTimer = null;\n }\n if (this.sseClient) {\n this.sseClient.disconnect();\n this.sseClient = null;\n }\n this._connected = false;\n }\n\n // ===========================================================================\n // Global event listeners\n // ===========================================================================\n\n /**\n * Listen for events across all conversations.\n * Returns an unsubscribe function.\n */\n on(event: string, handler: (...args: unknown[]) => void): () => void {\n if (!this.globalListeners.has(event)) {\n this.globalListeners.set(event, new Set());\n }\n this.globalListeners.get(event)!.add(handler);\n return () => {\n this.globalListeners.get(event)?.delete(handler);\n };\n }\n\n /**\n * Remove a global event listener.\n */\n off(event: string, handler: (...args: unknown[]) => void): void {\n this.globalListeners.get(event)?.delete(handler);\n }\n\n // ===========================================================================\n // ChatEventBus: per-conversation listeners (used by Conversation)\n // ===========================================================================\n\n addConversationListener(conversationId: string, event: string, handler: (...args: unknown[]) => void): () => void {\n if (!this.conversationListeners.has(conversationId)) {\n this.conversationListeners.set(conversationId, new Map());\n }\n const convMap = this.conversationListeners.get(conversationId)!;\n if (!convMap.has(event)) {\n convMap.set(event, new Set());\n }\n convMap.get(event)!.add(handler);\n\n return () => {\n convMap.get(event)?.delete(handler);\n };\n }\n\n // ===========================================================================\n // Internal event routing\n // ===========================================================================\n\n private handleStreamEvent(event: ChannelEvent): void {\n const eventType = event.type;\n const conversationId = event.conversationId;\n // Dispatch to global listeners\n this.emitGlobal(eventType, event);\n\n // Dispatch to conversation-specific listeners\n if (conversationId) {\n const convMap = this.conversationListeners.get(conversationId);\n if (convMap) {\n const handlers = convMap.get(eventType);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(event);\n } catch {\n // Don't let listener errors break the stream\n }\n }\n }\n }\n }\n }\n\n private emitGlobal(event: string, ...args: unknown[]): void {\n const handlers = this.globalListeners.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(...args);\n } catch {\n // Don't let listener errors break the stream\n }\n }\n }\n }\n\n // ===========================================================================\n // API helpers\n // ===========================================================================\n\n private async buildHeaders(): Promise<Record<string, string>> {\n const token = await this.config.getToken();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n };\n if (this.config.userId) {\n headers['X-Chat-User-Id'] = this.config.userId;\n }\n return headers;\n }\n\n private extractConversationId(data: Record<string, unknown>): string {\n let conversationId = data['conversationId'] as string | undefined;\n if (!conversationId && data['conversation']) {\n let conv = data['conversation'];\n if (typeof conv === 'string') {\n try {\n conv = JSON.parse(conv);\n } catch {\n // not JSON\n }\n }\n if (conv && typeof conv === 'object' && 'id' in conv) {\n conversationId = (conv as { id: string }).id;\n }\n }\n if (!conversationId) {\n throw new Error('No conversationId returned from API');\n }\n return conversationId;\n }\n\n private trackConversation(conversationId: string): Conversation {\n const existing = this.conversations.get(conversationId);\n if (existing) return existing;\n const conversation = new Conversation(conversationId, this.config, this);\n this.conversations.set(conversationId, conversation);\n return conversation;\n }\n\n /**\n * Get or create a Conversation handle for a known conversationId.\n * Does not make any API calls \u2014 just returns a local wrapper.\n */\n getConversation(conversationId: string): Conversation {\n return this.trackConversation(conversationId);\n }\n\n // ===========================================================================\n // Conversation creation (v1 compat)\n // ===========================================================================\n\n async openConversation(\n options: {\n topic?: string;\n buddyId?: string;\n buddyProjectId?: string;\n userName?: string;\n } = {},\n ): Promise<Conversation> {\n const headers = await this.buildHeaders();\n\n const createResponse = await fetch(`${this.config.apiUrl}/chat/create-conversation`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n ...(options.topic ? { topic: options.topic } : {}),\n ...(options.userName ? { userName: options.userName } : {}),\n }),\n });\n\n if (!createResponse.ok) {\n const body = await createResponse.text();\n throw new Error(`Failed to create conversation: ${createResponse.status} ${body}`);\n }\n\n const createData = (await createResponse.json()) as Record<string, unknown>;\n const conversationId = this.extractConversationId(createData);\n\n if (options.buddyId) {\n const attachResponse = await fetch(`${this.config.apiUrl}/chat/attach-buddy`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n conversationId,\n buddyId: options.buddyId,\n ...(options.buddyProjectId ? { buddyProjectId: options.buddyProjectId } : {}),\n }),\n });\n\n if (!attachResponse.ok) {\n const body = await attachResponse.text();\n throw new Error(`Failed to attach buddy: ${attachResponse.status} ${body}`);\n }\n }\n\n return this.trackConversation(conversationId);\n }\n\n // ===========================================================================\n // v2: Channel management\n // ===========================================================================\n\n async createChannel(opts: {\n name: string;\n visibility?: ConversationVisibility;\n description?: string;\n topic?: string;\n }): Promise<Conversation> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/create-channel`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to create channel: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const conversationId = this.extractConversationId(data);\n return this.trackConversation(conversationId);\n }\n\n async joinChannel(conversationId: string): Promise<Conversation> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/join-channel`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ conversationId }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to join channel: ${response.status} ${body}`);\n }\n\n return this.trackConversation(conversationId);\n }\n\n async listChannels(opts?: { visibility?: ConversationVisibility; search?: string }): Promise<ConversationInfo[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/list-channels`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts ?? {}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to list channels: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { conversations?: ConversationInfo[] };\n return data.conversations ?? [];\n }\n\n // ===========================================================================\n // v2: DMs\n // ===========================================================================\n\n async openDM(userId: string): Promise<Conversation> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/create-dm`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ participantId: userId }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to open DM: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const conversationId = this.extractConversationId(data);\n return this.trackConversation(conversationId);\n }\n\n async openGroupDM(userIds: string[]): Promise<Conversation> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/create-group-dm`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ participantIds: userIds }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to open group DM: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as Record<string, unknown>;\n const conversationId = this.extractConversationId(data);\n return this.trackConversation(conversationId);\n }\n\n // ===========================================================================\n // v2: List conversations (all types)\n // ===========================================================================\n\n async listConversations(opts?: {\n type?: ConversationType;\n status?: string;\n visibility?: ConversationVisibility;\n limit?: number;\n offset?: number;\n }): Promise<{ conversations: ConversationInfo[]; myContextInstanceId?: string }> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/list-conversations`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts ?? {}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to list conversations: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { conversations?: ConversationInfo[]; myContextInstanceId?: string };\n return { conversations: data.conversations ?? [], myContextInstanceId: data.myContextInstanceId };\n }\n\n // ===========================================================================\n // User search\n // ===========================================================================\n\n async searchUsers(opts?: { search?: string; limit?: number }): Promise<ChatUser[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/search-users`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts ?? {}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to search users: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { users?: ChatUser[] };\n return data.users ?? [];\n }\n\n // ===========================================================================\n // User profile\n // ===========================================================================\n\n async getProfile(): Promise<UserProfile & { contextInstanceId?: string }> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-profile`, {\n method: 'POST',\n headers,\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get profile: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { profile?: UserProfile; contextInstanceId?: string };\n return { ...(data.profile ?? {}), contextInstanceId: data.contextInstanceId };\n }\n\n async getProfiles(contextInstanceIds: string[]): Promise<Record<string, UserProfile>> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-profiles`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ contextInstanceIds }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get profiles: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { profiles?: Record<string, UserProfile> };\n return data.profiles ?? {};\n }\n\n async updateProfile(profile: {\n name?: string;\n avatarUrl?: string;\n handle?: string;\n notificationPreference?: 'all' | 'mentions' | 'nothing';\n }): Promise<UserProfile> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/update-profile`, {\n method: 'POST',\n headers,\n body: JSON.stringify(profile),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to update profile: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { profile?: UserProfile };\n return data.profile ?? {};\n }\n\n // ===========================================================================\n // Gadget management\n // ===========================================================================\n\n async listGadgets(): Promise<GadgetInfo[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/list-gadgets`, {\n method: 'POST',\n headers,\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to list gadgets: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { entities?: GadgetInfo[] };\n return data.entities ?? [];\n }\n\n async getGadget(gadgetId: string): Promise<GadgetDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetDetail;\n }\n\n async createGadget(input: CreateGadgetInput): Promise<GadgetDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/create-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to create gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetDetail;\n }\n\n async updateGadget(input: UpdateGadgetInput): Promise<GadgetDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/update-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to update gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetDetail;\n }\n\n async deleteGadget(gadgetId: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/delete-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to delete gadget: ${response.status} ${body}`);\n }\n }\n\n async duplicateGadget(gadgetId: string, newName?: string): Promise<GadgetDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/duplicate-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId, newName }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to duplicate gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetDetail;\n }\n\n async getGadgetVersions(gadgetId: string): Promise<GadgetVersionInfo[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-gadget-versions`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get gadget versions: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { versions?: GadgetVersionInfo[] };\n return data.versions ?? [];\n }\n\n async getGadgetVersion(gadgetId: string, version: number): Promise<GadgetVersionDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-gadget-version`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId, version }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get gadget version: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetVersionDetail;\n }\n\n async revertGadgetVersion(gadgetId: string, version: number): Promise<GadgetDetail> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/revert-gadget-version`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId, version }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to revert gadget version: ${response.status} ${body}`);\n }\n\n return (await response.json()) as GadgetDetail;\n }\n\n async refineGadgetCode(\n gadgetId: string,\n feedback: string,\n ): Promise<{ componentCode: string; reducerCode?: string; commitMessage: string; changeType?: string }> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/refine-gadget-code`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ gadgetId, feedback }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to refine gadget code: ${response.status} ${body}`);\n }\n\n return (await response.json()) as {\n componentCode: string;\n reducerCode?: string;\n commitMessage: string;\n changeType?: string;\n };\n }\n\n async generateStatefulGadget(intent: string, currentSpec?: Partial<StatefulGadgetSpec>): Promise<StatefulGadgetSpec> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/generate-stateful-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ intent, currentSpec }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to generate stateful gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as StatefulGadgetSpec;\n }\n\n async createStatefulGadget(input: CreateStatefulGadgetInput): Promise<StatefulGadgetResult> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/create-stateful-gadget`, {\n method: 'POST',\n headers,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to create stateful gadget: ${response.status} ${body}`);\n }\n\n return (await response.json()) as StatefulGadgetResult;\n }\n\n // ===========================================================================\n // File uploads\n // ===========================================================================\n\n /**\n * Upload a file for use in chat messages.\n * Returns metadata that can be passed as `FileContent` to `conversation.sendMessage()`.\n */\n async uploadFile(conversationId: string, file: Blob, filename?: string): Promise<FileUploadResult> {\n const token = await this.config.getToken();\n const formData = new FormData();\n formData.append('file', file, filename);\n formData.append('conversationId', conversationId);\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n if (this.config.userId) {\n headers['X-Chat-User-Id'] = this.config.userId;\n }\n\n const response = await fetch(`${this.config.apiUrl}/chat/upload-file`, {\n method: 'POST',\n headers,\n body: formData,\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to upload file: ${response.status} ${body}`);\n }\n\n return (await response.json()) as FileUploadResult;\n }\n\n // ===========================================================================\n // Push notifications\n // ===========================================================================\n\n /**\n * Get the VAPID public key for subscribing to push notifications.\n * Returns null if push is not configured on the server.\n */\n async getVapidPublicKey(): Promise<string | null> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/get-vapid-key`, {\n method: 'POST',\n headers,\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n if (response.status === 503) return null;\n const body = await response.text();\n throw new Error(`Failed to get VAPID key: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { vapidPublicKey?: string };\n return data.vapidPublicKey ?? null;\n }\n\n /**\n * Register a push subscription for the current user.\n * Pass the PushSubscription from the browser's Push API.\n */\n async registerPushSubscription(subscription: PushSubscriptionJSON): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/register-push-subscription`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ subscription }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to register push subscription: ${response.status} ${body}`);\n }\n }\n\n /**\n * Unregister a push subscription by endpoint URL.\n */\n async unregisterPushSubscription(endpoint: string): Promise<void> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/unregister-push-subscription`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ endpoint }),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to unregister push subscription: ${response.status} ${body}`);\n }\n }\n\n // ===========================================================================\n // Unread summary\n // ===========================================================================\n\n /**\n * Get unread message counts across all conversations for the current user.\n */\n async getUnreadSummary(): Promise<{ totalUnread: number; totalMentions: number }> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/unread-summary`, {\n method: 'POST',\n headers,\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get unread summary: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { totalUnread?: number; totalMentions?: number };\n return { totalUnread: data.totalUnread ?? 0, totalMentions: data.totalMentions ?? 0 };\n }\n\n // ===========================================================================\n // User stats\n // ===========================================================================\n\n /**\n * Get per-user conversation statistics.\n * Optionally filter to a single user by contextInstanceId.\n */\n async getUserStats(opts?: { contextInstanceId?: string }): Promise<UserStat[]> {\n const headers = await this.buildHeaders();\n\n const response = await fetch(`${this.config.apiUrl}/chat/user-stats`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts ?? {}),\n });\n\n if (!response.ok) {\n const body = await response.text();\n throw new Error(`Failed to get user stats: ${response.status} ${body}`);\n }\n\n const data = (await response.json()) as { users?: UserStat[] };\n return data.users ?? [];\n }\n\n // ===========================================================================\n // Lifecycle\n // ===========================================================================\n\n closeConversation(conversationId: string): void {\n const conversation = this.conversations.get(conversationId);\n if (conversation) {\n conversation.disconnect();\n this.conversations.delete(conversationId);\n }\n // Clean up conversation-specific listeners\n this.conversationListeners.delete(conversationId);\n }\n\n destroy(): void {\n this.disconnect();\n for (const [id] of this.conversations) {\n this.conversations.delete(id);\n }\n this.conversationListeners.clear();\n this.globalListeners.clear();\n }\n}\n"],
|
|
5
|
+
"mappings": ";AAiBO,IAAM,eAAN,MAAmB;AAAA,EACf;AAAA,EACD;AAAA,EACA;AAAA,EACA,eAA+B,CAAC;AAAA,EAExC,YAAY,gBAAwB,QAA6B,UAAyB;AACxF,SAAK,iBAAiB;AACtB,SAAK,SAAS;AACd,SAAK,WAAW,YAAY;AAAA,EAC9B;AAAA,EAEA,MAAc,eAAgD;AAC5D,UAAM,QAAQ,MAAM,KAAK,OAAO,SAAS;AACzC,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,MAChB,eAAe,UAAU,KAAK;AAAA,IAChC;AACA,QAAI,KAAK,OAAO,QAAQ;AACtB,cAAQ,gBAAgB,IAAI,KAAK,OAAO;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,SAAiD;AACjE,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,OAAgC;AAAA,MACpC,gBAAgB,KAAK;AAAA,IACvB;AAEA,QAAI,OAAO,YAAY,UAAU;AAC/B,WAAK,MAAM,IAAI;AAAA,IACjB,OAAO;AACL,WAAK,SAAS,IAAI;AAAA,IACpB;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sBAAsB;AAAA,MACtE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,eAAe,MAAM,SAAS,KAAK;AACzC,YAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,IAAI,YAAY,EAAE;AAAA,IAC9E;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,WAAmB,SAAiD;AAChF,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,OAAgC;AAAA,MACpC,gBAAgB,KAAK;AAAA,MACrB,iBAAiB;AAAA,IACnB;AAEA,QAAI,OAAO,YAAY,UAAU;AAC/B,WAAK,MAAM,IAAI;AAAA,IACjB,OAAO;AACL,WAAK,SAAS,IAAI;AAAA,IACpB;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,0BAA0B;AAAA,MAC1E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,eAAe,MAAM,SAAS,KAAK;AACzC,YAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,IAAI,YAAY,EAAE;AAAA,IAClF;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,WAAmB,SAAiD;AACpF,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sBAAsB;AAAA,MACtE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACtE;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,WAAkC;AACpD,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,wBAAwB;AAAA,MACxE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,6BAA6B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACxE;AAAA,EACF;AAAA,EAEA,MAAM,qBAAqB,cAAsB,SAAiD;AAChG,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,OAAgC;AAAA,MACpC,gBAAgB,KAAK;AAAA,MACrB;AAAA,IACF;AAEA,QAAI,OAAO,YAAY,UAAU;AAC/B,WAAK,MAAM,IAAI;AAAA,IACjB,OAAO;AACL,WAAK,SAAS,IAAI;AAAA,IACpB;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,gCAAgC;AAAA,MAChF,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,eAAe,MAAM,SAAS,KAAK;AACzC,YAAM,IAAI,MAAM,qCAAqC,SAAS,MAAM,IAAI,YAAY,EAAE;AAAA,IACxF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,WAAmB,OAA8B;AACjE,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sBAAsB;AAAA,MACtE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACtE;AAAA,EACF;AAAA,EAEA,MAAM,eAAe,WAAmB,OAA8B;AACpE,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,yBAAyB;AAAA,MACzE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,8BAA8B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACzE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,SAAS,WAAmC;AAChD,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,mBAAmB;AAAA,MACnE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MACnC,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,wBAAwB,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACnE;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,OAA8B;AAC9C,WAAO,KAAK,cAAc,EAAE,MAAM,CAAC;AAAA,EACrC;AAAA,EAEA,MAAM,cAAc,QAKF;AAChB,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,wBAAwB;AAAA,MACxE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB,GAAG;AAAA,MACL,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,6BAA6B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACxE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eAAe,QAA+B;AAClD,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,2BAA2B;AAAA,MAC3E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,8BAA8B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACzE;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,QAA+B;AACrD,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,4BAA4B;AAAA,MAC5E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC5E;AAAA,EACF;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,4BAA4B;AAAA,MAC5E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,MACvB,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC5E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,MAAgE;AAChF,UAAM,UAAU,MAAM,KAAK,aAAa;AACxC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sBAAsB;AAAA,MACtE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB,GAAI,MAAM,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,QAC3C,GAAI,MAAM,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,MAChD,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACtE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,YAAY,CAAC;AAAA,EAC3B;AAAA,EAEA,MAAM,iBAAiB,iBAAyB,MAAgE;AAC9G,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,4BAA4B;AAAA,MAC5E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB;AAAA,QACA,GAAI,MAAM,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,QAC3C,GAAI,MAAM,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,MAChD,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC5E;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,YAAY,CAAC;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,GAAyC,OAAU,SAA8C;AAC/F,QAAI,KAAK,UAAU;AACjB,YAAM,QAAQ,KAAK,SAAS;AAAA,QAC1B,KAAK;AAAA,QACL;AAAA,QACA;AAAA,MACF;AACA,WAAK,aAAa,KAAK,KAAK;AAC5B,aAAO;AAAA,IACT;AAGA,WAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAyB;AAAA,EAE/B;AAAA;AAAA,EAGA,aAAmB;AAEjB,eAAW,SAAS,KAAK,cAAc;AACrC,YAAM;AAAA,IACR;AACA,SAAK,eAAe,CAAC;AAAA,EACvB;AACF;;;ACvXA,IAAM,yBAAyB;AAC/B,IAAM,qBAAqB;AAC3B,IAAM,iBAAiB;AAEhB,IAAM,YAAN,MAAgB;AAAA,EACb;AAAA,EACA,kBAA0C;AAAA,EAC1C,iBAAuD;AAAA,EACvD,mBAAmB;AAAA,EACnB,UAAU;AAAA,EAElB,YAAY,QAAyB;AACnC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,UAAyB;AAC7B,SAAK,UAAU;AACf,SAAK,mBAAmB;AACxB,UAAM,KAAK,YAAY;AAAA,EACzB;AAAA,EAEA,aAAmB;AACjB,SAAK,UAAU;AACf,QAAI,KAAK,gBAAgB;AACvB,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AACA,QAAI,KAAK,iBAAiB;AACxB,WAAK,gBAAgB,MAAM;AAC3B,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,UAAiC;AAEjD,UAAM,mBAAmB,KAAK,OAAO;AACrC,SAAK,OAAO,WAAW,MAAM;AAG7B,QAAI,KAAK,iBAAiB;AACxB,WAAK,gBAAgB,MAAM;AAC3B,WAAK,kBAAkB;AACvB,WAAK,mBAAmB;AACxB,YAAM,KAAK,YAAY;AAAA,IACzB;AAGA,SAAK,OAAO,WAAW;AAAA,EACzB;AAAA,EAEA,MAAc,cAA6B;AACzC,QAAI,KAAK;AAAS;AAElB,QAAI;AACF,YAAM,QAAQ,MAAM,KAAK,OAAO,SAAS;AACzC,WAAK,kBAAkB,IAAI,gBAAgB;AAE3C,YAAM,WAAW,MAAM,MAAM,KAAK,OAAO,KAAK;AAAA,QAC5C,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,eAAe,UAAU,KAAK;AAAA,UAC9B,QAAQ;AAAA,QACV;AAAA,QACA,QAAQ,KAAK,gBAAgB;AAAA,MAC/B,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,0BAA0B,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,MACpF;AAEA,UAAI,CAAC,SAAS,MAAM;AAClB,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AAEA,WAAK,mBAAmB;AAExB,WAAK,WAAW,SAAS,IAAI;AAAA,IAC/B,SAAS,OAAO;AACd,UAAI,KAAK;AAAS;AAClB,UAAI,iBAAiB,gBAAgB,MAAM,SAAS;AAAc;AAElE,WAAK,OAAO,eAAe;AAC3B,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAc,WAAW,MAAiD;AACxE,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AAEb,QAAI;AACF,aAAO,MAAM;AACX,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI;AAAM;AAEV,kBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAGhD,cAAM,WAAW,OAAO,MAAM,MAAM;AACpC,iBAAS,SAAS,IAAI,KAAK;AAE3B,mBAAW,WAAW,UAAU;AAC9B,eAAK,gBAAgB,OAAO;AAAA,QAC9B;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,UAAI,KAAK;AAAS;AAClB,UAAI,iBAAiB,gBAAgB,MAAM,SAAS;AAAc;AAAA,IACpE,UAAE;AACA,aAAO,YAAY;AAAA,IACrB;AAGA,QAAI,CAAC,KAAK,SAAS;AACjB,WAAK,OAAO,eAAe;AAC3B,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEQ,gBAAgB,SAAuB;AAE7C,QAAI,QAAQ,KAAK,EAAE,WAAW,GAAG;AAAG;AAEpC,QAAI,YAAY;AAChB,QAAI,OAAO;AAEX,eAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,UAAI,KAAK,WAAW,SAAS,GAAG;AAC9B,oBAAY,KAAK,MAAM,CAAC,EAAE,KAAK;AAAA,MACjC,WAAW,KAAK,WAAW,QAAQ,GAAG;AACpC,eAAO,KAAK,MAAM,CAAC;AAAA,MACrB,WAAW,KAAK,WAAW,OAAO,GAAG;AACnC,eAAO,KAAK,MAAM,CAAC;AAAA,MACrB;AAAA,IACF;AAEA,QAAI,cAAc,aAAa;AAC7B,WAAK,OAAO,YAAY;AACxB;AAAA,IACF;AAEA,QAAI,CAAC;AAAM;AAEX,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,IAAI;AAE9B,UAAI,CAAC,OAAO,MAAM;AAChB,eAAO,OAAO;AAAA,MAChB;AACA,WAAK,OAAO,QAAQ,MAAM;AAAA,IAC5B,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK;AAAS;AAClB,QAAI,KAAK,oBAAoB;AAAwB;AAErD,UAAM,UAAU,KAAK,IAAI,qBAAqB,KAAK,IAAI,GAAG,KAAK,gBAAgB,GAAG,cAAc;AAChG,SAAK;AAEL,SAAK,iBAAiB,WAAW,MAAM;AACrC,WAAK,iBAAiB;AACtB,WAAK,YAAY;AAAA,IACnB,GAAG,OAAO;AAAA,EACZ;AACF;;;AC9JO,IAAM,gBAAN,MAA4C;AAAA,EACzC;AAAA,EACA,gBAAgB,oBAAI,IAA0B;AAAA;AAAA,EAG9C,YAA8B;AAAA,EAC9B,oBAA2D;AAAA,EAC3D,aAAa;AAAA;AAAA,EAGb,kBAAkB,oBAAI,IAA+C;AAAA;AAAA,EAGrE,wBAAwB,oBAAI,IAA4D;AAAA;AAAA,EAGxF;AAAA,EACA;AAAA,EAER,YAAY,QAA6B;AACvC,SAAK,SAAS;AACd,UAAM,MAAM,IAAI,IAAI,OAAO,MAAM;AACjC,SAAK,UAAU,IAAI;AACnB,UAAM,YAAY,IAAI,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AACxD,SAAK,YAAY,UAAU,UAAU,SAAS,CAAC;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,UAAgB;AACd,QAAI,KAAK;AAAW;AAEpB,SAAK,YAAY,IAAI,UAAU;AAAA,MAC7B,KAAK,GAAG,KAAK,OAAO,8BAA8B,mBAAmB,KAAK,SAAS,CAAC;AAAA,MACpF,UAAU,KAAK,OAAO;AAAA,MACtB,SAAS,CAAC,UAAwB,KAAK,kBAAkB,KAAK;AAAA,MAC9D,aAAa,MAAM;AACjB,aAAK,aAAa;AAClB,aAAK,WAAW,WAAW;AAAA,MAC7B;AAAA,MACA,gBAAgB,MAAM;AACpB,aAAK,aAAa;AAClB,aAAK,WAAW,cAAc;AAAA,MAChC;AAAA,IACF,CAAC;AAED,SAAK,KAAK,UAAU,QAAQ;AAG5B,SAAK,oBAAoB;AAAA,MACvB,YAAY;AACV,YAAI,KAAK,WAAW;AAClB,gBAAM,WAAW,MAAM,KAAK,OAAO,SAAS;AAC5C,gBAAM,KAAK,UAAU,YAAY,QAAQ;AAAA,QAC3C;AAAA,MACF;AAAA,MACA,KAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,aAAmB;AACjB,QAAI,KAAK,mBAAmB;AAC1B,oBAAc,KAAK,iBAAiB;AACpC,WAAK,oBAAoB;AAAA,IAC3B;AACA,QAAI,KAAK,WAAW;AAClB,WAAK,UAAU,WAAW;AAC1B,WAAK,YAAY;AAAA,IACnB;AACA,SAAK,aAAa;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,GAAG,OAAe,SAAmD;AACnE,QAAI,CAAC,KAAK,gBAAgB,IAAI,KAAK,GAAG;AACpC,WAAK,gBAAgB,IAAI,OAAO,oBAAI,IAAI,CAAC;AAAA,IAC3C;AACA,SAAK,gBAAgB,IAAI,KAAK,EAAG,IAAI,OAAO;AAC5C,WAAO,MAAM;AACX,WAAK,gBAAgB,IAAI,KAAK,GAAG,OAAO,OAAO;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe,SAA6C;AAC9D,SAAK,gBAAgB,IAAI,KAAK,GAAG,OAAO,OAAO;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAMA,wBAAwB,gBAAwB,OAAe,SAAmD;AAChH,QAAI,CAAC,KAAK,sBAAsB,IAAI,cAAc,GAAG;AACnD,WAAK,sBAAsB,IAAI,gBAAgB,oBAAI,IAAI,CAAC;AAAA,IAC1D;AACA,UAAM,UAAU,KAAK,sBAAsB,IAAI,cAAc;AAC7D,QAAI,CAAC,QAAQ,IAAI,KAAK,GAAG;AACvB,cAAQ,IAAI,OAAO,oBAAI,IAAI,CAAC;AAAA,IAC9B;AACA,YAAQ,IAAI,KAAK,EAAG,IAAI,OAAO;AAE/B,WAAO,MAAM;AACX,cAAQ,IAAI,KAAK,GAAG,OAAO,OAAO;AAAA,IACpC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAkB,OAA2B;AACnD,UAAM,YAAY,MAAM;AACxB,UAAM,iBAAiB,MAAM;AAE7B,SAAK,WAAW,WAAW,KAAK;AAGhC,QAAI,gBAAgB;AAClB,YAAM,UAAU,KAAK,sBAAsB,IAAI,cAAc;AAC7D,UAAI,SAAS;AACX,cAAM,WAAW,QAAQ,IAAI,SAAS;AACtC,YAAI,UAAU;AACZ,qBAAW,WAAW,UAAU;AAC9B,gBAAI;AACF,sBAAQ,KAAK;AAAA,YACf,QAAQ;AAAA,YAER;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,WAAW,UAAkB,MAAuB;AAC1D,UAAM,WAAW,KAAK,gBAAgB,IAAI,KAAK;AAC/C,QAAI,UAAU;AACZ,iBAAW,WAAW,UAAU;AAC9B,YAAI;AACF,kBAAQ,GAAG,IAAI;AAAA,QACjB,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,eAAgD;AAC5D,UAAM,QAAQ,MAAM,KAAK,OAAO,SAAS;AACzC,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,MAChB,eAAe,UAAU,KAAK;AAAA,IAChC;AACA,QAAI,KAAK,OAAO,QAAQ;AACtB,cAAQ,gBAAgB,IAAI,KAAK,OAAO;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsB,MAAuC;AACnE,QAAI,iBAAiB,KAAK,gBAAgB;AAC1C,QAAI,CAAC,kBAAkB,KAAK,cAAc,GAAG;AAC3C,UAAI,OAAO,KAAK,cAAc;AAC9B,UAAI,OAAO,SAAS,UAAU;AAC5B,YAAI;AACF,iBAAO,KAAK,MAAM,IAAI;AAAA,QACxB,QAAQ;AAAA,QAER;AAAA,MACF;AACA,UAAI,QAAQ,OAAO,SAAS,YAAY,QAAQ,MAAM;AACpD,yBAAkB,KAAwB;AAAA,MAC5C;AAAA,IACF;AACA,QAAI,CAAC,gBAAgB;AACnB,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,gBAAsC;AAC9D,UAAM,WAAW,KAAK,cAAc,IAAI,cAAc;AACtD,QAAI;AAAU,aAAO;AACrB,UAAM,eAAe,IAAI,aAAa,gBAAgB,KAAK,QAAQ,IAAI;AACvE,SAAK,cAAc,IAAI,gBAAgB,YAAY;AACnD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,gBAAsC;AACpD,WAAO,KAAK,kBAAkB,cAAc;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBACJ,UAKI,CAAC,GACkB;AACvB,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,iBAAiB,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,6BAA6B;AAAA,MACnF,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,QAChD,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MAC3D,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,eAAe,IAAI;AACtB,YAAM,OAAO,MAAM,eAAe,KAAK;AACvC,YAAM,IAAI,MAAM,kCAAkC,eAAe,MAAM,IAAI,IAAI,EAAE;AAAA,IACnF;AAEA,UAAM,aAAc,MAAM,eAAe,KAAK;AAC9C,UAAM,iBAAiB,KAAK,sBAAsB,UAAU;AAE5D,QAAI,QAAQ,SAAS;AACnB,YAAM,iBAAiB,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sBAAsB;AAAA,QAC5E,QAAQ;AAAA,QACR;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB;AAAA,UACA,SAAS,QAAQ;AAAA,UACjB,GAAI,QAAQ,iBAAiB,EAAE,gBAAgB,QAAQ,eAAe,IAAI,CAAC;AAAA,QAC7E,CAAC;AAAA,MACH,CAAC;AAED,UAAI,CAAC,eAAe,IAAI;AACtB,cAAM,OAAO,MAAM,eAAe,KAAK;AACvC,cAAM,IAAI,MAAM,2BAA2B,eAAe,MAAM,IAAI,IAAI,EAAE;AAAA,MAC5E;AAAA,IACF;AAEA,WAAO,KAAK,kBAAkB,cAAc;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAAc,MAKM;AACxB,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,wBAAwB;AAAA,MACxE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,6BAA6B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACxE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAM,iBAAiB,KAAK,sBAAsB,IAAI;AACtD,WAAO,KAAK,kBAAkB,cAAc;AAAA,EAC9C;AAAA,EAEA,MAAM,YAAY,gBAA+C;AAC/D,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sBAAsB;AAAA,MACtE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,eAAe,CAAC;AAAA,IACzC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACtE;AAEA,WAAO,KAAK,kBAAkB,cAAc;AAAA,EAC9C;AAAA,EAEA,MAAM,aAAa,MAA8F;AAC/G,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,uBAAuB;AAAA,MACvE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,QAAQ,CAAC,CAAC;AAAA,IACjC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACvE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,iBAAiB,CAAC;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,QAAuC;AAClD,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,mBAAmB;AAAA,MACnE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,eAAe,OAAO,CAAC;AAAA,IAChD,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,sBAAsB,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACjE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAM,iBAAiB,KAAK,sBAAsB,IAAI;AACtD,WAAO,KAAK,kBAAkB,cAAc;AAAA,EAC9C;AAAA,EAEA,MAAM,YAAY,SAA0C;AAC1D,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,yBAAyB;AAAA,MACzE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,gBAAgB,QAAQ,CAAC;AAAA,IAClD,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACvE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAM,iBAAiB,KAAK,sBAAsB,IAAI;AACtD,WAAO,KAAK,kBAAkB,cAAc;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBAAkB,MAMyD;AAC/E,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,4BAA4B;AAAA,MAC5E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,QAAQ,CAAC,CAAC;AAAA,IACjC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC5E;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,EAAE,eAAe,KAAK,iBAAiB,CAAC,GAAG,qBAAqB,KAAK,oBAAoB;AAAA,EAClG;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,MAAiE;AACjF,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sBAAsB;AAAA,MACtE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,QAAQ,CAAC,CAAC;AAAA,IACjC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACtE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,SAAS,CAAC;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAoE;AACxE,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,qBAAqB;AAAA,MACrE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,IACzB,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,0BAA0B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACrE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,EAAE,GAAI,KAAK,WAAW,CAAC,GAAI,mBAAmB,KAAK,kBAAkB;AAAA,EAC9E;AAAA,EAEA,MAAM,YAAY,oBAAoE;AACpF,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sBAAsB;AAAA,MACtE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,mBAAmB,CAAC;AAAA,IAC7C,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACtE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,YAAY,CAAC;AAAA,EAC3B;AAAA,EAEA,MAAM,cAAc,SAKK;AACvB,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,wBAAwB;AAAA,MACxE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,OAAO;AAAA,IAC9B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,6BAA6B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACxE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,WAAW,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAAqC;AACzC,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sBAAsB;AAAA,MACtE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,IACzB,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,2BAA2B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACtE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,YAAY,CAAC;AAAA,EAC3B;AAAA,EAEA,MAAM,UAAU,UAAyC;AACvD,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,oBAAoB;AAAA,MACpE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,IACnC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,yBAAyB,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACpE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,aAAa,OAAiD;AAClE,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,uBAAuB;AAAA,MACvE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,KAAK;AAAA,IAC5B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACvE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,aAAa,OAAiD;AAClE,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,uBAAuB;AAAA,MACvE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,KAAK;AAAA,IAC5B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACvE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,aAAa,UAAiC;AAClD,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,uBAAuB;AAAA,MACvE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,IACnC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACvE;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,UAAkB,SAAyC;AAC/E,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,0BAA0B;AAAA,MAC1E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,UAAU,QAAQ,CAAC;AAAA,IAC5C,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC1E;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,kBAAkB,UAAgD;AACtE,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,6BAA6B;AAAA,MAC7E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,IACnC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,kCAAkC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC7E;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,YAAY,CAAC;AAAA,EAC3B;AAAA,EAEA,MAAM,iBAAiB,UAAkB,SAA+C;AACtF,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,4BAA4B;AAAA,MAC5E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,UAAU,QAAQ,CAAC;AAAA,IAC5C,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC5E;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,oBAAoB,UAAkB,SAAwC;AAClF,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,+BAA+B;AAAA,MAC/E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,UAAU,QAAQ,CAAC;AAAA,IAC5C,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,oCAAoC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC/E;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,iBACJ,UACA,UACsG;AACtG,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,4BAA4B;AAAA,MAC5E,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,UAAU,SAAS,CAAC;AAAA,IAC7C,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC5E;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAM9B;AAAA,EAEA,MAAM,uBAAuB,QAAgB,aAAwE;AACnH,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,kCAAkC;AAAA,MAClF,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,QAAQ,YAAY,CAAC;AAAA,IAC9C,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,uCAAuC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAClF;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,qBAAqB,OAAiE;AAC1F,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,gCAAgC;AAAA,MAChF,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,KAAK;AAAA,IAC5B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,qCAAqC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAChF;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,WAAW,gBAAwB,MAAY,UAA8C;AACjG,UAAM,QAAQ,MAAM,KAAK,OAAO,SAAS;AACzC,UAAM,WAAW,IAAI,SAAS;AAC9B,aAAS,OAAO,QAAQ,MAAM,QAAQ;AACtC,aAAS,OAAO,kBAAkB,cAAc;AAEhD,UAAM,UAAkC;AAAA,MACtC,eAAe,UAAU,KAAK;AAAA,IAChC;AACA,QAAI,KAAK,OAAO,QAAQ;AACtB,cAAQ,gBAAgB,IAAI,KAAK,OAAO;AAAA,IAC1C;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,qBAAqB;AAAA,MACrE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,0BAA0B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACrE;AAEA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,oBAA4C;AAChD,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,uBAAuB;AAAA,MACvE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,IACzB,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,SAAS,WAAW;AAAK,eAAO;AACpC,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,4BAA4B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACvE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,kBAAkB;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,yBAAyB,cAAmD;AAChF,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,oCAAoC;AAAA,MACpF,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,aAAa,CAAC;AAAA,IACvC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,yCAAyC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACpF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,2BAA2B,UAAiC;AAChE,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,sCAAsC;AAAA,MACtF,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,IACnC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,2CAA2C,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACtF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,mBAA4E;AAChF,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,wBAAwB;AAAA,MACxE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,IACzB,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC5E;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,EAAE,aAAa,KAAK,eAAe,GAAG,eAAe,KAAK,iBAAiB,EAAE;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAa,MAA4D;AAC7E,UAAM,UAAU,MAAM,KAAK,aAAa;AAExC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,oBAAoB;AAAA,MACpE,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU,QAAQ,CAAC,CAAC;AAAA,IACjC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,6BAA6B,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACxE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,SAAS,CAAC;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,gBAA8B;AAC9C,UAAM,eAAe,KAAK,cAAc,IAAI,cAAc;AAC1D,QAAI,cAAc;AAChB,mBAAa,WAAW;AACxB,WAAK,cAAc,OAAO,cAAc;AAAA,IAC1C;AAEA,SAAK,sBAAsB,OAAO,cAAc;AAAA,EAClD;AAAA,EAEA,UAAgB;AACd,SAAK,WAAW;AAChB,eAAW,CAAC,EAAE,KAAK,KAAK,eAAe;AACrC,WAAK,cAAc,OAAO,EAAE;AAAA,IAC9B;AACA,SAAK,sBAAsB,MAAM;AACjC,SAAK,gBAAgB,MAAM;AAAA,EAC7B;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { GigabuddyChat } from './lib/GigabuddyChat.js';
|
|
2
2
|
export { Conversation } from './lib/Conversation.js';
|
|
3
|
-
export type { GigabuddyChatConfig, ChannelEvent, ChannelEventType, ConversationEventMap, Message, UserProfile, ConversationType, ConversationVisibility, MessageRole, MessageContent, TextContent, GadgetContent, GadgetRefineContent, DataContent, SystemContent, CompositeContent, FileContent, MessageReaction, ConversationReadState, ConversationInfo, ChatUser, UserStreamEventType, ConversationAddedEvent, ConversationRemovedEvent, ChatEventBus, ChatNotification, GadgetInfo, GadgetDetail, GadgetVersionInfo, GadgetVersionDetail, CreateGadgetInput, UpdateGadgetInput, StateFieldDefinition, StatefulGadgetSpec, CreateStatefulGadgetInput, StatefulGadgetResult, } from './lib/types.js';
|
|
3
|
+
export type { GigabuddyChatConfig, ChannelEvent, ChannelEventType, ConversationEventMap, Message, UserProfile, ConversationType, ConversationVisibility, MessageRole, MessageContent, TextContent, GadgetContent, GadgetRefineContent, DataContent, SystemContent, CompositeContent, FileContent, MessageReaction, ConversationReadState, ConversationInfo, ChatUser, UserStreamEventType, ConversationAddedEvent, ConversationRemovedEvent, ChatEventBus, ChatNotification, GadgetInfo, GadgetDetail, GadgetVersionInfo, GadgetVersionDetail, CreateGadgetInput, UpdateGadgetInput, StateFieldDefinition, StatefulGadgetSpec, CreateStatefulGadgetInput, StatefulGadgetResult, UserStat, } from './lib/types.js';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* connection and routes events to conversation-level listeners.
|
|
6
6
|
*/
|
|
7
7
|
import { Conversation } from './Conversation.js';
|
|
8
|
-
import type { ChatEventBus, ChatUser, ConversationInfo, ConversationType, ConversationVisibility, CreateGadgetInput, CreateStatefulGadgetInput, FileUploadResult, GadgetDetail, GadgetInfo, GadgetVersionDetail, GadgetVersionInfo, GigabuddyChatConfig, StatefulGadgetResult, StatefulGadgetSpec, UpdateGadgetInput, UserProfile } from './types.js';
|
|
8
|
+
import type { ChatEventBus, ChatUser, ConversationInfo, ConversationType, ConversationVisibility, CreateGadgetInput, CreateStatefulGadgetInput, FileUploadResult, GadgetDetail, GadgetInfo, GadgetVersionDetail, GadgetVersionInfo, GigabuddyChatConfig, StatefulGadgetResult, StatefulGadgetSpec, UpdateGadgetInput, UserProfile, UserStat } from './types.js';
|
|
9
9
|
export declare class GigabuddyChat implements ChatEventBus {
|
|
10
10
|
private config;
|
|
11
11
|
private conversations;
|
|
@@ -135,6 +135,13 @@ export declare class GigabuddyChat implements ChatEventBus {
|
|
|
135
135
|
totalUnread: number;
|
|
136
136
|
totalMentions: number;
|
|
137
137
|
}>;
|
|
138
|
+
/**
|
|
139
|
+
* Get per-user conversation statistics.
|
|
140
|
+
* Optionally filter to a single user by contextInstanceId.
|
|
141
|
+
*/
|
|
142
|
+
getUserStats(opts?: {
|
|
143
|
+
contextInstanceId?: string;
|
|
144
|
+
}): Promise<UserStat[]>;
|
|
138
145
|
closeConversation(conversationId: string): void;
|
|
139
146
|
destroy(): void;
|
|
140
147
|
}
|
package/src/lib/types.d.ts
CHANGED
|
@@ -301,3 +301,10 @@ export interface StatefulGadgetResult {
|
|
|
301
301
|
latestVersion: number;
|
|
302
302
|
data: GadgetDetail['data'];
|
|
303
303
|
}
|
|
304
|
+
export interface UserStat {
|
|
305
|
+
contextInstanceId: string;
|
|
306
|
+
name: string;
|
|
307
|
+
conversationCount: number;
|
|
308
|
+
lastActiveAt: string | null;
|
|
309
|
+
firstSeenAt: string | null;
|
|
310
|
+
}
|