@bootdesk/js-web-adapter-core 0.4.19 → 0.4.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/index.cjs +40 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -6
- package/dist/index.d.ts +13 -6
- package/dist/index.js +40 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -83,6 +83,14 @@ const client = new WebChatClient({
|
|
|
83
83
|
});
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
+
Channel name hashing (for threadIds with incompatible chars like `:`):
|
|
87
|
+
```typescript
|
|
88
|
+
const broadcast = new PusherBroadcastClient(config, "chat", {
|
|
89
|
+
useHashChannel: true,
|
|
90
|
+
});
|
|
91
|
+
// Uses Web Crypto SHA-256 — safe for Pusher char restrictions
|
|
92
|
+
```
|
|
93
|
+
|
|
86
94
|
### Push Notifications
|
|
87
95
|
|
|
88
96
|
```typescript
|
package/dist/index.cjs
CHANGED
|
@@ -399,8 +399,8 @@ var WebChatClient = class {
|
|
|
399
399
|
threadEvents.onReactionAdded = (event) => this.handleReactionAdded(event);
|
|
400
400
|
threadEvents.onReactionRemoved = (event) => this.handleReactionRemoved(event);
|
|
401
401
|
}
|
|
402
|
-
this.broadcastClient.subscribe(threadId, threadEvents);
|
|
403
|
-
this.unsubscribeUserChannel = this.broadcastClient.subscribeToUser(
|
|
402
|
+
await this.broadcastClient.subscribe(threadId, threadEvents);
|
|
403
|
+
this.unsubscribeUserChannel = await this.broadcastClient.subscribeToUser(
|
|
404
404
|
threadId,
|
|
405
405
|
this.currentUserId,
|
|
406
406
|
{
|
|
@@ -763,6 +763,7 @@ var PusherBroadcastClient = class {
|
|
|
763
763
|
this.channelPrefix = channelPrefix;
|
|
764
764
|
this.threadChannelType = channelTypes?.threadChannel ?? "public";
|
|
765
765
|
this.userChannelType = channelTypes?.userChannel ?? "private";
|
|
766
|
+
this.useHashChannel = channelTypes?.useHashChannel ?? false;
|
|
766
767
|
if ("key" in pusherOrConfig) {
|
|
767
768
|
const PusherCtor = globalThis.Pusher ?? globalThis.pusherJs;
|
|
768
769
|
if (!PusherCtor) {
|
|
@@ -783,6 +784,20 @@ var PusherBroadcastClient = class {
|
|
|
783
784
|
return base;
|
|
784
785
|
}
|
|
785
786
|
}
|
|
787
|
+
async buildResolvedChannelName(threadId) {
|
|
788
|
+
const name = this.useHashChannel ? await this.hashChannelName(threadId) : threadId;
|
|
789
|
+
return `${this.channelPrefix}.${name}`;
|
|
790
|
+
}
|
|
791
|
+
async hashChannelName(name) {
|
|
792
|
+
if (typeof crypto?.subtle?.digest !== "function") {
|
|
793
|
+
throw new Error("Web Crypto API not available. Cannot hash channel names.");
|
|
794
|
+
}
|
|
795
|
+
const encoder = new TextEncoder();
|
|
796
|
+
const data = encoder.encode(name);
|
|
797
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
798
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
799
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
800
|
+
}
|
|
786
801
|
connect() {
|
|
787
802
|
if (this.pusher.connection?.state !== "connected") {
|
|
788
803
|
this.pusher.connect();
|
|
@@ -793,8 +808,8 @@ var PusherBroadcastClient = class {
|
|
|
793
808
|
this.subscriptions.clear();
|
|
794
809
|
this.pusher.disconnect?.();
|
|
795
810
|
}
|
|
796
|
-
subscribe(threadId, handlers) {
|
|
797
|
-
const baseName =
|
|
811
|
+
async subscribe(threadId, handlers) {
|
|
812
|
+
const baseName = await this.buildResolvedChannelName(threadId);
|
|
798
813
|
const channelName = this.buildChannelName(baseName, this.threadChannelType);
|
|
799
814
|
const channel = this.pusher.subscribe(channelName);
|
|
800
815
|
const key = `thread:${threadId}`;
|
|
@@ -819,8 +834,8 @@ var PusherBroadcastClient = class {
|
|
|
819
834
|
this.subscriptions.delete(key);
|
|
820
835
|
};
|
|
821
836
|
}
|
|
822
|
-
subscribeToUser(threadId, userId, handlers) {
|
|
823
|
-
const baseName = `${this.
|
|
837
|
+
async subscribeToUser(threadId, userId, handlers) {
|
|
838
|
+
const baseName = `${await this.buildResolvedChannelName(threadId)}.${userId}`;
|
|
824
839
|
const channelName = this.buildChannelName(baseName, this.userChannelType);
|
|
825
840
|
const channel = this.pusher.subscribe(channelName);
|
|
826
841
|
const key = `user:${threadId}:${userId}`;
|
|
@@ -880,6 +895,7 @@ var LaravelEchoBroadcastClient = class {
|
|
|
880
895
|
this.channelPrefix = channelPrefix;
|
|
881
896
|
this.threadChannelType = channelTypes?.threadChannel ?? "public";
|
|
882
897
|
this.userChannelType = channelTypes?.userChannel ?? "private";
|
|
898
|
+
this.useHashChannel = channelTypes?.useHashChannel ?? false;
|
|
883
899
|
}
|
|
884
900
|
subscribeToEcho(name, type) {
|
|
885
901
|
switch (type) {
|
|
@@ -901,8 +917,22 @@ var LaravelEchoBroadcastClient = class {
|
|
|
901
917
|
});
|
|
902
918
|
this.subscriptions.clear();
|
|
903
919
|
}
|
|
904
|
-
|
|
905
|
-
const
|
|
920
|
+
async buildResolvedChannelName(threadId) {
|
|
921
|
+
const name = this.useHashChannel ? await this.hashChannelName(threadId) : threadId;
|
|
922
|
+
return `${this.channelPrefix}.${name}`;
|
|
923
|
+
}
|
|
924
|
+
async hashChannelName(name) {
|
|
925
|
+
if (typeof crypto?.subtle?.digest !== "function") {
|
|
926
|
+
throw new Error("Web Crypto API not available. Cannot hash channel names.");
|
|
927
|
+
}
|
|
928
|
+
const encoder = new TextEncoder();
|
|
929
|
+
const data = encoder.encode(name);
|
|
930
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
931
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
932
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
933
|
+
}
|
|
934
|
+
async subscribe(threadId, handlers) {
|
|
935
|
+
const channelName = await this.buildResolvedChannelName(threadId);
|
|
906
936
|
const channel = this.subscribeToEcho(channelName, this.threadChannelType);
|
|
907
937
|
const key = `thread:${threadId}`;
|
|
908
938
|
this.subscriptions.set(key, channel);
|
|
@@ -925,8 +955,8 @@ var LaravelEchoBroadcastClient = class {
|
|
|
925
955
|
this.subscriptions.delete(key);
|
|
926
956
|
};
|
|
927
957
|
}
|
|
928
|
-
subscribeToUser(threadId, userId, handlers) {
|
|
929
|
-
const channelName = `${this.
|
|
958
|
+
async subscribeToUser(threadId, userId, handlers) {
|
|
959
|
+
const channelName = `${await this.buildResolvedChannelName(threadId)}.${userId}`;
|
|
930
960
|
const channel = this.subscribeToEcho(channelName, this.userChannelType);
|
|
931
961
|
const key = `user:${threadId}:${userId}`;
|
|
932
962
|
this.subscriptions.set(key, channel);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client/HttpClient.ts","../src/events/base/ChatEvent.ts","../src/events/MessagePostedEvent.ts","../src/events/MessageEditedEvent.ts","../src/events/MessageDeletedEvent.ts","../src/events/ReactionAddedEvent.ts","../src/events/ReactionRemovedEvent.ts","../src/events/TypingStartedEvent.ts","../src/events/StreamingChunkEvent.ts","../src/events/DMRequestedEvent.ts","../src/events/ChatEventFactory.ts","../src/utils/eventIdGenerator.ts","../src/client/WebChatClient.ts","../src/client/PusherBroadcastClient.ts","../src/client/LaravelEchoBroadcastClient.ts","../src/push/PushManager.ts","../src/push/PushSubscriptionManager.ts"],"sourcesContent":["export { WebChatClient } from \"./client/WebChatClient\";\nexport type {\n WebChatClientConfig,\n ReconfigureConfig,\n LoadMessagesOptions,\n LoadMessagesResult,\n} from \"./client/WebChatClient\";\n\nexport {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./client/BroadcastClient\";\nexport { PusherBroadcastClient } from \"./client/PusherBroadcastClient\";\nexport type { PusherConfig } from \"./client/PusherBroadcastClient\";\nexport { LaravelEchoBroadcastClient } from \"./client/LaravelEchoBroadcastClient\";\n\nexport { HttpClient } from \"./client/HttpClient\";\nexport type { HttpClientConfig, ChatResponse } from \"./client/HttpClient\";\n\nexport * from \"./types\";\n\nexport { ChatEvent, UnknownEvent } from \"./events/base/ChatEvent\";\nexport { parseChatEvent } from \"./events/ChatEventFactory\";\nexport { MessagePostedEvent } from \"./events/MessagePostedEvent\";\nexport { MessageEditedEvent } from \"./events/MessageEditedEvent\";\nexport { MessageDeletedEvent } from \"./events/MessageDeletedEvent\";\nexport { ReactionAddedEvent } from \"./events/ReactionAddedEvent\";\nexport { ReactionRemovedEvent } from \"./events/ReactionRemovedEvent\";\nexport { TypingStartedEvent } from \"./events/TypingStartedEvent\";\nexport { StreamingChunkEvent } from \"./events/StreamingChunkEvent\";\nexport { DMRequestedEvent } from \"./events/DMRequestedEvent\";\n\nexport { generateId, generateConversationId } from \"./utils/eventIdGenerator\";\n\nexport { PushManager } from \"./push/PushManager\";\nexport { createPushSubscriptionHandlers } from \"./push/PushSubscriptionManager\";\nexport type { PushSubscriptionStatus, PushConfig, PushEventData } from \"./push/types\";\n","export interface HttpClientConfig {\n apiUrl: string;\n headers?: Record<string, string>;\n timeout?: number;\n verifyToken?: string;\n}\n\nexport interface ChatResponse {\n id: string;\n role: \"assistant\" | \"user\";\n text: string;\n attachments?: Array<{\n type: string;\n url: string;\n name?: string;\n mime_type?: string;\n size?: number;\n }>;\n events?: Array<Record<string, unknown>>;\n}\n\nexport class HttpClient {\n private config: Required<Pick<HttpClientConfig, \"apiUrl\" | \"timeout\">> & {\n headers: Record<string, string>;\n };\n\n constructor(config: HttpClientConfig) {\n const headers: Record<string, string> = { ...config.headers };\n if (config.verifyToken) {\n headers[\"X-Verify-Token\"] = config.verifyToken;\n }\n this.config = { apiUrl: config.apiUrl, timeout: config.timeout ?? 30000, headers };\n }\n\n async get(url: string, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"GET\",\n headers: this.config.headers,\n signal: combined,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async post(url: string, body: unknown, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.config.headers },\n signal: combined,\n body: JSON.stringify(body),\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async delete(url: string, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"DELETE\",\n headers: this.config.headers,\n signal: combined,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n const text = await response.text();\n return text ? JSON.parse(text) : undefined;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async sendMessage(\n messages: Array<{\n id: string;\n role: string;\n text: string;\n attachments?: Array<{ url: string; name?: string; mime_type?: string; size?: number }>;\n }>,\n endpoint: string = \"/api/webhooks/web\",\n conversationId?: string,\n ): Promise<ChatResponse> {\n return this.post(endpoint, { id: conversationId, messages }) as Promise<ChatResponse>;\n }\n\n async sendAction(\n actionId: string,\n value: string,\n messageId: string,\n conversationId: string,\n endpoint: string = \"/api/webhooks/web\",\n ): Promise<Record<string, unknown>> {\n return this.post(endpoint, {\n id: conversationId,\n action: { actionId, value, messageId },\n }) as Promise<Record<string, unknown>>;\n }\n\n async editMessage(\n messageId: string,\n newText: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/edit\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.post(url, { text: newText });\n }\n\n async deleteMessage(\n messageId: string,\n endpointTemplate: string = \"/api/chat/messages/{id}\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.delete(url);\n }\n\n async addReaction(\n messageId: string,\n emoji: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/reactions\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.post(url, { emoji });\n }\n\n async removeReaction(\n messageId: string,\n emoji: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/reactions/{emoji}\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId, emoji });\n await this.delete(url);\n }\n\n async postFormData(url: string, formData: FormData, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"POST\",\n headers: this.config.headers,\n signal: combined,\n body: formData,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n setHeader(name: string, value: string): void {\n this.config.headers[name] = value;\n }\n\n removeHeader(name: string): void {\n delete this.config.headers[name];\n }\n\n private resolve(url: string): string {\n return /^https?:\\/\\//.test(url) ? url : `${this.config.apiUrl}${url}`;\n }\n\n private expandTemplate(template: string, params: Record<string, string>): string {\n let url = template;\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`{${key}}`, encodeURIComponent(value));\n }\n return this.resolve(url);\n }\n}\n","export abstract class ChatEvent {\n readonly type: string;\n readonly threadId: string;\n readonly timestamp: number;\n\n constructor(type: string, threadId: string, timestamp: number) {\n this.type = type;\n this.threadId = threadId;\n this.timestamp = timestamp;\n }\n\n static fromJSON: ((json: Record<string, unknown>) => ChatEvent) | undefined;\n}\n\nexport class UnknownEvent extends ChatEvent {\n readonly data: Record<string, unknown>;\n\n constructor(type: string, threadId: string, data: Record<string, unknown>, timestamp: number) {\n super(type, threadId, timestamp);\n this.data = data;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User, Card } from \"../types\";\n\nexport class MessagePostedEvent extends ChatEvent {\n readonly messageId: string;\n readonly text: string;\n readonly author: User;\n readonly card?: Card;\n readonly attachments?: Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>;\n\n constructor(\n threadId: string,\n messageId: string,\n text: string,\n author: User,\n card?: Card,\n attachments?: Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>,\n timestamp?: number,\n ) {\n super(\"message.posted\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.text = text;\n this.author = author;\n this.card = card;\n this.attachments = attachments;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { Card } from \"../types\";\n\nexport class MessageEditedEvent extends ChatEvent {\n readonly messageId: string;\n readonly newText: string;\n readonly card?: Card;\n\n constructor(\n threadId: string,\n messageId: string,\n newText: string,\n card?: Card,\n timestamp?: number,\n ) {\n super(\"message.edited\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.newText = newText;\n this.card = card;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class MessageDeletedEvent extends ChatEvent {\n readonly messageId: string;\n\n constructor(threadId: string, messageId: string, timestamp?: number) {\n super(\"message.deleted\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User } from \"../types\";\n\nexport class ReactionAddedEvent extends ChatEvent {\n readonly messageId: string;\n readonly emoji: string;\n readonly user: User;\n\n constructor(threadId: string, messageId: string, emoji: string, user: User, timestamp?: number) {\n super(\"reaction.added\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.emoji = emoji;\n this.user = user;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User } from \"../types\";\n\nexport class ReactionRemovedEvent extends ChatEvent {\n readonly messageId: string;\n readonly emoji: string;\n readonly user: User;\n\n constructor(threadId: string, messageId: string, emoji: string, user: User, timestamp?: number) {\n super(\"reaction.removed\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.emoji = emoji;\n this.user = user;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class TypingStartedEvent extends ChatEvent {\n readonly userId: string;\n\n constructor(threadId: string, userId: string, timestamp?: number) {\n super(\"typing.started\", threadId, timestamp ?? Date.now());\n this.userId = userId;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class StreamingChunkEvent extends ChatEvent {\n readonly messageId: string;\n readonly chunk: string;\n readonly isFinal: boolean;\n\n constructor(\n threadId: string,\n messageId: string,\n chunk: string,\n isFinal: boolean,\n timestamp?: number,\n ) {\n super(\"streaming.chunk\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.chunk = chunk;\n this.isFinal = isFinal;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class DMRequestedEvent extends ChatEvent {\n readonly userId: string;\n\n constructor(threadId: string, userId: string, timestamp?: number) {\n super(\"dm.requested\", threadId, timestamp ?? Date.now());\n this.userId = userId;\n }\n}\n","import { ChatEvent, UnknownEvent } from \"./base/ChatEvent\";\nimport type { Card, User } from \"../types\";\nimport { MessagePostedEvent } from \"./MessagePostedEvent\";\nimport { MessageEditedEvent } from \"./MessageEditedEvent\";\nimport { MessageDeletedEvent } from \"./MessageDeletedEvent\";\nimport { ReactionAddedEvent } from \"./ReactionAddedEvent\";\nimport { ReactionRemovedEvent } from \"./ReactionRemovedEvent\";\nimport { TypingStartedEvent } from \"./TypingStartedEvent\";\nimport { StreamingChunkEvent } from \"./StreamingChunkEvent\";\nimport { DMRequestedEvent } from \"./DMRequestedEvent\";\n\nfunction parseCard(value: unknown): Card | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const obj = value as Record<string, unknown>;\n if (typeof obj.type !== \"string\") return undefined;\n return obj as unknown as Card;\n}\n\nexport function parseChatEvent(json: Record<string, unknown>): ChatEvent {\n const type = json.type as string;\n const threadId = json.threadId as string;\n const timestamp = json.timestamp as number;\n const data = (json.data ?? {}) as Record<string, unknown>;\n\n switch (type) {\n case \"message.posted\":\n return new MessagePostedEvent(\n threadId,\n data.messageId as string,\n data.text as string,\n data.author as User,\n parseCard(data.card),\n data.attachments as Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>,\n timestamp,\n );\n case \"message.edited\":\n return new MessageEditedEvent(\n threadId,\n data.messageId as string,\n data.newText as string,\n parseCard(data.card),\n timestamp,\n );\n case \"message.deleted\":\n return new MessageDeletedEvent(threadId, data.messageId as string, timestamp);\n case \"reaction.added\":\n return new ReactionAddedEvent(\n threadId,\n data.messageId as string,\n data.emoji as string,\n data.user as User,\n timestamp,\n );\n case \"reaction.removed\":\n return new ReactionRemovedEvent(\n threadId,\n data.messageId as string,\n data.emoji as string,\n data.user as User,\n timestamp,\n );\n case \"typing.started\":\n return new TypingStartedEvent(threadId, data.userId as string, timestamp);\n case \"streaming.chunk\":\n return new StreamingChunkEvent(\n threadId,\n data.messageId as string,\n data.chunk as string,\n data.isFinal as boolean,\n timestamp,\n );\n case \"dm.requested\":\n return new DMRequestedEvent(threadId, data.userId as string, timestamp);\n default:\n return new UnknownEvent(type, threadId, data, timestamp);\n }\n}\n\n// Wire up the static method\nChatEvent.fromJSON = parseChatEvent;\n","export function generateId(): string {\n return `msg-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\nexport function generateConversationId(): string {\n return `conv-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n","import { HttpClient } from \"./HttpClient\";\nimport type { BroadcastClient, EventHandlers, Unsubscribe } from \"./BroadcastClient\";\nimport type { Message } from \"../types\";\nimport { ChatEvent } from \"../events/base/ChatEvent\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type { MessagePostedEvent } from \"../events/MessagePostedEvent\";\nimport type { MessageEditedEvent } from \"../events/MessageEditedEvent\";\nimport type { MessageDeletedEvent } from \"../events/MessageDeletedEvent\";\nimport type { ReactionAddedEvent } from \"../events/ReactionAddedEvent\";\nimport type { ReactionRemovedEvent } from \"../events/ReactionRemovedEvent\";\nimport type { TypingStartedEvent } from \"../events/TypingStartedEvent\";\nimport type { StreamingChunkEvent } from \"../events/StreamingChunkEvent\";\nimport type { DMRequestedEvent } from \"../events/DMRequestedEvent\";\nimport { generateId, generateConversationId } from \"../utils/eventIdGenerator\";\n\nexport interface ReconfigureConfig {\n userId?: string;\n userName?: string;\n verifyToken?: string;\n conversationId?: string;\n headers?: Record<string, string>;\n}\n\nexport interface WebChatClientConfig {\n apiUrl: string;\n userId: string;\n userName: string;\n broadcastClient?: BroadcastClient;\n headers?: Record<string, string>;\n verifyToken?: string;\n conversationId?: string;\n endpoints?: {\n sendMessage?: string;\n loadMessages?: string;\n editMessage?: string;\n deleteMessage?: string;\n addReaction?: string;\n removeReaction?: string;\n };\n features?: {\n editMessages?: boolean;\n deleteMessages?: boolean;\n reactions?: boolean;\n };\n}\n\ninterface StreamingState {\n messageId: string;\n accumulatedText: string;\n isComplete: boolean;\n}\n\ninterface AttachmentInput {\n url: string;\n name?: string;\n mimeType?: string;\n size?: number;\n}\n\nexport interface LoadMessagesOptions {\n limit?: number;\n before?: number;\n after?: number;\n skipStateSeed?: boolean;\n}\n\nexport interface LoadMessagesResult {\n messages: Message[];\n hasMore: boolean;\n nextCursor?: number;\n prevCursor?: number;\n}\n\nexport class WebChatClient {\n private config: WebChatClientConfig;\n private httpClient: HttpClient;\n private broadcastClient?: BroadcastClient;\n private conversationId: string;\n private messages: Message[] = [];\n private currentUserId: string;\n private eventHandlers: EventHandlers = {};\n private streamingMessages: Map<string, StreamingState> = new Map();\n private pendingTyping: ReturnType<typeof setTimeout> | null = null;\n private subscribers: Map<string, Array<(event: unknown) => void>> = new Map();\n private unsubscribeUserChannel?: Unsubscribe;\n\n constructor(config: WebChatClientConfig) {\n this.config = config;\n this.httpClient = new HttpClient({\n apiUrl: config.apiUrl,\n headers: {\n \"X-User-Id\": config.userId,\n \"X-User-Name\": config.userName,\n ...(config.headers ?? {}),\n },\n verifyToken: config.verifyToken,\n });\n this.broadcastClient = config.broadcastClient;\n this.conversationId = config.conversationId ?? generateConversationId();\n this.currentUserId = config.userId;\n }\n\n reconfigure(config: ReconfigureConfig): void {\n if (config.userId) {\n this.currentUserId = config.userId;\n this.httpClient.setHeader(\"X-User-Id\", config.userId);\n }\n if (config.userName) {\n this.config = { ...this.config, userName: config.userName };\n this.httpClient.setHeader(\"X-User-Name\", config.userName);\n }\n if (config.verifyToken) {\n this.config = { ...this.config, verifyToken: config.verifyToken };\n this.httpClient.setHeader(\"X-Verify-Token\", config.verifyToken);\n }\n if (config.conversationId) {\n this.conversationId = config.conversationId;\n }\n if (config.headers) {\n Object.entries(config.headers).forEach(([key, value]) => {\n this.httpClient.setHeader(key, value);\n });\n }\n }\n\n setLocaleHeader(locale: string): void {\n this.httpClient.setHeader(\"X-Locale\", locale);\n this.httpClient.setHeader(\"X-Language\", locale.split(\"-\")[0] ?? locale);\n }\n\n setTimezoneHeader(timezone: string): void {\n this.httpClient.setHeader(\"X-Timezone\", timezone);\n }\n\n async connect(): Promise<void> {\n if (this.broadcastClient) {\n this.broadcastClient.connect();\n\n const threadId = this.getThreadId();\n const threadEvents: EventHandlers = {\n onMessagePosted: (event) => this.handleMessagePosted(event),\n };\n\n if (this.config.features?.editMessages) {\n threadEvents.onMessageEdited = (event) => this.handleMessageEdited(event);\n }\n if (this.config.features?.deleteMessages) {\n threadEvents.onMessageDeleted = (event) => this.handleMessageDeleted(event);\n }\n if (this.config.features?.reactions) {\n threadEvents.onReactionAdded = (event) => this.handleReactionAdded(event);\n threadEvents.onReactionRemoved = (event) => this.handleReactionRemoved(event);\n }\n\n this.broadcastClient.subscribe(threadId, threadEvents);\n\n this.unsubscribeUserChannel = this.broadcastClient.subscribeToUser(\n threadId,\n this.currentUserId,\n {\n onTypingStarted: (event) => this.handleTypingStarted(event),\n onStreamingChunk: (event) => this.handleStreamingChunk(event),\n onDMRequested: (event) => this.handleDMRequested(event),\n },\n );\n }\n }\n\n disconnect(): void {\n this.unsubscribeUserChannel?.();\n this.unsubscribeUserChannel = undefined;\n this.broadcastClient?.disconnect();\n this.streamingMessages.clear();\n }\n\n async loadMessages(\n options?: LoadMessagesOptions,\n signal?: AbortSignal,\n ): Promise<LoadMessagesResult> {\n const endpoint = this.config.endpoints?.loadMessages ?? \"/api/chat/messages\";\n const threadId = this.getThreadId();\n const params = new URLSearchParams({\n threadId,\n limit: String(options?.limit ?? 50),\n });\n if (options?.before) params.set(\"before\", String(options.before));\n if (options?.after) params.set(\"after\", String(options.after));\n\n const response = (await this.httpClient.get(\n `${endpoint}?${params.toString()}`,\n signal,\n )) as Record<string, unknown>;\n const rawMessages = (response.messages as Record<string, unknown>[]) ?? [];\n const messages: Message[] = rawMessages.map((msg) => ({\n id: msg.id as string,\n threadId,\n content: {\n text: msg.text as string,\n cards: msg.card ? ([msg.card as Record<string, unknown>] as never[]) : undefined,\n },\n author: {\n id: (msg.author as Record<string, unknown>).id as string,\n name: (msg.author as Record<string, unknown>).name as string,\n isBot: ((msg.author as Record<string, unknown>).isBot as boolean) ?? false,\n isMe: (msg.author as Record<string, unknown>).id === this.currentUserId,\n },\n timestamp: msg.timestamp as number,\n attachments: (msg.attachments as Record<string, unknown>[])?.map((a) => ({\n id: `att-${msg.id as string}-${a.url as string}`,\n url: a.url as string,\n name: a.name as string,\n type: a.type as string,\n mimeType: a.mime_type as string,\n size: a.size as number,\n })),\n reactions: (msg.reactions as { emoji: string; count: number; users: string[] }[]) ?? [],\n }));\n\n if (!options?.before && !options?.after && !options?.skipStateSeed) {\n this.messages = messages;\n this.notifySubscribers(\"messages:loaded\", messages);\n }\n\n return {\n messages,\n hasMore: (response.hasMore as boolean) ?? false,\n nextCursor: response.nextCursor as number | undefined,\n prevCursor: response.prevCursor as number | undefined,\n };\n }\n\n async sendMessage(text: string, attachments: AttachmentInput[] = []): Promise<void> {\n const messageId = generateId();\n\n const userMessage: Message = {\n id: messageId,\n threadId: this.getThreadId(),\n content: { text },\n author: { id: this.currentUserId, name: this.config.userName, isMe: true },\n timestamp: Date.now(),\n attachments:\n attachments.length > 0\n ? attachments.map((a, i) => ({\n id: `att-${messageId}-${i}`,\n name: a.name ?? \"\",\n url: a.url,\n size: a.size,\n mimeType: a.mimeType,\n }))\n : undefined,\n };\n\n this.messages.push(userMessage);\n this.notifySubscribers(\"message:added\", userMessage);\n\n const endpoint = this.config.endpoints?.sendMessage ?? \"/api/webhooks/web\";\n const response = await this.httpClient.sendMessage(\n [\n {\n id: messageId,\n role: \"user\",\n text,\n attachments: attachments.map((a) => ({\n url: a.url,\n name: a.name,\n mime_type: a.mimeType,\n size: a.size,\n })),\n },\n ],\n endpoint,\n this.conversationId,\n );\n\n if (response.events) {\n response.events.forEach((eventData) => {\n const event = parseChatEvent(eventData);\n this.dispatchEvent(event);\n });\n }\n\n if (response.text && !response.events?.some((e) => e.type === \"message.posted\")) {\n const assistantMessage: Message = {\n id: response.id ?? generateId(),\n threadId: this.getThreadId(),\n content: { text: response.text },\n author: { id: \"assistant\", name: \"Assistant\", isBot: true },\n timestamp: Date.now(),\n attachments: (response.attachments as Record<string, unknown>[])?.map((a, i) => ({\n id: `att-${response.id ?? \"msg\"}-${i}`,\n name: (a.name as string) ?? \"\",\n url: (a.url as string) ?? \"\",\n type: a.type as string,\n mimeType: a.mime_type as string,\n size: a.size as number,\n })),\n };\n this.messages.push(assistantMessage);\n this.notifySubscribers(\"message:added\", assistantMessage);\n }\n }\n\n async sendAction(messageId: string, actionId: string, value: string): Promise<void> {\n const endpoint = this.config.endpoints?.sendMessage ?? \"/api/webhooks/web\";\n const response = await this.httpClient.sendAction(\n actionId,\n value,\n messageId,\n this.conversationId,\n endpoint,\n );\n\n if (response.events) {\n (response.events as Array<Record<string, unknown>>).forEach((eventData) => {\n const event = parseChatEvent(eventData);\n this.dispatchEvent(event);\n });\n }\n }\n\n async editMessage(messageId: string, newText: string): Promise<void> {\n if (!this.config.features?.editMessages) {\n throw new Error(\"Edit messages not enabled. Set features.editMessages = true in config.\");\n }\n const endpoint = this.config.endpoints?.editMessage ?? \"/api/chat/messages/{id}/edit\";\n await this.httpClient.editMessage(messageId, newText, endpoint);\n }\n\n async deleteMessage(messageId: string): Promise<void> {\n if (!this.config.features?.deleteMessages) {\n throw new Error(\"Delete messages not enabled. Set features.deleteMessages = true in config.\");\n }\n const endpoint = this.config.endpoints?.deleteMessage ?? \"/api/chat/messages/{id}\";\n await this.httpClient.deleteMessage(messageId, endpoint);\n }\n\n async addReaction(messageId: string, emoji: string): Promise<void> {\n if (!this.config.features?.reactions) {\n throw new Error(\"Reactions not enabled. Set features.reactions = true in config.\");\n }\n const endpoint = this.config.endpoints?.addReaction ?? \"/api/chat/messages/{id}/reactions\";\n await this.httpClient.addReaction(messageId, emoji, endpoint);\n }\n\n async removeReaction(messageId: string, emoji: string): Promise<void> {\n if (!this.config.features?.reactions) {\n throw new Error(\"Reactions not enabled. Set features.reactions = true in config.\");\n }\n const endpoint =\n this.config.endpoints?.removeReaction ?? \"/api/chat/messages/{id}/reactions/{emoji}\";\n await this.httpClient.removeReaction(messageId, emoji, endpoint);\n }\n\n onMessagePosted(handler: (event: MessagePostedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message.posted\", handler);\n }\n\n onMessageEdited(handler: (event: MessageEditedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message:edited\", handler);\n }\n\n onMessageDeleted(handler: (event: MessageDeletedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message:deleted\", handler);\n }\n\n onReactionAdded(handler: (event: ReactionAddedEvent) => void): Unsubscribe {\n return this.addEventListener(\"reaction:added\", handler);\n }\n\n onReactionRemoved(handler: (event: ReactionRemovedEvent) => void): Unsubscribe {\n return this.addEventListener(\"reaction:removed\", handler);\n }\n\n onStreamingChunk(handler: (event: StreamingChunkEvent) => void): Unsubscribe {\n return this.addEventListener(\"streaming:chunk\", handler);\n }\n\n onTypingStarted(handler: (event: TypingStartedEvent) => void): Unsubscribe {\n return this.addEventListener(\"typing:started\", handler);\n }\n\n getConversationId(): string {\n return this.conversationId;\n }\n getMessages(): Message[] {\n return [...this.messages];\n }\n getThreadId(): string {\n return `web:${this.currentUserId}:${this.conversationId}`;\n }\n getCurrentUserId(): string {\n return this.currentUserId;\n }\n getFeatures(): NonNullable<WebChatClientConfig[\"features\"]> {\n return this.config.features ?? {};\n }\n getEndpoints(): NonNullable<WebChatClientConfig[\"endpoints\"]> {\n return this.config.endpoints ?? {};\n }\n getHttpClient(): HttpClient {\n return this.httpClient;\n }\n\n addEventListener<T = unknown>(eventType: string, handler: (event: T) => void): Unsubscribe {\n if (!this.subscribers.has(eventType)) this.subscribers.set(eventType, []);\n this.subscribers.get(eventType)!.push(handler as (event: unknown) => void);\n return () => {\n const handlers = this.subscribers.get(eventType);\n if (handlers) {\n const index = handlers.indexOf(handler as (event: unknown) => void);\n if (index !== -1) handlers.splice(index, 1);\n }\n };\n }\n\n private handleMessagePosted(event: MessagePostedEvent): void {\n if (this.messages.some((m) => m.id === event.messageId)) return;\n if (this.streamingMessages.has(event.messageId)) return;\n\n const message: Message = {\n id: event.messageId,\n threadId: event.threadId,\n content: { text: event.text, cards: event.card ? [event.card] : undefined },\n author: event.author,\n timestamp: event.timestamp,\n attachments: event.attachments?.map((a) => ({\n id: `att-${event.messageId}-${Math.random().toString(36).slice(2, 8)}`,\n name: a.name ?? \"\",\n url: a.url ?? \"\",\n type: a.type,\n mimeType: a.mimeType,\n size: a.size ?? undefined,\n })),\n };\n this.messages.push(message);\n this.notifySubscribers(\"message:added\", message);\n this.notifySubscribers(\"message.posted\", event);\n }\n\n private handleMessageEdited(event: MessageEditedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (message?.content) {\n message.content.text = event.newText;\n this.notifySubscribers(\"message:edited\", event);\n }\n }\n\n private handleMessageDeleted(event: MessageDeletedEvent): void {\n const index = this.messages.findIndex((m) => m.id === event.messageId);\n if (index !== -1) {\n this.messages.splice(index, 1);\n this.notifySubscribers(\"message:deleted\", event);\n }\n }\n\n private handleReactionAdded(event: ReactionAddedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (!message) return;\n if (!message.reactions) message.reactions = [];\n\n const existing = message.reactions.find((r) => r.emoji === event.emoji);\n if (existing) {\n existing.count++;\n existing.users.push(event.user.id);\n } else {\n message.reactions.push({ emoji: event.emoji, count: 1, users: [event.user.id] });\n }\n this.notifySubscribers(\"reaction:added\", event);\n }\n\n private handleReactionRemoved(event: ReactionRemovedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (!message?.reactions) return;\n\n const index = message.reactions.findIndex((r) => r.emoji === event.emoji);\n if (index !== -1) {\n const reaction = message.reactions[index]!;\n reaction.count--;\n reaction.users = reaction.users.filter((id) => id !== event.user.id);\n if (reaction.count === 0) message.reactions.splice(index, 1);\n }\n this.notifySubscribers(\"reaction:removed\", event);\n }\n\n private handleStreamingChunk(event: StreamingChunkEvent): void {\n const { messageId, chunk, isFinal } = event;\n\n if (!this.streamingMessages.has(messageId)) {\n this.streamingMessages.set(messageId, { messageId, accumulatedText: \"\", isComplete: false });\n this.notifySubscribers(\"streaming:started\", event);\n }\n\n const state = this.streamingMessages.get(messageId)!;\n state.accumulatedText += chunk;\n\n if (isFinal) {\n state.isComplete = true;\n if (!this.messages.some((m) => m.id === messageId)) {\n const message: Message = {\n id: messageId,\n threadId: event.threadId,\n content: { text: state.accumulatedText },\n author: { id: \"assistant\", name: \"Assistant\", isBot: true },\n timestamp: event.timestamp,\n };\n this.messages.push(message);\n this.notifySubscribers(\"message:added\", message);\n }\n this.streamingMessages.delete(messageId);\n this.notifySubscribers(\"streaming:complete\", { messageId, text: state.accumulatedText });\n } else {\n this.notifySubscribers(\"streaming:chunk\", event);\n }\n }\n\n private handleTypingStarted(event: TypingStartedEvent): void {\n if (this.pendingTyping) clearTimeout(this.pendingTyping);\n this.notifySubscribers(\"typing:started\", event);\n this.pendingTyping = setTimeout(() => {\n this.notifySubscribers(\"typing:stopped\", { userId: event.userId });\n }, 3000);\n }\n\n private handleDMRequested(event: DMRequestedEvent): void {\n this.notifySubscribers(\"dm.requested\", event);\n }\n\n private notifySubscribers<T>(eventType: string, data: T): void {\n this.subscribers.get(eventType)?.forEach((handler) => handler(data));\n }\n\n private dispatchEvent(event: ChatEvent): void {\n switch (event.type) {\n case \"message.posted\":\n this.handleMessagePosted(event as MessagePostedEvent);\n break;\n case \"message.edited\":\n this.handleMessageEdited(event as MessageEditedEvent);\n break;\n case \"message.deleted\":\n this.handleMessageDeleted(event as MessageDeletedEvent);\n break;\n case \"reaction.added\":\n this.handleReactionAdded(event as ReactionAddedEvent);\n break;\n case \"reaction.removed\":\n this.handleReactionRemoved(event as ReactionRemovedEvent);\n break;\n case \"typing.started\":\n this.handleTypingStarted(event as TypingStartedEvent);\n break;\n case \"streaming.chunk\":\n this.handleStreamingChunk(event as StreamingChunkEvent);\n break;\n case \"dm.requested\":\n this.handleDMRequested(event as DMRequestedEvent);\n break;\n }\n }\n}\n","import {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./BroadcastClient\";\nimport { ChatEvent } from \"../events/base/ChatEvent\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type Pusher from \"pusher-js\";\nimport type { Channel as PusherChannel } from \"pusher-js\";\n\nexport interface PusherConfig {\n key: string;\n cluster?: string;\n host?: string;\n port?: number;\n forceTLS?: boolean;\n authEndpoint?: string;\n}\n\nexport class PusherBroadcastClient implements BroadcastClient {\n private pusher: Pusher;\n private channelPrefix: string;\n private threadChannelType: \"public\" | \"private\" | \"presence\";\n private userChannelType: \"private\" | \"presence\";\n private subscriptions: Map<string, PusherChannel> = new Map();\n\n constructor(pusher: Pusher, channelPrefix?: string, channelTypes?: ChannelTypeConfig);\n constructor(config: PusherConfig, channelPrefix?: string, channelTypes?: ChannelTypeConfig);\n constructor(\n pusherOrConfig: Pusher | PusherConfig,\n channelPrefix: string = \"chat\",\n channelTypes?: ChannelTypeConfig,\n ) {\n this.channelPrefix = channelPrefix;\n this.threadChannelType = channelTypes?.threadChannel ?? \"public\";\n this.userChannelType = channelTypes?.userChannel ?? \"private\";\n\n if (\"key\" in pusherOrConfig) {\n const PusherCtor = (globalThis as any).Pusher ?? (globalThis as any).pusherJs;\n if (!PusherCtor) {\n throw new Error(\"pusher-js not found. Install it or pass a Pusher instance.\");\n }\n this.pusher = new PusherCtor((pusherOrConfig as PusherConfig).key, pusherOrConfig) as Pusher;\n } else {\n this.pusher = pusherOrConfig as Pusher;\n }\n }\n\n private buildChannelName(base: string, type: \"public\" | \"private\" | \"presence\"): string {\n switch (type) {\n case \"private\":\n return `private-${base}`;\n case \"presence\":\n return `presence-${base}`;\n default:\n return base;\n }\n }\n\n connect(): void {\n if (this.pusher.connection?.state !== \"connected\") {\n this.pusher.connect();\n }\n }\n\n disconnect(): void {\n this.subscriptions.forEach((channel) => channel.unbind_all?.() ?? channel.unsubscribe?.());\n this.subscriptions.clear();\n this.pusher.disconnect?.();\n }\n\n subscribe(threadId: string, handlers: EventHandlers): Unsubscribe {\n const baseName = `${this.channelPrefix}.${threadId}`;\n const channelName = this.buildChannelName(baseName, this.threadChannelType);\n const channel = this.pusher.subscribe(channelName);\n const key = `thread:${threadId}`;\n this.subscriptions.set(key, channel);\n\n const threadEvents = [\n \"message.posted\",\n \"message.edited\",\n \"message.deleted\",\n \"reaction.added\",\n \"reaction.removed\",\n ] as const;\n\n threadEvents.forEach((eventType) => {\n const eventName = `${this.channelPrefix}.${eventType}`;\n channel.bind(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n this.dispatchToHandler(event, handlers);\n });\n });\n\n return () => {\n channel.unbind_all?.();\n this.pusher.unsubscribe(channelName);\n this.subscriptions.delete(key);\n };\n }\n\n subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Unsubscribe {\n const baseName = `${this.channelPrefix}.${threadId}.${userId}`;\n const channelName = this.buildChannelName(baseName, this.userChannelType);\n const channel = this.pusher.subscribe(channelName);\n const key = `user:${threadId}:${userId}`;\n this.subscriptions.set(key, channel);\n\n const userEvents = [\"typing.started\", \"streaming.chunk\", \"dm.requested\"] as const;\n\n userEvents.forEach((eventType) => {\n const eventName = `${this.channelPrefix}.${eventType}`;\n channel.bind(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n this.dispatchToHandler(event, handlers);\n });\n });\n\n return () => {\n channel.unbind_all?.();\n this.pusher.unsubscribe(channelName);\n this.subscriptions.delete(key);\n };\n }\n\n isConnected(): boolean {\n return this.pusher.connection?.state === \"connected\";\n }\n\n private dispatchToHandler(event: ChatEvent, handlers: EventHandlers): void {\n switch (event.type) {\n case \"message.posted\":\n handlers.onMessagePosted?.(event as any);\n break;\n case \"message.edited\":\n handlers.onMessageEdited?.(event as any);\n break;\n case \"message.deleted\":\n handlers.onMessageDeleted?.(event as any);\n break;\n case \"reaction.added\":\n handlers.onReactionAdded?.(event as any);\n break;\n case \"reaction.removed\":\n handlers.onReactionRemoved?.(event as any);\n break;\n case \"typing.started\":\n handlers.onTypingStarted?.(event as any);\n break;\n case \"streaming.chunk\":\n handlers.onStreamingChunk?.(event as any);\n break;\n case \"dm.requested\":\n handlers.onDMRequested?.(event as any);\n break;\n }\n }\n}\n","import {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./BroadcastClient\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type Echo from \"laravel-echo\";\n\ninterface EchoChannel {\n listen(event: string, callback: (data: unknown) => void): this;\n unsubscribe(): void;\n stopListening(event?: string, callback?: (data: unknown) => void): this;\n}\n\nexport class LaravelEchoBroadcastClient implements BroadcastClient {\n private echo: Echo<any>;\n private channelPrefix: string;\n private threadChannelType: \"public\" | \"private\" | \"presence\";\n private userChannelType: \"private\" | \"presence\";\n private subscriptions: Map<string, EchoChannel> = new Map();\n\n constructor(echo: Echo<any>, channelPrefix: string = \"chat\", channelTypes?: ChannelTypeConfig) {\n this.echo = echo;\n this.channelPrefix = channelPrefix;\n this.threadChannelType = channelTypes?.threadChannel ?? \"public\";\n this.userChannelType = channelTypes?.userChannel ?? \"private\";\n }\n\n private subscribeToEcho(name: string, type: \"public\" | \"private\" | \"presence\"): EchoChannel {\n switch (type) {\n case \"private\":\n return this.echo.private(name) as unknown as EchoChannel;\n case \"presence\":\n return this.echo.join(name) as unknown as EchoChannel;\n default:\n return this.echo.channel(name) as unknown as EchoChannel;\n }\n }\n\n connect(): void | Promise<void> {\n return Promise.resolve();\n }\n\n disconnect(): void {\n this.subscriptions.forEach((channel) => {\n channel.unsubscribe?.();\n channel.stopListening?.();\n });\n this.subscriptions.clear();\n }\n\n subscribe(threadId: string, handlers: EventHandlers): Unsubscribe {\n const channelName = `${this.channelPrefix}.${threadId}`;\n const channel = this.subscribeToEcho(channelName, this.threadChannelType);\n const key = `thread:${threadId}`;\n this.subscriptions.set(key, channel);\n\n const threadEvents: Array<{ type: string; handler: keyof EventHandlers }> = [\n { type: \"message.posted\", handler: \"onMessagePosted\" },\n { type: \"message.edited\", handler: \"onMessageEdited\" },\n { type: \"message.deleted\", handler: \"onMessageDeleted\" },\n { type: \"reaction.added\", handler: \"onReactionAdded\" },\n { type: \"reaction.removed\", handler: \"onReactionRemoved\" },\n ];\n\n threadEvents.forEach(({ type, handler }) => {\n const eventName = `.${this.channelPrefix}.${type}`;\n channel.listen(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n (handlers[handler] as any)?.(event);\n });\n });\n\n return () => {\n channel.unsubscribe?.();\n this.subscriptions.delete(key);\n };\n }\n\n subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Unsubscribe {\n const channelName = `${this.channelPrefix}.${threadId}.${userId}`;\n const channel = this.subscribeToEcho(channelName, this.userChannelType);\n const key = `user:${threadId}:${userId}`;\n this.subscriptions.set(key, channel);\n\n const userEvents: Array<{ type: string; handler: keyof EventHandlers }> = [\n { type: \"typing.started\", handler: \"onTypingStarted\" },\n { type: \"streaming.chunk\", handler: \"onStreamingChunk\" },\n { type: \"dm.requested\", handler: \"onDMRequested\" },\n ];\n\n userEvents.forEach(({ type, handler }) => {\n const eventName = `.${this.channelPrefix}.${type}`;\n channel.listen(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n (handlers[handler] as any)?.(event);\n });\n });\n\n return () => {\n channel.unsubscribe?.();\n this.subscriptions.delete(key);\n };\n }\n\n isConnected(): boolean {\n try {\n const connector = (this.echo as any).connector;\n if (!connector) return false;\n\n if (connector.pusher?.connection?.state === \"connected\") return true;\n if (connector.socket?.connected) return true;\n\n return false;\n } catch {\n return false;\n }\n }\n}\n","import type { PushConfig, PushSubscriptionStatus, PushEventData } from \"./types\";\n\nexport class PushManager {\n private config: PushConfig;\n private registration: ServiceWorkerRegistration | null = null;\n private status: PushSubscriptionStatus = \"unsupported\";\n private statusListeners: Set<(status: PushSubscriptionStatus) => void> = new Set();\n private messageListeners: Set<(data: PushEventData) => void> = new Set();\n\n constructor(config: PushConfig) {\n this.config = config;\n }\n\n static isSupported(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n \"serviceWorker\" in navigator &&\n \"PushManager\" in window &&\n \"Notification\" in window\n );\n }\n\n getStatus(): PushSubscriptionStatus {\n return this.status;\n }\n\n onStatusChange(listener: (status: PushSubscriptionStatus) => void): () => void {\n this.statusListeners.add(listener);\n return () => {\n this.statusListeners.delete(listener);\n };\n }\n\n onMessage(listener: (data: PushEventData) => void): () => void {\n this.messageListeners.add(listener);\n return () => {\n this.messageListeners.delete(listener);\n };\n }\n\n async initialize(): Promise<void> {\n if (!PushManager.isSupported()) {\n this.setStatus(\"unsupported\");\n return;\n }\n if (Notification.permission === \"denied\") {\n this.setStatus(\"denied\");\n return;\n }\n\n try {\n this.registration = await navigator.serviceWorker.register(\n this.config.serviceWorkerUrl || \"/chat-service-worker.js\",\n {\n scope: this.config.serviceWorkerScope || \"/\",\n type: this.config.serviceWorkerType,\n },\n );\n await navigator.serviceWorker.ready;\n\n navigator.serviceWorker.addEventListener(\"message\", (event: MessageEvent) => {\n const msg = event.data as Record<string, unknown>;\n if (msg?.type === \"chat-widget:push-data\") {\n const pushData = msg.data as PushEventData;\n this.messageListeners.forEach((listener) => listener(pushData));\n }\n });\n\n const subscription = await this.registration.pushManager.getSubscription();\n this.setStatus(subscription ? \"subscribed\" : \"default\");\n } catch {\n this.setStatus(\"error\");\n }\n }\n\n async subscribe(): Promise<void> {\n if (!this.registration)\n throw new Error(\"PushManager not initialized. Call initialize() first.\");\n\n this.setStatus(\"subscribing\");\n\n try {\n let subscription = await this.registration.pushManager.getSubscription();\n\n if (!subscription) {\n const permission = await Notification.requestPermission();\n if (permission !== \"granted\") {\n this.setStatus(permission === \"denied\" ? \"denied\" : \"default\");\n return;\n }\n\n const vapidPublicKey = await this.config.getVapidPublicKey();\n const convertedKey = this.urlBase64ToUint8Array(vapidPublicKey);\n subscription = await this.registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: convertedKey.buffer as ArrayBuffer,\n });\n }\n\n await this.config.onSubscribe(subscription.toJSON());\n this.setStatus(\"subscribed\");\n } catch {\n this.setStatus(\"error\");\n throw new Error(\"Push subscription failed\");\n }\n }\n\n async unsubscribe(): Promise<void> {\n if (!this.registration) return;\n\n try {\n const subscription = await this.registration.pushManager.getSubscription();\n if (subscription) {\n await this.config.onUnsubscribe(subscription.toJSON());\n await subscription.unsubscribe();\n }\n this.setStatus(\"default\");\n } catch {\n this.setStatus(\"error\");\n throw new Error(\"Push unsubscription failed\");\n }\n }\n\n private urlBase64ToUint8Array(base64String: string): Uint8Array {\n const padding = \"=\".repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding).replace(/-/g, \"+\").replace(/_/g, \"/\");\n const rawData = atob(base64);\n return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0)));\n }\n\n private setStatus(status: PushSubscriptionStatus): void {\n this.status = status;\n this.statusListeners.forEach((listener) => listener(status));\n }\n}\n","import { HttpClient } from \"../client/HttpClient\";\nimport type { PushConfig } from \"./types\";\n\nexport function createPushSubscriptionHandlers(\n httpClient: HttpClient,\n userId: string,\n): Pick<PushConfig, \"onSubscribe\" | \"onUnsubscribe\"> {\n return {\n onSubscribe: async (subscription: PushSubscriptionJSON) => {\n await httpClient.post(\"/api/push/subscriptions\", {\n userId,\n subscription,\n userAgent: navigator.userAgent,\n });\n },\n onUnsubscribe: async (subscription: PushSubscriptionJSON) => {\n await httpClient.delete(\n `/api/push/subscriptions?userId=${encodeURIComponent(userId)}&endpoint=${encodeURIComponent(subscription.endpoint || \"\")}`,\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client/HttpClient.ts","../src/events/base/ChatEvent.ts","../src/events/MessagePostedEvent.ts","../src/events/MessageEditedEvent.ts","../src/events/MessageDeletedEvent.ts","../src/events/ReactionAddedEvent.ts","../src/events/ReactionRemovedEvent.ts","../src/events/TypingStartedEvent.ts","../src/events/StreamingChunkEvent.ts","../src/events/DMRequestedEvent.ts","../src/events/ChatEventFactory.ts","../src/utils/eventIdGenerator.ts","../src/client/WebChatClient.ts","../src/client/PusherBroadcastClient.ts","../src/client/LaravelEchoBroadcastClient.ts","../src/push/PushManager.ts","../src/push/PushSubscriptionManager.ts"],"sourcesContent":["export { WebChatClient } from \"./client/WebChatClient\";\nexport type {\n WebChatClientConfig,\n ReconfigureConfig,\n LoadMessagesOptions,\n LoadMessagesResult,\n} from \"./client/WebChatClient\";\n\nexport {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./client/BroadcastClient\";\nexport { PusherBroadcastClient } from \"./client/PusherBroadcastClient\";\nexport type { PusherConfig } from \"./client/PusherBroadcastClient\";\nexport { LaravelEchoBroadcastClient } from \"./client/LaravelEchoBroadcastClient\";\n\nexport { HttpClient } from \"./client/HttpClient\";\nexport type { HttpClientConfig, ChatResponse } from \"./client/HttpClient\";\n\nexport * from \"./types\";\n\nexport { ChatEvent, UnknownEvent } from \"./events/base/ChatEvent\";\nexport { parseChatEvent } from \"./events/ChatEventFactory\";\nexport { MessagePostedEvent } from \"./events/MessagePostedEvent\";\nexport { MessageEditedEvent } from \"./events/MessageEditedEvent\";\nexport { MessageDeletedEvent } from \"./events/MessageDeletedEvent\";\nexport { ReactionAddedEvent } from \"./events/ReactionAddedEvent\";\nexport { ReactionRemovedEvent } from \"./events/ReactionRemovedEvent\";\nexport { TypingStartedEvent } from \"./events/TypingStartedEvent\";\nexport { StreamingChunkEvent } from \"./events/StreamingChunkEvent\";\nexport { DMRequestedEvent } from \"./events/DMRequestedEvent\";\n\nexport { generateId, generateConversationId } from \"./utils/eventIdGenerator\";\n\nexport { PushManager } from \"./push/PushManager\";\nexport { createPushSubscriptionHandlers } from \"./push/PushSubscriptionManager\";\nexport type { PushSubscriptionStatus, PushConfig, PushEventData } from \"./push/types\";\n","export interface HttpClientConfig {\n apiUrl: string;\n headers?: Record<string, string>;\n timeout?: number;\n verifyToken?: string;\n}\n\nexport interface ChatResponse {\n id: string;\n role: \"assistant\" | \"user\";\n text: string;\n attachments?: Array<{\n type: string;\n url: string;\n name?: string;\n mime_type?: string;\n size?: number;\n }>;\n events?: Array<Record<string, unknown>>;\n}\n\nexport class HttpClient {\n private config: Required<Pick<HttpClientConfig, \"apiUrl\" | \"timeout\">> & {\n headers: Record<string, string>;\n };\n\n constructor(config: HttpClientConfig) {\n const headers: Record<string, string> = { ...config.headers };\n if (config.verifyToken) {\n headers[\"X-Verify-Token\"] = config.verifyToken;\n }\n this.config = { apiUrl: config.apiUrl, timeout: config.timeout ?? 30000, headers };\n }\n\n async get(url: string, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"GET\",\n headers: this.config.headers,\n signal: combined,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async post(url: string, body: unknown, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.config.headers },\n signal: combined,\n body: JSON.stringify(body),\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async delete(url: string, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"DELETE\",\n headers: this.config.headers,\n signal: combined,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n const text = await response.text();\n return text ? JSON.parse(text) : undefined;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async sendMessage(\n messages: Array<{\n id: string;\n role: string;\n text: string;\n attachments?: Array<{ url: string; name?: string; mime_type?: string; size?: number }>;\n }>,\n endpoint: string = \"/api/webhooks/web\",\n conversationId?: string,\n ): Promise<ChatResponse> {\n return this.post(endpoint, { id: conversationId, messages }) as Promise<ChatResponse>;\n }\n\n async sendAction(\n actionId: string,\n value: string,\n messageId: string,\n conversationId: string,\n endpoint: string = \"/api/webhooks/web\",\n ): Promise<Record<string, unknown>> {\n return this.post(endpoint, {\n id: conversationId,\n action: { actionId, value, messageId },\n }) as Promise<Record<string, unknown>>;\n }\n\n async editMessage(\n messageId: string,\n newText: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/edit\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.post(url, { text: newText });\n }\n\n async deleteMessage(\n messageId: string,\n endpointTemplate: string = \"/api/chat/messages/{id}\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.delete(url);\n }\n\n async addReaction(\n messageId: string,\n emoji: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/reactions\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.post(url, { emoji });\n }\n\n async removeReaction(\n messageId: string,\n emoji: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/reactions/{emoji}\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId, emoji });\n await this.delete(url);\n }\n\n async postFormData(url: string, formData: FormData, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"POST\",\n headers: this.config.headers,\n signal: combined,\n body: formData,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n setHeader(name: string, value: string): void {\n this.config.headers[name] = value;\n }\n\n removeHeader(name: string): void {\n delete this.config.headers[name];\n }\n\n private resolve(url: string): string {\n return /^https?:\\/\\//.test(url) ? url : `${this.config.apiUrl}${url}`;\n }\n\n private expandTemplate(template: string, params: Record<string, string>): string {\n let url = template;\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`{${key}}`, encodeURIComponent(value));\n }\n return this.resolve(url);\n }\n}\n","export abstract class ChatEvent {\n readonly type: string;\n readonly threadId: string;\n readonly timestamp: number;\n\n constructor(type: string, threadId: string, timestamp: number) {\n this.type = type;\n this.threadId = threadId;\n this.timestamp = timestamp;\n }\n\n static fromJSON: ((json: Record<string, unknown>) => ChatEvent) | undefined;\n}\n\nexport class UnknownEvent extends ChatEvent {\n readonly data: Record<string, unknown>;\n\n constructor(type: string, threadId: string, data: Record<string, unknown>, timestamp: number) {\n super(type, threadId, timestamp);\n this.data = data;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User, Card } from \"../types\";\n\nexport class MessagePostedEvent extends ChatEvent {\n readonly messageId: string;\n readonly text: string;\n readonly author: User;\n readonly card?: Card;\n readonly attachments?: Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>;\n\n constructor(\n threadId: string,\n messageId: string,\n text: string,\n author: User,\n card?: Card,\n attachments?: Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>,\n timestamp?: number,\n ) {\n super(\"message.posted\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.text = text;\n this.author = author;\n this.card = card;\n this.attachments = attachments;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { Card } from \"../types\";\n\nexport class MessageEditedEvent extends ChatEvent {\n readonly messageId: string;\n readonly newText: string;\n readonly card?: Card;\n\n constructor(\n threadId: string,\n messageId: string,\n newText: string,\n card?: Card,\n timestamp?: number,\n ) {\n super(\"message.edited\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.newText = newText;\n this.card = card;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class MessageDeletedEvent extends ChatEvent {\n readonly messageId: string;\n\n constructor(threadId: string, messageId: string, timestamp?: number) {\n super(\"message.deleted\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User } from \"../types\";\n\nexport class ReactionAddedEvent extends ChatEvent {\n readonly messageId: string;\n readonly emoji: string;\n readonly user: User;\n\n constructor(threadId: string, messageId: string, emoji: string, user: User, timestamp?: number) {\n super(\"reaction.added\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.emoji = emoji;\n this.user = user;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User } from \"../types\";\n\nexport class ReactionRemovedEvent extends ChatEvent {\n readonly messageId: string;\n readonly emoji: string;\n readonly user: User;\n\n constructor(threadId: string, messageId: string, emoji: string, user: User, timestamp?: number) {\n super(\"reaction.removed\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.emoji = emoji;\n this.user = user;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class TypingStartedEvent extends ChatEvent {\n readonly userId: string;\n\n constructor(threadId: string, userId: string, timestamp?: number) {\n super(\"typing.started\", threadId, timestamp ?? Date.now());\n this.userId = userId;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class StreamingChunkEvent extends ChatEvent {\n readonly messageId: string;\n readonly chunk: string;\n readonly isFinal: boolean;\n\n constructor(\n threadId: string,\n messageId: string,\n chunk: string,\n isFinal: boolean,\n timestamp?: number,\n ) {\n super(\"streaming.chunk\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.chunk = chunk;\n this.isFinal = isFinal;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class DMRequestedEvent extends ChatEvent {\n readonly userId: string;\n\n constructor(threadId: string, userId: string, timestamp?: number) {\n super(\"dm.requested\", threadId, timestamp ?? Date.now());\n this.userId = userId;\n }\n}\n","import { ChatEvent, UnknownEvent } from \"./base/ChatEvent\";\nimport type { Card, User } from \"../types\";\nimport { MessagePostedEvent } from \"./MessagePostedEvent\";\nimport { MessageEditedEvent } from \"./MessageEditedEvent\";\nimport { MessageDeletedEvent } from \"./MessageDeletedEvent\";\nimport { ReactionAddedEvent } from \"./ReactionAddedEvent\";\nimport { ReactionRemovedEvent } from \"./ReactionRemovedEvent\";\nimport { TypingStartedEvent } from \"./TypingStartedEvent\";\nimport { StreamingChunkEvent } from \"./StreamingChunkEvent\";\nimport { DMRequestedEvent } from \"./DMRequestedEvent\";\n\nfunction parseCard(value: unknown): Card | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const obj = value as Record<string, unknown>;\n if (typeof obj.type !== \"string\") return undefined;\n return obj as unknown as Card;\n}\n\nexport function parseChatEvent(json: Record<string, unknown>): ChatEvent {\n const type = json.type as string;\n const threadId = json.threadId as string;\n const timestamp = json.timestamp as number;\n const data = (json.data ?? {}) as Record<string, unknown>;\n\n switch (type) {\n case \"message.posted\":\n return new MessagePostedEvent(\n threadId,\n data.messageId as string,\n data.text as string,\n data.author as User,\n parseCard(data.card),\n data.attachments as Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>,\n timestamp,\n );\n case \"message.edited\":\n return new MessageEditedEvent(\n threadId,\n data.messageId as string,\n data.newText as string,\n parseCard(data.card),\n timestamp,\n );\n case \"message.deleted\":\n return new MessageDeletedEvent(threadId, data.messageId as string, timestamp);\n case \"reaction.added\":\n return new ReactionAddedEvent(\n threadId,\n data.messageId as string,\n data.emoji as string,\n data.user as User,\n timestamp,\n );\n case \"reaction.removed\":\n return new ReactionRemovedEvent(\n threadId,\n data.messageId as string,\n data.emoji as string,\n data.user as User,\n timestamp,\n );\n case \"typing.started\":\n return new TypingStartedEvent(threadId, data.userId as string, timestamp);\n case \"streaming.chunk\":\n return new StreamingChunkEvent(\n threadId,\n data.messageId as string,\n data.chunk as string,\n data.isFinal as boolean,\n timestamp,\n );\n case \"dm.requested\":\n return new DMRequestedEvent(threadId, data.userId as string, timestamp);\n default:\n return new UnknownEvent(type, threadId, data, timestamp);\n }\n}\n\n// Wire up the static method\nChatEvent.fromJSON = parseChatEvent;\n","export function generateId(): string {\n return `msg-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\nexport function generateConversationId(): string {\n return `conv-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n","import { HttpClient } from \"./HttpClient\";\nimport type { BroadcastClient, EventHandlers, Unsubscribe } from \"./BroadcastClient\";\nimport type { Message } from \"../types\";\nimport { ChatEvent } from \"../events/base/ChatEvent\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type { MessagePostedEvent } from \"../events/MessagePostedEvent\";\nimport type { MessageEditedEvent } from \"../events/MessageEditedEvent\";\nimport type { MessageDeletedEvent } from \"../events/MessageDeletedEvent\";\nimport type { ReactionAddedEvent } from \"../events/ReactionAddedEvent\";\nimport type { ReactionRemovedEvent } from \"../events/ReactionRemovedEvent\";\nimport type { TypingStartedEvent } from \"../events/TypingStartedEvent\";\nimport type { StreamingChunkEvent } from \"../events/StreamingChunkEvent\";\nimport type { DMRequestedEvent } from \"../events/DMRequestedEvent\";\nimport { generateId, generateConversationId } from \"../utils/eventIdGenerator\";\n\nexport interface ReconfigureConfig {\n userId?: string;\n userName?: string;\n verifyToken?: string;\n conversationId?: string;\n headers?: Record<string, string>;\n}\n\nexport interface WebChatClientConfig {\n apiUrl: string;\n userId: string;\n userName: string;\n broadcastClient?: BroadcastClient;\n headers?: Record<string, string>;\n verifyToken?: string;\n conversationId?: string;\n endpoints?: {\n sendMessage?: string;\n loadMessages?: string;\n editMessage?: string;\n deleteMessage?: string;\n addReaction?: string;\n removeReaction?: string;\n };\n features?: {\n editMessages?: boolean;\n deleteMessages?: boolean;\n reactions?: boolean;\n };\n}\n\ninterface StreamingState {\n messageId: string;\n accumulatedText: string;\n isComplete: boolean;\n}\n\ninterface AttachmentInput {\n url: string;\n name?: string;\n mimeType?: string;\n size?: number;\n}\n\nexport interface LoadMessagesOptions {\n limit?: number;\n before?: number;\n after?: number;\n skipStateSeed?: boolean;\n}\n\nexport interface LoadMessagesResult {\n messages: Message[];\n hasMore: boolean;\n nextCursor?: number;\n prevCursor?: number;\n}\n\nexport class WebChatClient {\n private config: WebChatClientConfig;\n private httpClient: HttpClient;\n private broadcastClient?: BroadcastClient;\n private conversationId: string;\n private messages: Message[] = [];\n private currentUserId: string;\n private eventHandlers: EventHandlers = {};\n private streamingMessages: Map<string, StreamingState> = new Map();\n private pendingTyping: ReturnType<typeof setTimeout> | null = null;\n private subscribers: Map<string, Array<(event: unknown) => void>> = new Map();\n private unsubscribeUserChannel?: Unsubscribe;\n\n constructor(config: WebChatClientConfig) {\n this.config = config;\n this.httpClient = new HttpClient({\n apiUrl: config.apiUrl,\n headers: {\n \"X-User-Id\": config.userId,\n \"X-User-Name\": config.userName,\n ...(config.headers ?? {}),\n },\n verifyToken: config.verifyToken,\n });\n this.broadcastClient = config.broadcastClient;\n this.conversationId = config.conversationId ?? generateConversationId();\n this.currentUserId = config.userId;\n }\n\n reconfigure(config: ReconfigureConfig): void {\n if (config.userId) {\n this.currentUserId = config.userId;\n this.httpClient.setHeader(\"X-User-Id\", config.userId);\n }\n if (config.userName) {\n this.config = { ...this.config, userName: config.userName };\n this.httpClient.setHeader(\"X-User-Name\", config.userName);\n }\n if (config.verifyToken) {\n this.config = { ...this.config, verifyToken: config.verifyToken };\n this.httpClient.setHeader(\"X-Verify-Token\", config.verifyToken);\n }\n if (config.conversationId) {\n this.conversationId = config.conversationId;\n }\n if (config.headers) {\n Object.entries(config.headers).forEach(([key, value]) => {\n this.httpClient.setHeader(key, value);\n });\n }\n }\n\n setLocaleHeader(locale: string): void {\n this.httpClient.setHeader(\"X-Locale\", locale);\n this.httpClient.setHeader(\"X-Language\", locale.split(\"-\")[0] ?? locale);\n }\n\n setTimezoneHeader(timezone: string): void {\n this.httpClient.setHeader(\"X-Timezone\", timezone);\n }\n\n async connect(): Promise<void> {\n if (this.broadcastClient) {\n this.broadcastClient.connect();\n\n const threadId = this.getThreadId();\n const threadEvents: EventHandlers = {\n onMessagePosted: (event) => this.handleMessagePosted(event),\n };\n\n if (this.config.features?.editMessages) {\n threadEvents.onMessageEdited = (event) => this.handleMessageEdited(event);\n }\n if (this.config.features?.deleteMessages) {\n threadEvents.onMessageDeleted = (event) => this.handleMessageDeleted(event);\n }\n if (this.config.features?.reactions) {\n threadEvents.onReactionAdded = (event) => this.handleReactionAdded(event);\n threadEvents.onReactionRemoved = (event) => this.handleReactionRemoved(event);\n }\n\n await this.broadcastClient.subscribe(threadId, threadEvents);\n\n this.unsubscribeUserChannel = await this.broadcastClient.subscribeToUser(\n threadId,\n this.currentUserId,\n {\n onTypingStarted: (event) => this.handleTypingStarted(event),\n onStreamingChunk: (event) => this.handleStreamingChunk(event),\n onDMRequested: (event) => this.handleDMRequested(event),\n },\n );\n }\n }\n\n disconnect(): void {\n this.unsubscribeUserChannel?.();\n this.unsubscribeUserChannel = undefined;\n this.broadcastClient?.disconnect();\n this.streamingMessages.clear();\n }\n\n async loadMessages(\n options?: LoadMessagesOptions,\n signal?: AbortSignal,\n ): Promise<LoadMessagesResult> {\n const endpoint = this.config.endpoints?.loadMessages ?? \"/api/chat/messages\";\n const threadId = this.getThreadId();\n const params = new URLSearchParams({\n threadId,\n limit: String(options?.limit ?? 50),\n });\n if (options?.before) params.set(\"before\", String(options.before));\n if (options?.after) params.set(\"after\", String(options.after));\n\n const response = (await this.httpClient.get(\n `${endpoint}?${params.toString()}`,\n signal,\n )) as Record<string, unknown>;\n const rawMessages = (response.messages as Record<string, unknown>[]) ?? [];\n const messages: Message[] = rawMessages.map((msg) => ({\n id: msg.id as string,\n threadId,\n content: {\n text: msg.text as string,\n cards: msg.card ? ([msg.card as Record<string, unknown>] as never[]) : undefined,\n },\n author: {\n id: (msg.author as Record<string, unknown>).id as string,\n name: (msg.author as Record<string, unknown>).name as string,\n isBot: ((msg.author as Record<string, unknown>).isBot as boolean) ?? false,\n isMe: (msg.author as Record<string, unknown>).id === this.currentUserId,\n },\n timestamp: msg.timestamp as number,\n attachments: (msg.attachments as Record<string, unknown>[])?.map((a) => ({\n id: `att-${msg.id as string}-${a.url as string}`,\n url: a.url as string,\n name: a.name as string,\n type: a.type as string,\n mimeType: a.mime_type as string,\n size: a.size as number,\n })),\n reactions: (msg.reactions as { emoji: string; count: number; users: string[] }[]) ?? [],\n }));\n\n if (!options?.before && !options?.after && !options?.skipStateSeed) {\n this.messages = messages;\n this.notifySubscribers(\"messages:loaded\", messages);\n }\n\n return {\n messages,\n hasMore: (response.hasMore as boolean) ?? false,\n nextCursor: response.nextCursor as number | undefined,\n prevCursor: response.prevCursor as number | undefined,\n };\n }\n\n async sendMessage(text: string, attachments: AttachmentInput[] = []): Promise<void> {\n const messageId = generateId();\n\n const userMessage: Message = {\n id: messageId,\n threadId: this.getThreadId(),\n content: { text },\n author: { id: this.currentUserId, name: this.config.userName, isMe: true },\n timestamp: Date.now(),\n attachments:\n attachments.length > 0\n ? attachments.map((a, i) => ({\n id: `att-${messageId}-${i}`,\n name: a.name ?? \"\",\n url: a.url,\n size: a.size,\n mimeType: a.mimeType,\n }))\n : undefined,\n };\n\n this.messages.push(userMessage);\n this.notifySubscribers(\"message:added\", userMessage);\n\n const endpoint = this.config.endpoints?.sendMessage ?? \"/api/webhooks/web\";\n const response = await this.httpClient.sendMessage(\n [\n {\n id: messageId,\n role: \"user\",\n text,\n attachments: attachments.map((a) => ({\n url: a.url,\n name: a.name,\n mime_type: a.mimeType,\n size: a.size,\n })),\n },\n ],\n endpoint,\n this.conversationId,\n );\n\n if (response.events) {\n response.events.forEach((eventData) => {\n const event = parseChatEvent(eventData);\n this.dispatchEvent(event);\n });\n }\n\n if (response.text && !response.events?.some((e) => e.type === \"message.posted\")) {\n const assistantMessage: Message = {\n id: response.id ?? generateId(),\n threadId: this.getThreadId(),\n content: { text: response.text },\n author: { id: \"assistant\", name: \"Assistant\", isBot: true },\n timestamp: Date.now(),\n attachments: (response.attachments as Record<string, unknown>[])?.map((a, i) => ({\n id: `att-${response.id ?? \"msg\"}-${i}`,\n name: (a.name as string) ?? \"\",\n url: (a.url as string) ?? \"\",\n type: a.type as string,\n mimeType: a.mime_type as string,\n size: a.size as number,\n })),\n };\n this.messages.push(assistantMessage);\n this.notifySubscribers(\"message:added\", assistantMessage);\n }\n }\n\n async sendAction(messageId: string, actionId: string, value: string): Promise<void> {\n const endpoint = this.config.endpoints?.sendMessage ?? \"/api/webhooks/web\";\n const response = await this.httpClient.sendAction(\n actionId,\n value,\n messageId,\n this.conversationId,\n endpoint,\n );\n\n if (response.events) {\n (response.events as Array<Record<string, unknown>>).forEach((eventData) => {\n const event = parseChatEvent(eventData);\n this.dispatchEvent(event);\n });\n }\n }\n\n async editMessage(messageId: string, newText: string): Promise<void> {\n if (!this.config.features?.editMessages) {\n throw new Error(\"Edit messages not enabled. Set features.editMessages = true in config.\");\n }\n const endpoint = this.config.endpoints?.editMessage ?? \"/api/chat/messages/{id}/edit\";\n await this.httpClient.editMessage(messageId, newText, endpoint);\n }\n\n async deleteMessage(messageId: string): Promise<void> {\n if (!this.config.features?.deleteMessages) {\n throw new Error(\"Delete messages not enabled. Set features.deleteMessages = true in config.\");\n }\n const endpoint = this.config.endpoints?.deleteMessage ?? \"/api/chat/messages/{id}\";\n await this.httpClient.deleteMessage(messageId, endpoint);\n }\n\n async addReaction(messageId: string, emoji: string): Promise<void> {\n if (!this.config.features?.reactions) {\n throw new Error(\"Reactions not enabled. Set features.reactions = true in config.\");\n }\n const endpoint = this.config.endpoints?.addReaction ?? \"/api/chat/messages/{id}/reactions\";\n await this.httpClient.addReaction(messageId, emoji, endpoint);\n }\n\n async removeReaction(messageId: string, emoji: string): Promise<void> {\n if (!this.config.features?.reactions) {\n throw new Error(\"Reactions not enabled. Set features.reactions = true in config.\");\n }\n const endpoint =\n this.config.endpoints?.removeReaction ?? \"/api/chat/messages/{id}/reactions/{emoji}\";\n await this.httpClient.removeReaction(messageId, emoji, endpoint);\n }\n\n onMessagePosted(handler: (event: MessagePostedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message.posted\", handler);\n }\n\n onMessageEdited(handler: (event: MessageEditedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message:edited\", handler);\n }\n\n onMessageDeleted(handler: (event: MessageDeletedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message:deleted\", handler);\n }\n\n onReactionAdded(handler: (event: ReactionAddedEvent) => void): Unsubscribe {\n return this.addEventListener(\"reaction:added\", handler);\n }\n\n onReactionRemoved(handler: (event: ReactionRemovedEvent) => void): Unsubscribe {\n return this.addEventListener(\"reaction:removed\", handler);\n }\n\n onStreamingChunk(handler: (event: StreamingChunkEvent) => void): Unsubscribe {\n return this.addEventListener(\"streaming:chunk\", handler);\n }\n\n onTypingStarted(handler: (event: TypingStartedEvent) => void): Unsubscribe {\n return this.addEventListener(\"typing:started\", handler);\n }\n\n getConversationId(): string {\n return this.conversationId;\n }\n getMessages(): Message[] {\n return [...this.messages];\n }\n getThreadId(): string {\n return `web:${this.currentUserId}:${this.conversationId}`;\n }\n getCurrentUserId(): string {\n return this.currentUserId;\n }\n getFeatures(): NonNullable<WebChatClientConfig[\"features\"]> {\n return this.config.features ?? {};\n }\n getEndpoints(): NonNullable<WebChatClientConfig[\"endpoints\"]> {\n return this.config.endpoints ?? {};\n }\n getHttpClient(): HttpClient {\n return this.httpClient;\n }\n\n addEventListener<T = unknown>(eventType: string, handler: (event: T) => void): Unsubscribe {\n if (!this.subscribers.has(eventType)) this.subscribers.set(eventType, []);\n this.subscribers.get(eventType)!.push(handler as (event: unknown) => void);\n return () => {\n const handlers = this.subscribers.get(eventType);\n if (handlers) {\n const index = handlers.indexOf(handler as (event: unknown) => void);\n if (index !== -1) handlers.splice(index, 1);\n }\n };\n }\n\n private handleMessagePosted(event: MessagePostedEvent): void {\n if (this.messages.some((m) => m.id === event.messageId)) return;\n if (this.streamingMessages.has(event.messageId)) return;\n\n const message: Message = {\n id: event.messageId,\n threadId: event.threadId,\n content: { text: event.text, cards: event.card ? [event.card] : undefined },\n author: event.author,\n timestamp: event.timestamp,\n attachments: event.attachments?.map((a) => ({\n id: `att-${event.messageId}-${Math.random().toString(36).slice(2, 8)}`,\n name: a.name ?? \"\",\n url: a.url ?? \"\",\n type: a.type,\n mimeType: a.mimeType,\n size: a.size ?? undefined,\n })),\n };\n this.messages.push(message);\n this.notifySubscribers(\"message:added\", message);\n this.notifySubscribers(\"message.posted\", event);\n }\n\n private handleMessageEdited(event: MessageEditedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (message?.content) {\n message.content.text = event.newText;\n this.notifySubscribers(\"message:edited\", event);\n }\n }\n\n private handleMessageDeleted(event: MessageDeletedEvent): void {\n const index = this.messages.findIndex((m) => m.id === event.messageId);\n if (index !== -1) {\n this.messages.splice(index, 1);\n this.notifySubscribers(\"message:deleted\", event);\n }\n }\n\n private handleReactionAdded(event: ReactionAddedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (!message) return;\n if (!message.reactions) message.reactions = [];\n\n const existing = message.reactions.find((r) => r.emoji === event.emoji);\n if (existing) {\n existing.count++;\n existing.users.push(event.user.id);\n } else {\n message.reactions.push({ emoji: event.emoji, count: 1, users: [event.user.id] });\n }\n this.notifySubscribers(\"reaction:added\", event);\n }\n\n private handleReactionRemoved(event: ReactionRemovedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (!message?.reactions) return;\n\n const index = message.reactions.findIndex((r) => r.emoji === event.emoji);\n if (index !== -1) {\n const reaction = message.reactions[index]!;\n reaction.count--;\n reaction.users = reaction.users.filter((id) => id !== event.user.id);\n if (reaction.count === 0) message.reactions.splice(index, 1);\n }\n this.notifySubscribers(\"reaction:removed\", event);\n }\n\n private handleStreamingChunk(event: StreamingChunkEvent): void {\n const { messageId, chunk, isFinal } = event;\n\n if (!this.streamingMessages.has(messageId)) {\n this.streamingMessages.set(messageId, { messageId, accumulatedText: \"\", isComplete: false });\n this.notifySubscribers(\"streaming:started\", event);\n }\n\n const state = this.streamingMessages.get(messageId)!;\n state.accumulatedText += chunk;\n\n if (isFinal) {\n state.isComplete = true;\n if (!this.messages.some((m) => m.id === messageId)) {\n const message: Message = {\n id: messageId,\n threadId: event.threadId,\n content: { text: state.accumulatedText },\n author: { id: \"assistant\", name: \"Assistant\", isBot: true },\n timestamp: event.timestamp,\n };\n this.messages.push(message);\n this.notifySubscribers(\"message:added\", message);\n }\n this.streamingMessages.delete(messageId);\n this.notifySubscribers(\"streaming:complete\", { messageId, text: state.accumulatedText });\n } else {\n this.notifySubscribers(\"streaming:chunk\", event);\n }\n }\n\n private handleTypingStarted(event: TypingStartedEvent): void {\n if (this.pendingTyping) clearTimeout(this.pendingTyping);\n this.notifySubscribers(\"typing:started\", event);\n this.pendingTyping = setTimeout(() => {\n this.notifySubscribers(\"typing:stopped\", { userId: event.userId });\n }, 3000);\n }\n\n private handleDMRequested(event: DMRequestedEvent): void {\n this.notifySubscribers(\"dm.requested\", event);\n }\n\n private notifySubscribers<T>(eventType: string, data: T): void {\n this.subscribers.get(eventType)?.forEach((handler) => handler(data));\n }\n\n private dispatchEvent(event: ChatEvent): void {\n switch (event.type) {\n case \"message.posted\":\n this.handleMessagePosted(event as MessagePostedEvent);\n break;\n case \"message.edited\":\n this.handleMessageEdited(event as MessageEditedEvent);\n break;\n case \"message.deleted\":\n this.handleMessageDeleted(event as MessageDeletedEvent);\n break;\n case \"reaction.added\":\n this.handleReactionAdded(event as ReactionAddedEvent);\n break;\n case \"reaction.removed\":\n this.handleReactionRemoved(event as ReactionRemovedEvent);\n break;\n case \"typing.started\":\n this.handleTypingStarted(event as TypingStartedEvent);\n break;\n case \"streaming.chunk\":\n this.handleStreamingChunk(event as StreamingChunkEvent);\n break;\n case \"dm.requested\":\n this.handleDMRequested(event as DMRequestedEvent);\n break;\n }\n }\n}\n","import {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./BroadcastClient\";\nimport { ChatEvent } from \"../events/base/ChatEvent\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type Pusher from \"pusher-js\";\nimport type { Channel as PusherChannel } from \"pusher-js\";\n\nexport interface PusherConfig {\n key: string;\n cluster?: string;\n host?: string;\n port?: number;\n forceTLS?: boolean;\n authEndpoint?: string;\n}\n\nexport class PusherBroadcastClient implements BroadcastClient {\n private pusher: Pusher;\n private channelPrefix: string;\n private threadChannelType: \"public\" | \"private\" | \"presence\";\n private userChannelType: \"private\" | \"presence\";\n private useHashChannel: boolean;\n private subscriptions: Map<string, PusherChannel> = new Map();\n\n constructor(pusher: Pusher, channelPrefix?: string, channelTypes?: ChannelTypeConfig);\n constructor(config: PusherConfig, channelPrefix?: string, channelTypes?: ChannelTypeConfig);\n constructor(\n pusherOrConfig: Pusher | PusherConfig,\n channelPrefix: string = \"chat\",\n channelTypes?: ChannelTypeConfig,\n ) {\n this.channelPrefix = channelPrefix;\n this.threadChannelType = channelTypes?.threadChannel ?? \"public\";\n this.userChannelType = channelTypes?.userChannel ?? \"private\";\n this.useHashChannel = channelTypes?.useHashChannel ?? false;\n\n if (\"key\" in pusherOrConfig) {\n const PusherCtor = (globalThis as any).Pusher ?? (globalThis as any).pusherJs;\n if (!PusherCtor) {\n throw new Error(\"pusher-js not found. Install it or pass a Pusher instance.\");\n }\n this.pusher = new PusherCtor((pusherOrConfig as PusherConfig).key, pusherOrConfig) as Pusher;\n } else {\n this.pusher = pusherOrConfig as Pusher;\n }\n }\n\n private buildChannelName(base: string, type: \"public\" | \"private\" | \"presence\"): string {\n switch (type) {\n case \"private\":\n return `private-${base}`;\n case \"presence\":\n return `presence-${base}`;\n default:\n return base;\n }\n }\n\n protected async buildResolvedChannelName(threadId: string): Promise<string> {\n const name = this.useHashChannel ? await this.hashChannelName(threadId) : threadId;\n\n return `${this.channelPrefix}.${name}`;\n }\n\n private async hashChannelName(name: string): Promise<string> {\n if (typeof crypto?.subtle?.digest !== \"function\") {\n throw new Error(\"Web Crypto API not available. Cannot hash channel names.\");\n }\n const encoder = new TextEncoder();\n const data = encoder.encode(name);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n\n connect(): void {\n if (this.pusher.connection?.state !== \"connected\") {\n this.pusher.connect();\n }\n }\n\n disconnect(): void {\n this.subscriptions.forEach((channel) => channel.unbind_all?.() ?? channel.unsubscribe?.());\n this.subscriptions.clear();\n this.pusher.disconnect?.();\n }\n\n async subscribe(threadId: string, handlers: EventHandlers): Promise<Unsubscribe> {\n const baseName = await this.buildResolvedChannelName(threadId);\n const channelName = this.buildChannelName(baseName, this.threadChannelType);\n const channel = this.pusher.subscribe(channelName);\n const key = `thread:${threadId}`;\n this.subscriptions.set(key, channel);\n\n const threadEvents = [\n \"message.posted\",\n \"message.edited\",\n \"message.deleted\",\n \"reaction.added\",\n \"reaction.removed\",\n ] as const;\n\n threadEvents.forEach((eventType) => {\n const eventName = `${this.channelPrefix}.${eventType}`;\n channel.bind(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n this.dispatchToHandler(event, handlers);\n });\n });\n\n return () => {\n channel.unbind_all?.();\n this.pusher.unsubscribe(channelName);\n this.subscriptions.delete(key);\n };\n }\n\n async subscribeToUser(\n threadId: string,\n userId: string,\n handlers: EventHandlers,\n ): Promise<Unsubscribe> {\n const baseName = `${await this.buildResolvedChannelName(threadId)}.${userId}`;\n const channelName = this.buildChannelName(baseName, this.userChannelType);\n const channel = this.pusher.subscribe(channelName);\n const key = `user:${threadId}:${userId}`;\n this.subscriptions.set(key, channel);\n\n const userEvents = [\"typing.started\", \"streaming.chunk\", \"dm.requested\"] as const;\n\n userEvents.forEach((eventType) => {\n const eventName = `${this.channelPrefix}.${eventType}`;\n channel.bind(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n this.dispatchToHandler(event, handlers);\n });\n });\n\n return () => {\n channel.unbind_all?.();\n this.pusher.unsubscribe(channelName);\n this.subscriptions.delete(key);\n };\n }\n\n isConnected(): boolean {\n return this.pusher.connection?.state === \"connected\";\n }\n\n private dispatchToHandler(event: ChatEvent, handlers: EventHandlers): void {\n switch (event.type) {\n case \"message.posted\":\n handlers.onMessagePosted?.(event as any);\n break;\n case \"message.edited\":\n handlers.onMessageEdited?.(event as any);\n break;\n case \"message.deleted\":\n handlers.onMessageDeleted?.(event as any);\n break;\n case \"reaction.added\":\n handlers.onReactionAdded?.(event as any);\n break;\n case \"reaction.removed\":\n handlers.onReactionRemoved?.(event as any);\n break;\n case \"typing.started\":\n handlers.onTypingStarted?.(event as any);\n break;\n case \"streaming.chunk\":\n handlers.onStreamingChunk?.(event as any);\n break;\n case \"dm.requested\":\n handlers.onDMRequested?.(event as any);\n break;\n }\n }\n}\n","import {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./BroadcastClient\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type Echo from \"laravel-echo\";\n\ninterface EchoChannel {\n listen(event: string, callback: (data: unknown) => void): this;\n unsubscribe(): void;\n stopListening(event?: string, callback?: (data: unknown) => void): this;\n}\n\nexport class LaravelEchoBroadcastClient implements BroadcastClient {\n private echo: Echo<any>;\n private channelPrefix: string;\n private threadChannelType: \"public\" | \"private\" | \"presence\";\n private userChannelType: \"private\" | \"presence\";\n private useHashChannel: boolean;\n private subscriptions: Map<string, EchoChannel> = new Map();\n\n constructor(echo: Echo<any>, channelPrefix: string = \"chat\", channelTypes?: ChannelTypeConfig) {\n this.echo = echo;\n this.channelPrefix = channelPrefix;\n this.threadChannelType = channelTypes?.threadChannel ?? \"public\";\n this.userChannelType = channelTypes?.userChannel ?? \"private\";\n this.useHashChannel = channelTypes?.useHashChannel ?? false;\n }\n\n private subscribeToEcho(name: string, type: \"public\" | \"private\" | \"presence\"): EchoChannel {\n switch (type) {\n case \"private\":\n return this.echo.private(name) as unknown as EchoChannel;\n case \"presence\":\n return this.echo.join(name) as unknown as EchoChannel;\n default:\n return this.echo.channel(name) as unknown as EchoChannel;\n }\n }\n\n connect(): void | Promise<void> {\n return Promise.resolve();\n }\n\n disconnect(): void {\n this.subscriptions.forEach((channel) => {\n channel.unsubscribe?.();\n channel.stopListening?.();\n });\n this.subscriptions.clear();\n }\n\n protected async buildResolvedChannelName(threadId: string): Promise<string> {\n const name = this.useHashChannel ? await this.hashChannelName(threadId) : threadId;\n\n return `${this.channelPrefix}.${name}`;\n }\n\n private async hashChannelName(name: string): Promise<string> {\n if (typeof crypto?.subtle?.digest !== \"function\") {\n throw new Error(\"Web Crypto API not available. Cannot hash channel names.\");\n }\n const encoder = new TextEncoder();\n const data = encoder.encode(name);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n\n async subscribe(threadId: string, handlers: EventHandlers): Promise<Unsubscribe> {\n const channelName = await this.buildResolvedChannelName(threadId);\n const channel = this.subscribeToEcho(channelName, this.threadChannelType);\n const key = `thread:${threadId}`;\n this.subscriptions.set(key, channel);\n\n const threadEvents: Array<{ type: string; handler: keyof EventHandlers }> = [\n { type: \"message.posted\", handler: \"onMessagePosted\" },\n { type: \"message.edited\", handler: \"onMessageEdited\" },\n { type: \"message.deleted\", handler: \"onMessageDeleted\" },\n { type: \"reaction.added\", handler: \"onReactionAdded\" },\n { type: \"reaction.removed\", handler: \"onReactionRemoved\" },\n ];\n\n threadEvents.forEach(({ type, handler }) => {\n const eventName = `.${this.channelPrefix}.${type}`;\n channel.listen(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n (handlers[handler] as any)?.(event);\n });\n });\n\n return () => {\n channel.unsubscribe?.();\n this.subscriptions.delete(key);\n };\n }\n\n async subscribeToUser(\n threadId: string,\n userId: string,\n handlers: EventHandlers,\n ): Promise<Unsubscribe> {\n const channelName = `${await this.buildResolvedChannelName(threadId)}.${userId}`;\n const channel = this.subscribeToEcho(channelName, this.userChannelType);\n const key = `user:${threadId}:${userId}`;\n this.subscriptions.set(key, channel);\n\n const userEvents: Array<{ type: string; handler: keyof EventHandlers }> = [\n { type: \"typing.started\", handler: \"onTypingStarted\" },\n { type: \"streaming.chunk\", handler: \"onStreamingChunk\" },\n { type: \"dm.requested\", handler: \"onDMRequested\" },\n ];\n\n userEvents.forEach(({ type, handler }) => {\n const eventName = `.${this.channelPrefix}.${type}`;\n channel.listen(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n (handlers[handler] as any)?.(event);\n });\n });\n\n return () => {\n channel.unsubscribe?.();\n this.subscriptions.delete(key);\n };\n }\n\n isConnected(): boolean {\n try {\n const connector = (this.echo as any).connector;\n if (!connector) return false;\n\n if (connector.pusher?.connection?.state === \"connected\") return true;\n if (connector.socket?.connected) return true;\n\n return false;\n } catch {\n return false;\n }\n }\n}\n","import type { PushConfig, PushSubscriptionStatus, PushEventData } from \"./types\";\n\nexport class PushManager {\n private config: PushConfig;\n private registration: ServiceWorkerRegistration | null = null;\n private status: PushSubscriptionStatus = \"unsupported\";\n private statusListeners: Set<(status: PushSubscriptionStatus) => void> = new Set();\n private messageListeners: Set<(data: PushEventData) => void> = new Set();\n\n constructor(config: PushConfig) {\n this.config = config;\n }\n\n static isSupported(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n \"serviceWorker\" in navigator &&\n \"PushManager\" in window &&\n \"Notification\" in window\n );\n }\n\n getStatus(): PushSubscriptionStatus {\n return this.status;\n }\n\n onStatusChange(listener: (status: PushSubscriptionStatus) => void): () => void {\n this.statusListeners.add(listener);\n return () => {\n this.statusListeners.delete(listener);\n };\n }\n\n onMessage(listener: (data: PushEventData) => void): () => void {\n this.messageListeners.add(listener);\n return () => {\n this.messageListeners.delete(listener);\n };\n }\n\n async initialize(): Promise<void> {\n if (!PushManager.isSupported()) {\n this.setStatus(\"unsupported\");\n return;\n }\n if (Notification.permission === \"denied\") {\n this.setStatus(\"denied\");\n return;\n }\n\n try {\n this.registration = await navigator.serviceWorker.register(\n this.config.serviceWorkerUrl || \"/chat-service-worker.js\",\n {\n scope: this.config.serviceWorkerScope || \"/\",\n type: this.config.serviceWorkerType,\n },\n );\n await navigator.serviceWorker.ready;\n\n navigator.serviceWorker.addEventListener(\"message\", (event: MessageEvent) => {\n const msg = event.data as Record<string, unknown>;\n if (msg?.type === \"chat-widget:push-data\") {\n const pushData = msg.data as PushEventData;\n this.messageListeners.forEach((listener) => listener(pushData));\n }\n });\n\n const subscription = await this.registration.pushManager.getSubscription();\n this.setStatus(subscription ? \"subscribed\" : \"default\");\n } catch {\n this.setStatus(\"error\");\n }\n }\n\n async subscribe(): Promise<void> {\n if (!this.registration)\n throw new Error(\"PushManager not initialized. Call initialize() first.\");\n\n this.setStatus(\"subscribing\");\n\n try {\n let subscription = await this.registration.pushManager.getSubscription();\n\n if (!subscription) {\n const permission = await Notification.requestPermission();\n if (permission !== \"granted\") {\n this.setStatus(permission === \"denied\" ? \"denied\" : \"default\");\n return;\n }\n\n const vapidPublicKey = await this.config.getVapidPublicKey();\n const convertedKey = this.urlBase64ToUint8Array(vapidPublicKey);\n subscription = await this.registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: convertedKey.buffer as ArrayBuffer,\n });\n }\n\n await this.config.onSubscribe(subscription.toJSON());\n this.setStatus(\"subscribed\");\n } catch {\n this.setStatus(\"error\");\n throw new Error(\"Push subscription failed\");\n }\n }\n\n async unsubscribe(): Promise<void> {\n if (!this.registration) return;\n\n try {\n const subscription = await this.registration.pushManager.getSubscription();\n if (subscription) {\n await this.config.onUnsubscribe(subscription.toJSON());\n await subscription.unsubscribe();\n }\n this.setStatus(\"default\");\n } catch {\n this.setStatus(\"error\");\n throw new Error(\"Push unsubscription failed\");\n }\n }\n\n private urlBase64ToUint8Array(base64String: string): Uint8Array {\n const padding = \"=\".repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding).replace(/-/g, \"+\").replace(/_/g, \"/\");\n const rawData = atob(base64);\n return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0)));\n }\n\n private setStatus(status: PushSubscriptionStatus): void {\n this.status = status;\n this.statusListeners.forEach((listener) => listener(status));\n }\n}\n","import { HttpClient } from \"../client/HttpClient\";\nimport type { PushConfig } from \"./types\";\n\nexport function createPushSubscriptionHandlers(\n httpClient: HttpClient,\n userId: string,\n): Pick<PushConfig, \"onSubscribe\" | \"onUnsubscribe\"> {\n return {\n onSubscribe: async (subscription: PushSubscriptionJSON) => {\n await httpClient.post(\"/api/push/subscriptions\", {\n userId,\n subscription,\n userAgent: navigator.userAgent,\n });\n },\n onUnsubscribe: async (subscription: PushSubscriptionJSON) => {\n await httpClient.delete(\n `/api/push/subscriptions?userId=${encodeURIComponent(userId)}&endpoint=${encodeURIComponent(subscription.endpoint || \"\")}`,\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -257,12 +257,13 @@ type Unsubscribe = () => void;
|
|
|
257
257
|
interface ChannelTypeConfig {
|
|
258
258
|
threadChannel?: "public" | "private" | "presence";
|
|
259
259
|
userChannel?: "private" | "presence";
|
|
260
|
+
useHashChannel?: boolean;
|
|
260
261
|
}
|
|
261
262
|
interface BroadcastClient {
|
|
262
263
|
connect(): void | Promise<void>;
|
|
263
264
|
disconnect(): void;
|
|
264
|
-
subscribe(threadId: string, handlers: EventHandlers): Unsubscribe
|
|
265
|
-
subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Unsubscribe
|
|
265
|
+
subscribe(threadId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
266
|
+
subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
266
267
|
isConnected(): boolean;
|
|
267
268
|
}
|
|
268
269
|
|
|
@@ -378,14 +379,17 @@ declare class PusherBroadcastClient implements BroadcastClient {
|
|
|
378
379
|
private channelPrefix;
|
|
379
380
|
private threadChannelType;
|
|
380
381
|
private userChannelType;
|
|
382
|
+
private useHashChannel;
|
|
381
383
|
private subscriptions;
|
|
382
384
|
constructor(pusher: Pusher, channelPrefix?: string, channelTypes?: ChannelTypeConfig);
|
|
383
385
|
constructor(config: PusherConfig, channelPrefix?: string, channelTypes?: ChannelTypeConfig);
|
|
384
386
|
private buildChannelName;
|
|
387
|
+
protected buildResolvedChannelName(threadId: string): Promise<string>;
|
|
388
|
+
private hashChannelName;
|
|
385
389
|
connect(): void;
|
|
386
390
|
disconnect(): void;
|
|
387
|
-
subscribe(threadId: string, handlers: EventHandlers): Unsubscribe
|
|
388
|
-
subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Unsubscribe
|
|
391
|
+
subscribe(threadId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
392
|
+
subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
389
393
|
isConnected(): boolean;
|
|
390
394
|
private dispatchToHandler;
|
|
391
395
|
}
|
|
@@ -395,13 +399,16 @@ declare class LaravelEchoBroadcastClient implements BroadcastClient {
|
|
|
395
399
|
private channelPrefix;
|
|
396
400
|
private threadChannelType;
|
|
397
401
|
private userChannelType;
|
|
402
|
+
private useHashChannel;
|
|
398
403
|
private subscriptions;
|
|
399
404
|
constructor(echo: Echo<any>, channelPrefix?: string, channelTypes?: ChannelTypeConfig);
|
|
400
405
|
private subscribeToEcho;
|
|
401
406
|
connect(): void | Promise<void>;
|
|
402
407
|
disconnect(): void;
|
|
403
|
-
|
|
404
|
-
|
|
408
|
+
protected buildResolvedChannelName(threadId: string): Promise<string>;
|
|
409
|
+
private hashChannelName;
|
|
410
|
+
subscribe(threadId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
411
|
+
subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
405
412
|
isConnected(): boolean;
|
|
406
413
|
}
|
|
407
414
|
|
package/dist/index.d.ts
CHANGED
|
@@ -257,12 +257,13 @@ type Unsubscribe = () => void;
|
|
|
257
257
|
interface ChannelTypeConfig {
|
|
258
258
|
threadChannel?: "public" | "private" | "presence";
|
|
259
259
|
userChannel?: "private" | "presence";
|
|
260
|
+
useHashChannel?: boolean;
|
|
260
261
|
}
|
|
261
262
|
interface BroadcastClient {
|
|
262
263
|
connect(): void | Promise<void>;
|
|
263
264
|
disconnect(): void;
|
|
264
|
-
subscribe(threadId: string, handlers: EventHandlers): Unsubscribe
|
|
265
|
-
subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Unsubscribe
|
|
265
|
+
subscribe(threadId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
266
|
+
subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
266
267
|
isConnected(): boolean;
|
|
267
268
|
}
|
|
268
269
|
|
|
@@ -378,14 +379,17 @@ declare class PusherBroadcastClient implements BroadcastClient {
|
|
|
378
379
|
private channelPrefix;
|
|
379
380
|
private threadChannelType;
|
|
380
381
|
private userChannelType;
|
|
382
|
+
private useHashChannel;
|
|
381
383
|
private subscriptions;
|
|
382
384
|
constructor(pusher: Pusher, channelPrefix?: string, channelTypes?: ChannelTypeConfig);
|
|
383
385
|
constructor(config: PusherConfig, channelPrefix?: string, channelTypes?: ChannelTypeConfig);
|
|
384
386
|
private buildChannelName;
|
|
387
|
+
protected buildResolvedChannelName(threadId: string): Promise<string>;
|
|
388
|
+
private hashChannelName;
|
|
385
389
|
connect(): void;
|
|
386
390
|
disconnect(): void;
|
|
387
|
-
subscribe(threadId: string, handlers: EventHandlers): Unsubscribe
|
|
388
|
-
subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Unsubscribe
|
|
391
|
+
subscribe(threadId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
392
|
+
subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
389
393
|
isConnected(): boolean;
|
|
390
394
|
private dispatchToHandler;
|
|
391
395
|
}
|
|
@@ -395,13 +399,16 @@ declare class LaravelEchoBroadcastClient implements BroadcastClient {
|
|
|
395
399
|
private channelPrefix;
|
|
396
400
|
private threadChannelType;
|
|
397
401
|
private userChannelType;
|
|
402
|
+
private useHashChannel;
|
|
398
403
|
private subscriptions;
|
|
399
404
|
constructor(echo: Echo<any>, channelPrefix?: string, channelTypes?: ChannelTypeConfig);
|
|
400
405
|
private subscribeToEcho;
|
|
401
406
|
connect(): void | Promise<void>;
|
|
402
407
|
disconnect(): void;
|
|
403
|
-
|
|
404
|
-
|
|
408
|
+
protected buildResolvedChannelName(threadId: string): Promise<string>;
|
|
409
|
+
private hashChannelName;
|
|
410
|
+
subscribe(threadId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
411
|
+
subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Promise<Unsubscribe>;
|
|
405
412
|
isConnected(): boolean;
|
|
406
413
|
}
|
|
407
414
|
|
package/dist/index.js
CHANGED
|
@@ -355,8 +355,8 @@ var WebChatClient = class {
|
|
|
355
355
|
threadEvents.onReactionAdded = (event) => this.handleReactionAdded(event);
|
|
356
356
|
threadEvents.onReactionRemoved = (event) => this.handleReactionRemoved(event);
|
|
357
357
|
}
|
|
358
|
-
this.broadcastClient.subscribe(threadId, threadEvents);
|
|
359
|
-
this.unsubscribeUserChannel = this.broadcastClient.subscribeToUser(
|
|
358
|
+
await this.broadcastClient.subscribe(threadId, threadEvents);
|
|
359
|
+
this.unsubscribeUserChannel = await this.broadcastClient.subscribeToUser(
|
|
360
360
|
threadId,
|
|
361
361
|
this.currentUserId,
|
|
362
362
|
{
|
|
@@ -719,6 +719,7 @@ var PusherBroadcastClient = class {
|
|
|
719
719
|
this.channelPrefix = channelPrefix;
|
|
720
720
|
this.threadChannelType = channelTypes?.threadChannel ?? "public";
|
|
721
721
|
this.userChannelType = channelTypes?.userChannel ?? "private";
|
|
722
|
+
this.useHashChannel = channelTypes?.useHashChannel ?? false;
|
|
722
723
|
if ("key" in pusherOrConfig) {
|
|
723
724
|
const PusherCtor = globalThis.Pusher ?? globalThis.pusherJs;
|
|
724
725
|
if (!PusherCtor) {
|
|
@@ -739,6 +740,20 @@ var PusherBroadcastClient = class {
|
|
|
739
740
|
return base;
|
|
740
741
|
}
|
|
741
742
|
}
|
|
743
|
+
async buildResolvedChannelName(threadId) {
|
|
744
|
+
const name = this.useHashChannel ? await this.hashChannelName(threadId) : threadId;
|
|
745
|
+
return `${this.channelPrefix}.${name}`;
|
|
746
|
+
}
|
|
747
|
+
async hashChannelName(name) {
|
|
748
|
+
if (typeof crypto?.subtle?.digest !== "function") {
|
|
749
|
+
throw new Error("Web Crypto API not available. Cannot hash channel names.");
|
|
750
|
+
}
|
|
751
|
+
const encoder = new TextEncoder();
|
|
752
|
+
const data = encoder.encode(name);
|
|
753
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
754
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
755
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
756
|
+
}
|
|
742
757
|
connect() {
|
|
743
758
|
if (this.pusher.connection?.state !== "connected") {
|
|
744
759
|
this.pusher.connect();
|
|
@@ -749,8 +764,8 @@ var PusherBroadcastClient = class {
|
|
|
749
764
|
this.subscriptions.clear();
|
|
750
765
|
this.pusher.disconnect?.();
|
|
751
766
|
}
|
|
752
|
-
subscribe(threadId, handlers) {
|
|
753
|
-
const baseName =
|
|
767
|
+
async subscribe(threadId, handlers) {
|
|
768
|
+
const baseName = await this.buildResolvedChannelName(threadId);
|
|
754
769
|
const channelName = this.buildChannelName(baseName, this.threadChannelType);
|
|
755
770
|
const channel = this.pusher.subscribe(channelName);
|
|
756
771
|
const key = `thread:${threadId}`;
|
|
@@ -775,8 +790,8 @@ var PusherBroadcastClient = class {
|
|
|
775
790
|
this.subscriptions.delete(key);
|
|
776
791
|
};
|
|
777
792
|
}
|
|
778
|
-
subscribeToUser(threadId, userId, handlers) {
|
|
779
|
-
const baseName = `${this.
|
|
793
|
+
async subscribeToUser(threadId, userId, handlers) {
|
|
794
|
+
const baseName = `${await this.buildResolvedChannelName(threadId)}.${userId}`;
|
|
780
795
|
const channelName = this.buildChannelName(baseName, this.userChannelType);
|
|
781
796
|
const channel = this.pusher.subscribe(channelName);
|
|
782
797
|
const key = `user:${threadId}:${userId}`;
|
|
@@ -836,6 +851,7 @@ var LaravelEchoBroadcastClient = class {
|
|
|
836
851
|
this.channelPrefix = channelPrefix;
|
|
837
852
|
this.threadChannelType = channelTypes?.threadChannel ?? "public";
|
|
838
853
|
this.userChannelType = channelTypes?.userChannel ?? "private";
|
|
854
|
+
this.useHashChannel = channelTypes?.useHashChannel ?? false;
|
|
839
855
|
}
|
|
840
856
|
subscribeToEcho(name, type) {
|
|
841
857
|
switch (type) {
|
|
@@ -857,8 +873,22 @@ var LaravelEchoBroadcastClient = class {
|
|
|
857
873
|
});
|
|
858
874
|
this.subscriptions.clear();
|
|
859
875
|
}
|
|
860
|
-
|
|
861
|
-
const
|
|
876
|
+
async buildResolvedChannelName(threadId) {
|
|
877
|
+
const name = this.useHashChannel ? await this.hashChannelName(threadId) : threadId;
|
|
878
|
+
return `${this.channelPrefix}.${name}`;
|
|
879
|
+
}
|
|
880
|
+
async hashChannelName(name) {
|
|
881
|
+
if (typeof crypto?.subtle?.digest !== "function") {
|
|
882
|
+
throw new Error("Web Crypto API not available. Cannot hash channel names.");
|
|
883
|
+
}
|
|
884
|
+
const encoder = new TextEncoder();
|
|
885
|
+
const data = encoder.encode(name);
|
|
886
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
887
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
888
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
889
|
+
}
|
|
890
|
+
async subscribe(threadId, handlers) {
|
|
891
|
+
const channelName = await this.buildResolvedChannelName(threadId);
|
|
862
892
|
const channel = this.subscribeToEcho(channelName, this.threadChannelType);
|
|
863
893
|
const key = `thread:${threadId}`;
|
|
864
894
|
this.subscriptions.set(key, channel);
|
|
@@ -881,8 +911,8 @@ var LaravelEchoBroadcastClient = class {
|
|
|
881
911
|
this.subscriptions.delete(key);
|
|
882
912
|
};
|
|
883
913
|
}
|
|
884
|
-
subscribeToUser(threadId, userId, handlers) {
|
|
885
|
-
const channelName = `${this.
|
|
914
|
+
async subscribeToUser(threadId, userId, handlers) {
|
|
915
|
+
const channelName = `${await this.buildResolvedChannelName(threadId)}.${userId}`;
|
|
886
916
|
const channel = this.subscribeToEcho(channelName, this.userChannelType);
|
|
887
917
|
const key = `user:${threadId}:${userId}`;
|
|
888
918
|
this.subscriptions.set(key, channel);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/HttpClient.ts","../src/events/base/ChatEvent.ts","../src/events/MessagePostedEvent.ts","../src/events/MessageEditedEvent.ts","../src/events/MessageDeletedEvent.ts","../src/events/ReactionAddedEvent.ts","../src/events/ReactionRemovedEvent.ts","../src/events/TypingStartedEvent.ts","../src/events/StreamingChunkEvent.ts","../src/events/DMRequestedEvent.ts","../src/events/ChatEventFactory.ts","../src/utils/eventIdGenerator.ts","../src/client/WebChatClient.ts","../src/client/PusherBroadcastClient.ts","../src/client/LaravelEchoBroadcastClient.ts","../src/push/PushManager.ts","../src/push/PushSubscriptionManager.ts"],"sourcesContent":["export interface HttpClientConfig {\n apiUrl: string;\n headers?: Record<string, string>;\n timeout?: number;\n verifyToken?: string;\n}\n\nexport interface ChatResponse {\n id: string;\n role: \"assistant\" | \"user\";\n text: string;\n attachments?: Array<{\n type: string;\n url: string;\n name?: string;\n mime_type?: string;\n size?: number;\n }>;\n events?: Array<Record<string, unknown>>;\n}\n\nexport class HttpClient {\n private config: Required<Pick<HttpClientConfig, \"apiUrl\" | \"timeout\">> & {\n headers: Record<string, string>;\n };\n\n constructor(config: HttpClientConfig) {\n const headers: Record<string, string> = { ...config.headers };\n if (config.verifyToken) {\n headers[\"X-Verify-Token\"] = config.verifyToken;\n }\n this.config = { apiUrl: config.apiUrl, timeout: config.timeout ?? 30000, headers };\n }\n\n async get(url: string, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"GET\",\n headers: this.config.headers,\n signal: combined,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async post(url: string, body: unknown, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.config.headers },\n signal: combined,\n body: JSON.stringify(body),\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async delete(url: string, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"DELETE\",\n headers: this.config.headers,\n signal: combined,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n const text = await response.text();\n return text ? JSON.parse(text) : undefined;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async sendMessage(\n messages: Array<{\n id: string;\n role: string;\n text: string;\n attachments?: Array<{ url: string; name?: string; mime_type?: string; size?: number }>;\n }>,\n endpoint: string = \"/api/webhooks/web\",\n conversationId?: string,\n ): Promise<ChatResponse> {\n return this.post(endpoint, { id: conversationId, messages }) as Promise<ChatResponse>;\n }\n\n async sendAction(\n actionId: string,\n value: string,\n messageId: string,\n conversationId: string,\n endpoint: string = \"/api/webhooks/web\",\n ): Promise<Record<string, unknown>> {\n return this.post(endpoint, {\n id: conversationId,\n action: { actionId, value, messageId },\n }) as Promise<Record<string, unknown>>;\n }\n\n async editMessage(\n messageId: string,\n newText: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/edit\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.post(url, { text: newText });\n }\n\n async deleteMessage(\n messageId: string,\n endpointTemplate: string = \"/api/chat/messages/{id}\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.delete(url);\n }\n\n async addReaction(\n messageId: string,\n emoji: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/reactions\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.post(url, { emoji });\n }\n\n async removeReaction(\n messageId: string,\n emoji: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/reactions/{emoji}\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId, emoji });\n await this.delete(url);\n }\n\n async postFormData(url: string, formData: FormData, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"POST\",\n headers: this.config.headers,\n signal: combined,\n body: formData,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n setHeader(name: string, value: string): void {\n this.config.headers[name] = value;\n }\n\n removeHeader(name: string): void {\n delete this.config.headers[name];\n }\n\n private resolve(url: string): string {\n return /^https?:\\/\\//.test(url) ? url : `${this.config.apiUrl}${url}`;\n }\n\n private expandTemplate(template: string, params: Record<string, string>): string {\n let url = template;\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`{${key}}`, encodeURIComponent(value));\n }\n return this.resolve(url);\n }\n}\n","export abstract class ChatEvent {\n readonly type: string;\n readonly threadId: string;\n readonly timestamp: number;\n\n constructor(type: string, threadId: string, timestamp: number) {\n this.type = type;\n this.threadId = threadId;\n this.timestamp = timestamp;\n }\n\n static fromJSON: ((json: Record<string, unknown>) => ChatEvent) | undefined;\n}\n\nexport class UnknownEvent extends ChatEvent {\n readonly data: Record<string, unknown>;\n\n constructor(type: string, threadId: string, data: Record<string, unknown>, timestamp: number) {\n super(type, threadId, timestamp);\n this.data = data;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User, Card } from \"../types\";\n\nexport class MessagePostedEvent extends ChatEvent {\n readonly messageId: string;\n readonly text: string;\n readonly author: User;\n readonly card?: Card;\n readonly attachments?: Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>;\n\n constructor(\n threadId: string,\n messageId: string,\n text: string,\n author: User,\n card?: Card,\n attachments?: Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>,\n timestamp?: number,\n ) {\n super(\"message.posted\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.text = text;\n this.author = author;\n this.card = card;\n this.attachments = attachments;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { Card } from \"../types\";\n\nexport class MessageEditedEvent extends ChatEvent {\n readonly messageId: string;\n readonly newText: string;\n readonly card?: Card;\n\n constructor(\n threadId: string,\n messageId: string,\n newText: string,\n card?: Card,\n timestamp?: number,\n ) {\n super(\"message.edited\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.newText = newText;\n this.card = card;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class MessageDeletedEvent extends ChatEvent {\n readonly messageId: string;\n\n constructor(threadId: string, messageId: string, timestamp?: number) {\n super(\"message.deleted\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User } from \"../types\";\n\nexport class ReactionAddedEvent extends ChatEvent {\n readonly messageId: string;\n readonly emoji: string;\n readonly user: User;\n\n constructor(threadId: string, messageId: string, emoji: string, user: User, timestamp?: number) {\n super(\"reaction.added\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.emoji = emoji;\n this.user = user;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User } from \"../types\";\n\nexport class ReactionRemovedEvent extends ChatEvent {\n readonly messageId: string;\n readonly emoji: string;\n readonly user: User;\n\n constructor(threadId: string, messageId: string, emoji: string, user: User, timestamp?: number) {\n super(\"reaction.removed\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.emoji = emoji;\n this.user = user;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class TypingStartedEvent extends ChatEvent {\n readonly userId: string;\n\n constructor(threadId: string, userId: string, timestamp?: number) {\n super(\"typing.started\", threadId, timestamp ?? Date.now());\n this.userId = userId;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class StreamingChunkEvent extends ChatEvent {\n readonly messageId: string;\n readonly chunk: string;\n readonly isFinal: boolean;\n\n constructor(\n threadId: string,\n messageId: string,\n chunk: string,\n isFinal: boolean,\n timestamp?: number,\n ) {\n super(\"streaming.chunk\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.chunk = chunk;\n this.isFinal = isFinal;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class DMRequestedEvent extends ChatEvent {\n readonly userId: string;\n\n constructor(threadId: string, userId: string, timestamp?: number) {\n super(\"dm.requested\", threadId, timestamp ?? Date.now());\n this.userId = userId;\n }\n}\n","import { ChatEvent, UnknownEvent } from \"./base/ChatEvent\";\nimport type { Card, User } from \"../types\";\nimport { MessagePostedEvent } from \"./MessagePostedEvent\";\nimport { MessageEditedEvent } from \"./MessageEditedEvent\";\nimport { MessageDeletedEvent } from \"./MessageDeletedEvent\";\nimport { ReactionAddedEvent } from \"./ReactionAddedEvent\";\nimport { ReactionRemovedEvent } from \"./ReactionRemovedEvent\";\nimport { TypingStartedEvent } from \"./TypingStartedEvent\";\nimport { StreamingChunkEvent } from \"./StreamingChunkEvent\";\nimport { DMRequestedEvent } from \"./DMRequestedEvent\";\n\nfunction parseCard(value: unknown): Card | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const obj = value as Record<string, unknown>;\n if (typeof obj.type !== \"string\") return undefined;\n return obj as unknown as Card;\n}\n\nexport function parseChatEvent(json: Record<string, unknown>): ChatEvent {\n const type = json.type as string;\n const threadId = json.threadId as string;\n const timestamp = json.timestamp as number;\n const data = (json.data ?? {}) as Record<string, unknown>;\n\n switch (type) {\n case \"message.posted\":\n return new MessagePostedEvent(\n threadId,\n data.messageId as string,\n data.text as string,\n data.author as User,\n parseCard(data.card),\n data.attachments as Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>,\n timestamp,\n );\n case \"message.edited\":\n return new MessageEditedEvent(\n threadId,\n data.messageId as string,\n data.newText as string,\n parseCard(data.card),\n timestamp,\n );\n case \"message.deleted\":\n return new MessageDeletedEvent(threadId, data.messageId as string, timestamp);\n case \"reaction.added\":\n return new ReactionAddedEvent(\n threadId,\n data.messageId as string,\n data.emoji as string,\n data.user as User,\n timestamp,\n );\n case \"reaction.removed\":\n return new ReactionRemovedEvent(\n threadId,\n data.messageId as string,\n data.emoji as string,\n data.user as User,\n timestamp,\n );\n case \"typing.started\":\n return new TypingStartedEvent(threadId, data.userId as string, timestamp);\n case \"streaming.chunk\":\n return new StreamingChunkEvent(\n threadId,\n data.messageId as string,\n data.chunk as string,\n data.isFinal as boolean,\n timestamp,\n );\n case \"dm.requested\":\n return new DMRequestedEvent(threadId, data.userId as string, timestamp);\n default:\n return new UnknownEvent(type, threadId, data, timestamp);\n }\n}\n\n// Wire up the static method\nChatEvent.fromJSON = parseChatEvent;\n","export function generateId(): string {\n return `msg-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\nexport function generateConversationId(): string {\n return `conv-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n","import { HttpClient } from \"./HttpClient\";\nimport type { BroadcastClient, EventHandlers, Unsubscribe } from \"./BroadcastClient\";\nimport type { Message } from \"../types\";\nimport { ChatEvent } from \"../events/base/ChatEvent\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type { MessagePostedEvent } from \"../events/MessagePostedEvent\";\nimport type { MessageEditedEvent } from \"../events/MessageEditedEvent\";\nimport type { MessageDeletedEvent } from \"../events/MessageDeletedEvent\";\nimport type { ReactionAddedEvent } from \"../events/ReactionAddedEvent\";\nimport type { ReactionRemovedEvent } from \"../events/ReactionRemovedEvent\";\nimport type { TypingStartedEvent } from \"../events/TypingStartedEvent\";\nimport type { StreamingChunkEvent } from \"../events/StreamingChunkEvent\";\nimport type { DMRequestedEvent } from \"../events/DMRequestedEvent\";\nimport { generateId, generateConversationId } from \"../utils/eventIdGenerator\";\n\nexport interface ReconfigureConfig {\n userId?: string;\n userName?: string;\n verifyToken?: string;\n conversationId?: string;\n headers?: Record<string, string>;\n}\n\nexport interface WebChatClientConfig {\n apiUrl: string;\n userId: string;\n userName: string;\n broadcastClient?: BroadcastClient;\n headers?: Record<string, string>;\n verifyToken?: string;\n conversationId?: string;\n endpoints?: {\n sendMessage?: string;\n loadMessages?: string;\n editMessage?: string;\n deleteMessage?: string;\n addReaction?: string;\n removeReaction?: string;\n };\n features?: {\n editMessages?: boolean;\n deleteMessages?: boolean;\n reactions?: boolean;\n };\n}\n\ninterface StreamingState {\n messageId: string;\n accumulatedText: string;\n isComplete: boolean;\n}\n\ninterface AttachmentInput {\n url: string;\n name?: string;\n mimeType?: string;\n size?: number;\n}\n\nexport interface LoadMessagesOptions {\n limit?: number;\n before?: number;\n after?: number;\n skipStateSeed?: boolean;\n}\n\nexport interface LoadMessagesResult {\n messages: Message[];\n hasMore: boolean;\n nextCursor?: number;\n prevCursor?: number;\n}\n\nexport class WebChatClient {\n private config: WebChatClientConfig;\n private httpClient: HttpClient;\n private broadcastClient?: BroadcastClient;\n private conversationId: string;\n private messages: Message[] = [];\n private currentUserId: string;\n private eventHandlers: EventHandlers = {};\n private streamingMessages: Map<string, StreamingState> = new Map();\n private pendingTyping: ReturnType<typeof setTimeout> | null = null;\n private subscribers: Map<string, Array<(event: unknown) => void>> = new Map();\n private unsubscribeUserChannel?: Unsubscribe;\n\n constructor(config: WebChatClientConfig) {\n this.config = config;\n this.httpClient = new HttpClient({\n apiUrl: config.apiUrl,\n headers: {\n \"X-User-Id\": config.userId,\n \"X-User-Name\": config.userName,\n ...(config.headers ?? {}),\n },\n verifyToken: config.verifyToken,\n });\n this.broadcastClient = config.broadcastClient;\n this.conversationId = config.conversationId ?? generateConversationId();\n this.currentUserId = config.userId;\n }\n\n reconfigure(config: ReconfigureConfig): void {\n if (config.userId) {\n this.currentUserId = config.userId;\n this.httpClient.setHeader(\"X-User-Id\", config.userId);\n }\n if (config.userName) {\n this.config = { ...this.config, userName: config.userName };\n this.httpClient.setHeader(\"X-User-Name\", config.userName);\n }\n if (config.verifyToken) {\n this.config = { ...this.config, verifyToken: config.verifyToken };\n this.httpClient.setHeader(\"X-Verify-Token\", config.verifyToken);\n }\n if (config.conversationId) {\n this.conversationId = config.conversationId;\n }\n if (config.headers) {\n Object.entries(config.headers).forEach(([key, value]) => {\n this.httpClient.setHeader(key, value);\n });\n }\n }\n\n setLocaleHeader(locale: string): void {\n this.httpClient.setHeader(\"X-Locale\", locale);\n this.httpClient.setHeader(\"X-Language\", locale.split(\"-\")[0] ?? locale);\n }\n\n setTimezoneHeader(timezone: string): void {\n this.httpClient.setHeader(\"X-Timezone\", timezone);\n }\n\n async connect(): Promise<void> {\n if (this.broadcastClient) {\n this.broadcastClient.connect();\n\n const threadId = this.getThreadId();\n const threadEvents: EventHandlers = {\n onMessagePosted: (event) => this.handleMessagePosted(event),\n };\n\n if (this.config.features?.editMessages) {\n threadEvents.onMessageEdited = (event) => this.handleMessageEdited(event);\n }\n if (this.config.features?.deleteMessages) {\n threadEvents.onMessageDeleted = (event) => this.handleMessageDeleted(event);\n }\n if (this.config.features?.reactions) {\n threadEvents.onReactionAdded = (event) => this.handleReactionAdded(event);\n threadEvents.onReactionRemoved = (event) => this.handleReactionRemoved(event);\n }\n\n this.broadcastClient.subscribe(threadId, threadEvents);\n\n this.unsubscribeUserChannel = this.broadcastClient.subscribeToUser(\n threadId,\n this.currentUserId,\n {\n onTypingStarted: (event) => this.handleTypingStarted(event),\n onStreamingChunk: (event) => this.handleStreamingChunk(event),\n onDMRequested: (event) => this.handleDMRequested(event),\n },\n );\n }\n }\n\n disconnect(): void {\n this.unsubscribeUserChannel?.();\n this.unsubscribeUserChannel = undefined;\n this.broadcastClient?.disconnect();\n this.streamingMessages.clear();\n }\n\n async loadMessages(\n options?: LoadMessagesOptions,\n signal?: AbortSignal,\n ): Promise<LoadMessagesResult> {\n const endpoint = this.config.endpoints?.loadMessages ?? \"/api/chat/messages\";\n const threadId = this.getThreadId();\n const params = new URLSearchParams({\n threadId,\n limit: String(options?.limit ?? 50),\n });\n if (options?.before) params.set(\"before\", String(options.before));\n if (options?.after) params.set(\"after\", String(options.after));\n\n const response = (await this.httpClient.get(\n `${endpoint}?${params.toString()}`,\n signal,\n )) as Record<string, unknown>;\n const rawMessages = (response.messages as Record<string, unknown>[]) ?? [];\n const messages: Message[] = rawMessages.map((msg) => ({\n id: msg.id as string,\n threadId,\n content: {\n text: msg.text as string,\n cards: msg.card ? ([msg.card as Record<string, unknown>] as never[]) : undefined,\n },\n author: {\n id: (msg.author as Record<string, unknown>).id as string,\n name: (msg.author as Record<string, unknown>).name as string,\n isBot: ((msg.author as Record<string, unknown>).isBot as boolean) ?? false,\n isMe: (msg.author as Record<string, unknown>).id === this.currentUserId,\n },\n timestamp: msg.timestamp as number,\n attachments: (msg.attachments as Record<string, unknown>[])?.map((a) => ({\n id: `att-${msg.id as string}-${a.url as string}`,\n url: a.url as string,\n name: a.name as string,\n type: a.type as string,\n mimeType: a.mime_type as string,\n size: a.size as number,\n })),\n reactions: (msg.reactions as { emoji: string; count: number; users: string[] }[]) ?? [],\n }));\n\n if (!options?.before && !options?.after && !options?.skipStateSeed) {\n this.messages = messages;\n this.notifySubscribers(\"messages:loaded\", messages);\n }\n\n return {\n messages,\n hasMore: (response.hasMore as boolean) ?? false,\n nextCursor: response.nextCursor as number | undefined,\n prevCursor: response.prevCursor as number | undefined,\n };\n }\n\n async sendMessage(text: string, attachments: AttachmentInput[] = []): Promise<void> {\n const messageId = generateId();\n\n const userMessage: Message = {\n id: messageId,\n threadId: this.getThreadId(),\n content: { text },\n author: { id: this.currentUserId, name: this.config.userName, isMe: true },\n timestamp: Date.now(),\n attachments:\n attachments.length > 0\n ? attachments.map((a, i) => ({\n id: `att-${messageId}-${i}`,\n name: a.name ?? \"\",\n url: a.url,\n size: a.size,\n mimeType: a.mimeType,\n }))\n : undefined,\n };\n\n this.messages.push(userMessage);\n this.notifySubscribers(\"message:added\", userMessage);\n\n const endpoint = this.config.endpoints?.sendMessage ?? \"/api/webhooks/web\";\n const response = await this.httpClient.sendMessage(\n [\n {\n id: messageId,\n role: \"user\",\n text,\n attachments: attachments.map((a) => ({\n url: a.url,\n name: a.name,\n mime_type: a.mimeType,\n size: a.size,\n })),\n },\n ],\n endpoint,\n this.conversationId,\n );\n\n if (response.events) {\n response.events.forEach((eventData) => {\n const event = parseChatEvent(eventData);\n this.dispatchEvent(event);\n });\n }\n\n if (response.text && !response.events?.some((e) => e.type === \"message.posted\")) {\n const assistantMessage: Message = {\n id: response.id ?? generateId(),\n threadId: this.getThreadId(),\n content: { text: response.text },\n author: { id: \"assistant\", name: \"Assistant\", isBot: true },\n timestamp: Date.now(),\n attachments: (response.attachments as Record<string, unknown>[])?.map((a, i) => ({\n id: `att-${response.id ?? \"msg\"}-${i}`,\n name: (a.name as string) ?? \"\",\n url: (a.url as string) ?? \"\",\n type: a.type as string,\n mimeType: a.mime_type as string,\n size: a.size as number,\n })),\n };\n this.messages.push(assistantMessage);\n this.notifySubscribers(\"message:added\", assistantMessage);\n }\n }\n\n async sendAction(messageId: string, actionId: string, value: string): Promise<void> {\n const endpoint = this.config.endpoints?.sendMessage ?? \"/api/webhooks/web\";\n const response = await this.httpClient.sendAction(\n actionId,\n value,\n messageId,\n this.conversationId,\n endpoint,\n );\n\n if (response.events) {\n (response.events as Array<Record<string, unknown>>).forEach((eventData) => {\n const event = parseChatEvent(eventData);\n this.dispatchEvent(event);\n });\n }\n }\n\n async editMessage(messageId: string, newText: string): Promise<void> {\n if (!this.config.features?.editMessages) {\n throw new Error(\"Edit messages not enabled. Set features.editMessages = true in config.\");\n }\n const endpoint = this.config.endpoints?.editMessage ?? \"/api/chat/messages/{id}/edit\";\n await this.httpClient.editMessage(messageId, newText, endpoint);\n }\n\n async deleteMessage(messageId: string): Promise<void> {\n if (!this.config.features?.deleteMessages) {\n throw new Error(\"Delete messages not enabled. Set features.deleteMessages = true in config.\");\n }\n const endpoint = this.config.endpoints?.deleteMessage ?? \"/api/chat/messages/{id}\";\n await this.httpClient.deleteMessage(messageId, endpoint);\n }\n\n async addReaction(messageId: string, emoji: string): Promise<void> {\n if (!this.config.features?.reactions) {\n throw new Error(\"Reactions not enabled. Set features.reactions = true in config.\");\n }\n const endpoint = this.config.endpoints?.addReaction ?? \"/api/chat/messages/{id}/reactions\";\n await this.httpClient.addReaction(messageId, emoji, endpoint);\n }\n\n async removeReaction(messageId: string, emoji: string): Promise<void> {\n if (!this.config.features?.reactions) {\n throw new Error(\"Reactions not enabled. Set features.reactions = true in config.\");\n }\n const endpoint =\n this.config.endpoints?.removeReaction ?? \"/api/chat/messages/{id}/reactions/{emoji}\";\n await this.httpClient.removeReaction(messageId, emoji, endpoint);\n }\n\n onMessagePosted(handler: (event: MessagePostedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message.posted\", handler);\n }\n\n onMessageEdited(handler: (event: MessageEditedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message:edited\", handler);\n }\n\n onMessageDeleted(handler: (event: MessageDeletedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message:deleted\", handler);\n }\n\n onReactionAdded(handler: (event: ReactionAddedEvent) => void): Unsubscribe {\n return this.addEventListener(\"reaction:added\", handler);\n }\n\n onReactionRemoved(handler: (event: ReactionRemovedEvent) => void): Unsubscribe {\n return this.addEventListener(\"reaction:removed\", handler);\n }\n\n onStreamingChunk(handler: (event: StreamingChunkEvent) => void): Unsubscribe {\n return this.addEventListener(\"streaming:chunk\", handler);\n }\n\n onTypingStarted(handler: (event: TypingStartedEvent) => void): Unsubscribe {\n return this.addEventListener(\"typing:started\", handler);\n }\n\n getConversationId(): string {\n return this.conversationId;\n }\n getMessages(): Message[] {\n return [...this.messages];\n }\n getThreadId(): string {\n return `web:${this.currentUserId}:${this.conversationId}`;\n }\n getCurrentUserId(): string {\n return this.currentUserId;\n }\n getFeatures(): NonNullable<WebChatClientConfig[\"features\"]> {\n return this.config.features ?? {};\n }\n getEndpoints(): NonNullable<WebChatClientConfig[\"endpoints\"]> {\n return this.config.endpoints ?? {};\n }\n getHttpClient(): HttpClient {\n return this.httpClient;\n }\n\n addEventListener<T = unknown>(eventType: string, handler: (event: T) => void): Unsubscribe {\n if (!this.subscribers.has(eventType)) this.subscribers.set(eventType, []);\n this.subscribers.get(eventType)!.push(handler as (event: unknown) => void);\n return () => {\n const handlers = this.subscribers.get(eventType);\n if (handlers) {\n const index = handlers.indexOf(handler as (event: unknown) => void);\n if (index !== -1) handlers.splice(index, 1);\n }\n };\n }\n\n private handleMessagePosted(event: MessagePostedEvent): void {\n if (this.messages.some((m) => m.id === event.messageId)) return;\n if (this.streamingMessages.has(event.messageId)) return;\n\n const message: Message = {\n id: event.messageId,\n threadId: event.threadId,\n content: { text: event.text, cards: event.card ? [event.card] : undefined },\n author: event.author,\n timestamp: event.timestamp,\n attachments: event.attachments?.map((a) => ({\n id: `att-${event.messageId}-${Math.random().toString(36).slice(2, 8)}`,\n name: a.name ?? \"\",\n url: a.url ?? \"\",\n type: a.type,\n mimeType: a.mimeType,\n size: a.size ?? undefined,\n })),\n };\n this.messages.push(message);\n this.notifySubscribers(\"message:added\", message);\n this.notifySubscribers(\"message.posted\", event);\n }\n\n private handleMessageEdited(event: MessageEditedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (message?.content) {\n message.content.text = event.newText;\n this.notifySubscribers(\"message:edited\", event);\n }\n }\n\n private handleMessageDeleted(event: MessageDeletedEvent): void {\n const index = this.messages.findIndex((m) => m.id === event.messageId);\n if (index !== -1) {\n this.messages.splice(index, 1);\n this.notifySubscribers(\"message:deleted\", event);\n }\n }\n\n private handleReactionAdded(event: ReactionAddedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (!message) return;\n if (!message.reactions) message.reactions = [];\n\n const existing = message.reactions.find((r) => r.emoji === event.emoji);\n if (existing) {\n existing.count++;\n existing.users.push(event.user.id);\n } else {\n message.reactions.push({ emoji: event.emoji, count: 1, users: [event.user.id] });\n }\n this.notifySubscribers(\"reaction:added\", event);\n }\n\n private handleReactionRemoved(event: ReactionRemovedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (!message?.reactions) return;\n\n const index = message.reactions.findIndex((r) => r.emoji === event.emoji);\n if (index !== -1) {\n const reaction = message.reactions[index]!;\n reaction.count--;\n reaction.users = reaction.users.filter((id) => id !== event.user.id);\n if (reaction.count === 0) message.reactions.splice(index, 1);\n }\n this.notifySubscribers(\"reaction:removed\", event);\n }\n\n private handleStreamingChunk(event: StreamingChunkEvent): void {\n const { messageId, chunk, isFinal } = event;\n\n if (!this.streamingMessages.has(messageId)) {\n this.streamingMessages.set(messageId, { messageId, accumulatedText: \"\", isComplete: false });\n this.notifySubscribers(\"streaming:started\", event);\n }\n\n const state = this.streamingMessages.get(messageId)!;\n state.accumulatedText += chunk;\n\n if (isFinal) {\n state.isComplete = true;\n if (!this.messages.some((m) => m.id === messageId)) {\n const message: Message = {\n id: messageId,\n threadId: event.threadId,\n content: { text: state.accumulatedText },\n author: { id: \"assistant\", name: \"Assistant\", isBot: true },\n timestamp: event.timestamp,\n };\n this.messages.push(message);\n this.notifySubscribers(\"message:added\", message);\n }\n this.streamingMessages.delete(messageId);\n this.notifySubscribers(\"streaming:complete\", { messageId, text: state.accumulatedText });\n } else {\n this.notifySubscribers(\"streaming:chunk\", event);\n }\n }\n\n private handleTypingStarted(event: TypingStartedEvent): void {\n if (this.pendingTyping) clearTimeout(this.pendingTyping);\n this.notifySubscribers(\"typing:started\", event);\n this.pendingTyping = setTimeout(() => {\n this.notifySubscribers(\"typing:stopped\", { userId: event.userId });\n }, 3000);\n }\n\n private handleDMRequested(event: DMRequestedEvent): void {\n this.notifySubscribers(\"dm.requested\", event);\n }\n\n private notifySubscribers<T>(eventType: string, data: T): void {\n this.subscribers.get(eventType)?.forEach((handler) => handler(data));\n }\n\n private dispatchEvent(event: ChatEvent): void {\n switch (event.type) {\n case \"message.posted\":\n this.handleMessagePosted(event as MessagePostedEvent);\n break;\n case \"message.edited\":\n this.handleMessageEdited(event as MessageEditedEvent);\n break;\n case \"message.deleted\":\n this.handleMessageDeleted(event as MessageDeletedEvent);\n break;\n case \"reaction.added\":\n this.handleReactionAdded(event as ReactionAddedEvent);\n break;\n case \"reaction.removed\":\n this.handleReactionRemoved(event as ReactionRemovedEvent);\n break;\n case \"typing.started\":\n this.handleTypingStarted(event as TypingStartedEvent);\n break;\n case \"streaming.chunk\":\n this.handleStreamingChunk(event as StreamingChunkEvent);\n break;\n case \"dm.requested\":\n this.handleDMRequested(event as DMRequestedEvent);\n break;\n }\n }\n}\n","import {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./BroadcastClient\";\nimport { ChatEvent } from \"../events/base/ChatEvent\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type Pusher from \"pusher-js\";\nimport type { Channel as PusherChannel } from \"pusher-js\";\n\nexport interface PusherConfig {\n key: string;\n cluster?: string;\n host?: string;\n port?: number;\n forceTLS?: boolean;\n authEndpoint?: string;\n}\n\nexport class PusherBroadcastClient implements BroadcastClient {\n private pusher: Pusher;\n private channelPrefix: string;\n private threadChannelType: \"public\" | \"private\" | \"presence\";\n private userChannelType: \"private\" | \"presence\";\n private subscriptions: Map<string, PusherChannel> = new Map();\n\n constructor(pusher: Pusher, channelPrefix?: string, channelTypes?: ChannelTypeConfig);\n constructor(config: PusherConfig, channelPrefix?: string, channelTypes?: ChannelTypeConfig);\n constructor(\n pusherOrConfig: Pusher | PusherConfig,\n channelPrefix: string = \"chat\",\n channelTypes?: ChannelTypeConfig,\n ) {\n this.channelPrefix = channelPrefix;\n this.threadChannelType = channelTypes?.threadChannel ?? \"public\";\n this.userChannelType = channelTypes?.userChannel ?? \"private\";\n\n if (\"key\" in pusherOrConfig) {\n const PusherCtor = (globalThis as any).Pusher ?? (globalThis as any).pusherJs;\n if (!PusherCtor) {\n throw new Error(\"pusher-js not found. Install it or pass a Pusher instance.\");\n }\n this.pusher = new PusherCtor((pusherOrConfig as PusherConfig).key, pusherOrConfig) as Pusher;\n } else {\n this.pusher = pusherOrConfig as Pusher;\n }\n }\n\n private buildChannelName(base: string, type: \"public\" | \"private\" | \"presence\"): string {\n switch (type) {\n case \"private\":\n return `private-${base}`;\n case \"presence\":\n return `presence-${base}`;\n default:\n return base;\n }\n }\n\n connect(): void {\n if (this.pusher.connection?.state !== \"connected\") {\n this.pusher.connect();\n }\n }\n\n disconnect(): void {\n this.subscriptions.forEach((channel) => channel.unbind_all?.() ?? channel.unsubscribe?.());\n this.subscriptions.clear();\n this.pusher.disconnect?.();\n }\n\n subscribe(threadId: string, handlers: EventHandlers): Unsubscribe {\n const baseName = `${this.channelPrefix}.${threadId}`;\n const channelName = this.buildChannelName(baseName, this.threadChannelType);\n const channel = this.pusher.subscribe(channelName);\n const key = `thread:${threadId}`;\n this.subscriptions.set(key, channel);\n\n const threadEvents = [\n \"message.posted\",\n \"message.edited\",\n \"message.deleted\",\n \"reaction.added\",\n \"reaction.removed\",\n ] as const;\n\n threadEvents.forEach((eventType) => {\n const eventName = `${this.channelPrefix}.${eventType}`;\n channel.bind(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n this.dispatchToHandler(event, handlers);\n });\n });\n\n return () => {\n channel.unbind_all?.();\n this.pusher.unsubscribe(channelName);\n this.subscriptions.delete(key);\n };\n }\n\n subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Unsubscribe {\n const baseName = `${this.channelPrefix}.${threadId}.${userId}`;\n const channelName = this.buildChannelName(baseName, this.userChannelType);\n const channel = this.pusher.subscribe(channelName);\n const key = `user:${threadId}:${userId}`;\n this.subscriptions.set(key, channel);\n\n const userEvents = [\"typing.started\", \"streaming.chunk\", \"dm.requested\"] as const;\n\n userEvents.forEach((eventType) => {\n const eventName = `${this.channelPrefix}.${eventType}`;\n channel.bind(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n this.dispatchToHandler(event, handlers);\n });\n });\n\n return () => {\n channel.unbind_all?.();\n this.pusher.unsubscribe(channelName);\n this.subscriptions.delete(key);\n };\n }\n\n isConnected(): boolean {\n return this.pusher.connection?.state === \"connected\";\n }\n\n private dispatchToHandler(event: ChatEvent, handlers: EventHandlers): void {\n switch (event.type) {\n case \"message.posted\":\n handlers.onMessagePosted?.(event as any);\n break;\n case \"message.edited\":\n handlers.onMessageEdited?.(event as any);\n break;\n case \"message.deleted\":\n handlers.onMessageDeleted?.(event as any);\n break;\n case \"reaction.added\":\n handlers.onReactionAdded?.(event as any);\n break;\n case \"reaction.removed\":\n handlers.onReactionRemoved?.(event as any);\n break;\n case \"typing.started\":\n handlers.onTypingStarted?.(event as any);\n break;\n case \"streaming.chunk\":\n handlers.onStreamingChunk?.(event as any);\n break;\n case \"dm.requested\":\n handlers.onDMRequested?.(event as any);\n break;\n }\n }\n}\n","import {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./BroadcastClient\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type Echo from \"laravel-echo\";\n\ninterface EchoChannel {\n listen(event: string, callback: (data: unknown) => void): this;\n unsubscribe(): void;\n stopListening(event?: string, callback?: (data: unknown) => void): this;\n}\n\nexport class LaravelEchoBroadcastClient implements BroadcastClient {\n private echo: Echo<any>;\n private channelPrefix: string;\n private threadChannelType: \"public\" | \"private\" | \"presence\";\n private userChannelType: \"private\" | \"presence\";\n private subscriptions: Map<string, EchoChannel> = new Map();\n\n constructor(echo: Echo<any>, channelPrefix: string = \"chat\", channelTypes?: ChannelTypeConfig) {\n this.echo = echo;\n this.channelPrefix = channelPrefix;\n this.threadChannelType = channelTypes?.threadChannel ?? \"public\";\n this.userChannelType = channelTypes?.userChannel ?? \"private\";\n }\n\n private subscribeToEcho(name: string, type: \"public\" | \"private\" | \"presence\"): EchoChannel {\n switch (type) {\n case \"private\":\n return this.echo.private(name) as unknown as EchoChannel;\n case \"presence\":\n return this.echo.join(name) as unknown as EchoChannel;\n default:\n return this.echo.channel(name) as unknown as EchoChannel;\n }\n }\n\n connect(): void | Promise<void> {\n return Promise.resolve();\n }\n\n disconnect(): void {\n this.subscriptions.forEach((channel) => {\n channel.unsubscribe?.();\n channel.stopListening?.();\n });\n this.subscriptions.clear();\n }\n\n subscribe(threadId: string, handlers: EventHandlers): Unsubscribe {\n const channelName = `${this.channelPrefix}.${threadId}`;\n const channel = this.subscribeToEcho(channelName, this.threadChannelType);\n const key = `thread:${threadId}`;\n this.subscriptions.set(key, channel);\n\n const threadEvents: Array<{ type: string; handler: keyof EventHandlers }> = [\n { type: \"message.posted\", handler: \"onMessagePosted\" },\n { type: \"message.edited\", handler: \"onMessageEdited\" },\n { type: \"message.deleted\", handler: \"onMessageDeleted\" },\n { type: \"reaction.added\", handler: \"onReactionAdded\" },\n { type: \"reaction.removed\", handler: \"onReactionRemoved\" },\n ];\n\n threadEvents.forEach(({ type, handler }) => {\n const eventName = `.${this.channelPrefix}.${type}`;\n channel.listen(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n (handlers[handler] as any)?.(event);\n });\n });\n\n return () => {\n channel.unsubscribe?.();\n this.subscriptions.delete(key);\n };\n }\n\n subscribeToUser(threadId: string, userId: string, handlers: EventHandlers): Unsubscribe {\n const channelName = `${this.channelPrefix}.${threadId}.${userId}`;\n const channel = this.subscribeToEcho(channelName, this.userChannelType);\n const key = `user:${threadId}:${userId}`;\n this.subscriptions.set(key, channel);\n\n const userEvents: Array<{ type: string; handler: keyof EventHandlers }> = [\n { type: \"typing.started\", handler: \"onTypingStarted\" },\n { type: \"streaming.chunk\", handler: \"onStreamingChunk\" },\n { type: \"dm.requested\", handler: \"onDMRequested\" },\n ];\n\n userEvents.forEach(({ type, handler }) => {\n const eventName = `.${this.channelPrefix}.${type}`;\n channel.listen(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n (handlers[handler] as any)?.(event);\n });\n });\n\n return () => {\n channel.unsubscribe?.();\n this.subscriptions.delete(key);\n };\n }\n\n isConnected(): boolean {\n try {\n const connector = (this.echo as any).connector;\n if (!connector) return false;\n\n if (connector.pusher?.connection?.state === \"connected\") return true;\n if (connector.socket?.connected) return true;\n\n return false;\n } catch {\n return false;\n }\n }\n}\n","import type { PushConfig, PushSubscriptionStatus, PushEventData } from \"./types\";\n\nexport class PushManager {\n private config: PushConfig;\n private registration: ServiceWorkerRegistration | null = null;\n private status: PushSubscriptionStatus = \"unsupported\";\n private statusListeners: Set<(status: PushSubscriptionStatus) => void> = new Set();\n private messageListeners: Set<(data: PushEventData) => void> = new Set();\n\n constructor(config: PushConfig) {\n this.config = config;\n }\n\n static isSupported(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n \"serviceWorker\" in navigator &&\n \"PushManager\" in window &&\n \"Notification\" in window\n );\n }\n\n getStatus(): PushSubscriptionStatus {\n return this.status;\n }\n\n onStatusChange(listener: (status: PushSubscriptionStatus) => void): () => void {\n this.statusListeners.add(listener);\n return () => {\n this.statusListeners.delete(listener);\n };\n }\n\n onMessage(listener: (data: PushEventData) => void): () => void {\n this.messageListeners.add(listener);\n return () => {\n this.messageListeners.delete(listener);\n };\n }\n\n async initialize(): Promise<void> {\n if (!PushManager.isSupported()) {\n this.setStatus(\"unsupported\");\n return;\n }\n if (Notification.permission === \"denied\") {\n this.setStatus(\"denied\");\n return;\n }\n\n try {\n this.registration = await navigator.serviceWorker.register(\n this.config.serviceWorkerUrl || \"/chat-service-worker.js\",\n {\n scope: this.config.serviceWorkerScope || \"/\",\n type: this.config.serviceWorkerType,\n },\n );\n await navigator.serviceWorker.ready;\n\n navigator.serviceWorker.addEventListener(\"message\", (event: MessageEvent) => {\n const msg = event.data as Record<string, unknown>;\n if (msg?.type === \"chat-widget:push-data\") {\n const pushData = msg.data as PushEventData;\n this.messageListeners.forEach((listener) => listener(pushData));\n }\n });\n\n const subscription = await this.registration.pushManager.getSubscription();\n this.setStatus(subscription ? \"subscribed\" : \"default\");\n } catch {\n this.setStatus(\"error\");\n }\n }\n\n async subscribe(): Promise<void> {\n if (!this.registration)\n throw new Error(\"PushManager not initialized. Call initialize() first.\");\n\n this.setStatus(\"subscribing\");\n\n try {\n let subscription = await this.registration.pushManager.getSubscription();\n\n if (!subscription) {\n const permission = await Notification.requestPermission();\n if (permission !== \"granted\") {\n this.setStatus(permission === \"denied\" ? \"denied\" : \"default\");\n return;\n }\n\n const vapidPublicKey = await this.config.getVapidPublicKey();\n const convertedKey = this.urlBase64ToUint8Array(vapidPublicKey);\n subscription = await this.registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: convertedKey.buffer as ArrayBuffer,\n });\n }\n\n await this.config.onSubscribe(subscription.toJSON());\n this.setStatus(\"subscribed\");\n } catch {\n this.setStatus(\"error\");\n throw new Error(\"Push subscription failed\");\n }\n }\n\n async unsubscribe(): Promise<void> {\n if (!this.registration) return;\n\n try {\n const subscription = await this.registration.pushManager.getSubscription();\n if (subscription) {\n await this.config.onUnsubscribe(subscription.toJSON());\n await subscription.unsubscribe();\n }\n this.setStatus(\"default\");\n } catch {\n this.setStatus(\"error\");\n throw new Error(\"Push unsubscription failed\");\n }\n }\n\n private urlBase64ToUint8Array(base64String: string): Uint8Array {\n const padding = \"=\".repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding).replace(/-/g, \"+\").replace(/_/g, \"/\");\n const rawData = atob(base64);\n return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0)));\n }\n\n private setStatus(status: PushSubscriptionStatus): void {\n this.status = status;\n this.statusListeners.forEach((listener) => listener(status));\n }\n}\n","import { HttpClient } from \"../client/HttpClient\";\nimport type { PushConfig } from \"./types\";\n\nexport function createPushSubscriptionHandlers(\n httpClient: HttpClient,\n userId: string,\n): Pick<PushConfig, \"onSubscribe\" | \"onUnsubscribe\"> {\n return {\n onSubscribe: async (subscription: PushSubscriptionJSON) => {\n await httpClient.post(\"/api/push/subscriptions\", {\n userId,\n subscription,\n userAgent: navigator.userAgent,\n });\n },\n onUnsubscribe: async (subscription: PushSubscriptionJSON) => {\n await httpClient.delete(\n `/api/push/subscriptions?userId=${encodeURIComponent(userId)}&endpoint=${encodeURIComponent(subscription.endpoint || \"\")}`,\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/client/HttpClient.ts","../src/events/base/ChatEvent.ts","../src/events/MessagePostedEvent.ts","../src/events/MessageEditedEvent.ts","../src/events/MessageDeletedEvent.ts","../src/events/ReactionAddedEvent.ts","../src/events/ReactionRemovedEvent.ts","../src/events/TypingStartedEvent.ts","../src/events/StreamingChunkEvent.ts","../src/events/DMRequestedEvent.ts","../src/events/ChatEventFactory.ts","../src/utils/eventIdGenerator.ts","../src/client/WebChatClient.ts","../src/client/PusherBroadcastClient.ts","../src/client/LaravelEchoBroadcastClient.ts","../src/push/PushManager.ts","../src/push/PushSubscriptionManager.ts"],"sourcesContent":["export interface HttpClientConfig {\n apiUrl: string;\n headers?: Record<string, string>;\n timeout?: number;\n verifyToken?: string;\n}\n\nexport interface ChatResponse {\n id: string;\n role: \"assistant\" | \"user\";\n text: string;\n attachments?: Array<{\n type: string;\n url: string;\n name?: string;\n mime_type?: string;\n size?: number;\n }>;\n events?: Array<Record<string, unknown>>;\n}\n\nexport class HttpClient {\n private config: Required<Pick<HttpClientConfig, \"apiUrl\" | \"timeout\">> & {\n headers: Record<string, string>;\n };\n\n constructor(config: HttpClientConfig) {\n const headers: Record<string, string> = { ...config.headers };\n if (config.verifyToken) {\n headers[\"X-Verify-Token\"] = config.verifyToken;\n }\n this.config = { apiUrl: config.apiUrl, timeout: config.timeout ?? 30000, headers };\n }\n\n async get(url: string, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"GET\",\n headers: this.config.headers,\n signal: combined,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async post(url: string, body: unknown, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.config.headers },\n signal: combined,\n body: JSON.stringify(body),\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async delete(url: string, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"DELETE\",\n headers: this.config.headers,\n signal: combined,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n const text = await response.text();\n return text ? JSON.parse(text) : undefined;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n async sendMessage(\n messages: Array<{\n id: string;\n role: string;\n text: string;\n attachments?: Array<{ url: string; name?: string; mime_type?: string; size?: number }>;\n }>,\n endpoint: string = \"/api/webhooks/web\",\n conversationId?: string,\n ): Promise<ChatResponse> {\n return this.post(endpoint, { id: conversationId, messages }) as Promise<ChatResponse>;\n }\n\n async sendAction(\n actionId: string,\n value: string,\n messageId: string,\n conversationId: string,\n endpoint: string = \"/api/webhooks/web\",\n ): Promise<Record<string, unknown>> {\n return this.post(endpoint, {\n id: conversationId,\n action: { actionId, value, messageId },\n }) as Promise<Record<string, unknown>>;\n }\n\n async editMessage(\n messageId: string,\n newText: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/edit\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.post(url, { text: newText });\n }\n\n async deleteMessage(\n messageId: string,\n endpointTemplate: string = \"/api/chat/messages/{id}\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.delete(url);\n }\n\n async addReaction(\n messageId: string,\n emoji: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/reactions\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId });\n await this.post(url, { emoji });\n }\n\n async removeReaction(\n messageId: string,\n emoji: string,\n endpointTemplate: string = \"/api/chat/messages/{id}/reactions/{emoji}\",\n ): Promise<void> {\n const url = this.expandTemplate(endpointTemplate, { id: messageId, emoji });\n await this.delete(url);\n }\n\n async postFormData(url: string, formData: FormData, signal?: AbortSignal): Promise<unknown> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const fullUrl = this.resolve(url);\n const combined = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;\n const response = await fetch(fullUrl, {\n method: \"POST\",\n headers: this.config.headers,\n signal: combined,\n body: formData,\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n return response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n setHeader(name: string, value: string): void {\n this.config.headers[name] = value;\n }\n\n removeHeader(name: string): void {\n delete this.config.headers[name];\n }\n\n private resolve(url: string): string {\n return /^https?:\\/\\//.test(url) ? url : `${this.config.apiUrl}${url}`;\n }\n\n private expandTemplate(template: string, params: Record<string, string>): string {\n let url = template;\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`{${key}}`, encodeURIComponent(value));\n }\n return this.resolve(url);\n }\n}\n","export abstract class ChatEvent {\n readonly type: string;\n readonly threadId: string;\n readonly timestamp: number;\n\n constructor(type: string, threadId: string, timestamp: number) {\n this.type = type;\n this.threadId = threadId;\n this.timestamp = timestamp;\n }\n\n static fromJSON: ((json: Record<string, unknown>) => ChatEvent) | undefined;\n}\n\nexport class UnknownEvent extends ChatEvent {\n readonly data: Record<string, unknown>;\n\n constructor(type: string, threadId: string, data: Record<string, unknown>, timestamp: number) {\n super(type, threadId, timestamp);\n this.data = data;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User, Card } from \"../types\";\n\nexport class MessagePostedEvent extends ChatEvent {\n readonly messageId: string;\n readonly text: string;\n readonly author: User;\n readonly card?: Card;\n readonly attachments?: Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>;\n\n constructor(\n threadId: string,\n messageId: string,\n text: string,\n author: User,\n card?: Card,\n attachments?: Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>,\n timestamp?: number,\n ) {\n super(\"message.posted\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.text = text;\n this.author = author;\n this.card = card;\n this.attachments = attachments;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { Card } from \"../types\";\n\nexport class MessageEditedEvent extends ChatEvent {\n readonly messageId: string;\n readonly newText: string;\n readonly card?: Card;\n\n constructor(\n threadId: string,\n messageId: string,\n newText: string,\n card?: Card,\n timestamp?: number,\n ) {\n super(\"message.edited\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.newText = newText;\n this.card = card;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class MessageDeletedEvent extends ChatEvent {\n readonly messageId: string;\n\n constructor(threadId: string, messageId: string, timestamp?: number) {\n super(\"message.deleted\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User } from \"../types\";\n\nexport class ReactionAddedEvent extends ChatEvent {\n readonly messageId: string;\n readonly emoji: string;\n readonly user: User;\n\n constructor(threadId: string, messageId: string, emoji: string, user: User, timestamp?: number) {\n super(\"reaction.added\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.emoji = emoji;\n this.user = user;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\nimport type { User } from \"../types\";\n\nexport class ReactionRemovedEvent extends ChatEvent {\n readonly messageId: string;\n readonly emoji: string;\n readonly user: User;\n\n constructor(threadId: string, messageId: string, emoji: string, user: User, timestamp?: number) {\n super(\"reaction.removed\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.emoji = emoji;\n this.user = user;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class TypingStartedEvent extends ChatEvent {\n readonly userId: string;\n\n constructor(threadId: string, userId: string, timestamp?: number) {\n super(\"typing.started\", threadId, timestamp ?? Date.now());\n this.userId = userId;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class StreamingChunkEvent extends ChatEvent {\n readonly messageId: string;\n readonly chunk: string;\n readonly isFinal: boolean;\n\n constructor(\n threadId: string,\n messageId: string,\n chunk: string,\n isFinal: boolean,\n timestamp?: number,\n ) {\n super(\"streaming.chunk\", threadId, timestamp ?? Date.now());\n this.messageId = messageId;\n this.chunk = chunk;\n this.isFinal = isFinal;\n }\n}\n","import { ChatEvent } from \"./base/ChatEvent\";\n\nexport class DMRequestedEvent extends ChatEvent {\n readonly userId: string;\n\n constructor(threadId: string, userId: string, timestamp?: number) {\n super(\"dm.requested\", threadId, timestamp ?? Date.now());\n this.userId = userId;\n }\n}\n","import { ChatEvent, UnknownEvent } from \"./base/ChatEvent\";\nimport type { Card, User } from \"../types\";\nimport { MessagePostedEvent } from \"./MessagePostedEvent\";\nimport { MessageEditedEvent } from \"./MessageEditedEvent\";\nimport { MessageDeletedEvent } from \"./MessageDeletedEvent\";\nimport { ReactionAddedEvent } from \"./ReactionAddedEvent\";\nimport { ReactionRemovedEvent } from \"./ReactionRemovedEvent\";\nimport { TypingStartedEvent } from \"./TypingStartedEvent\";\nimport { StreamingChunkEvent } from \"./StreamingChunkEvent\";\nimport { DMRequestedEvent } from \"./DMRequestedEvent\";\n\nfunction parseCard(value: unknown): Card | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const obj = value as Record<string, unknown>;\n if (typeof obj.type !== \"string\") return undefined;\n return obj as unknown as Card;\n}\n\nexport function parseChatEvent(json: Record<string, unknown>): ChatEvent {\n const type = json.type as string;\n const threadId = json.threadId as string;\n const timestamp = json.timestamp as number;\n const data = (json.data ?? {}) as Record<string, unknown>;\n\n switch (type) {\n case \"message.posted\":\n return new MessagePostedEvent(\n threadId,\n data.messageId as string,\n data.text as string,\n data.author as User,\n parseCard(data.card),\n data.attachments as Array<{\n type: string;\n url?: string;\n name?: string;\n mimeType?: string;\n size?: number | null;\n }>,\n timestamp,\n );\n case \"message.edited\":\n return new MessageEditedEvent(\n threadId,\n data.messageId as string,\n data.newText as string,\n parseCard(data.card),\n timestamp,\n );\n case \"message.deleted\":\n return new MessageDeletedEvent(threadId, data.messageId as string, timestamp);\n case \"reaction.added\":\n return new ReactionAddedEvent(\n threadId,\n data.messageId as string,\n data.emoji as string,\n data.user as User,\n timestamp,\n );\n case \"reaction.removed\":\n return new ReactionRemovedEvent(\n threadId,\n data.messageId as string,\n data.emoji as string,\n data.user as User,\n timestamp,\n );\n case \"typing.started\":\n return new TypingStartedEvent(threadId, data.userId as string, timestamp);\n case \"streaming.chunk\":\n return new StreamingChunkEvent(\n threadId,\n data.messageId as string,\n data.chunk as string,\n data.isFinal as boolean,\n timestamp,\n );\n case \"dm.requested\":\n return new DMRequestedEvent(threadId, data.userId as string, timestamp);\n default:\n return new UnknownEvent(type, threadId, data, timestamp);\n }\n}\n\n// Wire up the static method\nChatEvent.fromJSON = parseChatEvent;\n","export function generateId(): string {\n return `msg-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\nexport function generateConversationId(): string {\n return `conv-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n","import { HttpClient } from \"./HttpClient\";\nimport type { BroadcastClient, EventHandlers, Unsubscribe } from \"./BroadcastClient\";\nimport type { Message } from \"../types\";\nimport { ChatEvent } from \"../events/base/ChatEvent\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type { MessagePostedEvent } from \"../events/MessagePostedEvent\";\nimport type { MessageEditedEvent } from \"../events/MessageEditedEvent\";\nimport type { MessageDeletedEvent } from \"../events/MessageDeletedEvent\";\nimport type { ReactionAddedEvent } from \"../events/ReactionAddedEvent\";\nimport type { ReactionRemovedEvent } from \"../events/ReactionRemovedEvent\";\nimport type { TypingStartedEvent } from \"../events/TypingStartedEvent\";\nimport type { StreamingChunkEvent } from \"../events/StreamingChunkEvent\";\nimport type { DMRequestedEvent } from \"../events/DMRequestedEvent\";\nimport { generateId, generateConversationId } from \"../utils/eventIdGenerator\";\n\nexport interface ReconfigureConfig {\n userId?: string;\n userName?: string;\n verifyToken?: string;\n conversationId?: string;\n headers?: Record<string, string>;\n}\n\nexport interface WebChatClientConfig {\n apiUrl: string;\n userId: string;\n userName: string;\n broadcastClient?: BroadcastClient;\n headers?: Record<string, string>;\n verifyToken?: string;\n conversationId?: string;\n endpoints?: {\n sendMessage?: string;\n loadMessages?: string;\n editMessage?: string;\n deleteMessage?: string;\n addReaction?: string;\n removeReaction?: string;\n };\n features?: {\n editMessages?: boolean;\n deleteMessages?: boolean;\n reactions?: boolean;\n };\n}\n\ninterface StreamingState {\n messageId: string;\n accumulatedText: string;\n isComplete: boolean;\n}\n\ninterface AttachmentInput {\n url: string;\n name?: string;\n mimeType?: string;\n size?: number;\n}\n\nexport interface LoadMessagesOptions {\n limit?: number;\n before?: number;\n after?: number;\n skipStateSeed?: boolean;\n}\n\nexport interface LoadMessagesResult {\n messages: Message[];\n hasMore: boolean;\n nextCursor?: number;\n prevCursor?: number;\n}\n\nexport class WebChatClient {\n private config: WebChatClientConfig;\n private httpClient: HttpClient;\n private broadcastClient?: BroadcastClient;\n private conversationId: string;\n private messages: Message[] = [];\n private currentUserId: string;\n private eventHandlers: EventHandlers = {};\n private streamingMessages: Map<string, StreamingState> = new Map();\n private pendingTyping: ReturnType<typeof setTimeout> | null = null;\n private subscribers: Map<string, Array<(event: unknown) => void>> = new Map();\n private unsubscribeUserChannel?: Unsubscribe;\n\n constructor(config: WebChatClientConfig) {\n this.config = config;\n this.httpClient = new HttpClient({\n apiUrl: config.apiUrl,\n headers: {\n \"X-User-Id\": config.userId,\n \"X-User-Name\": config.userName,\n ...(config.headers ?? {}),\n },\n verifyToken: config.verifyToken,\n });\n this.broadcastClient = config.broadcastClient;\n this.conversationId = config.conversationId ?? generateConversationId();\n this.currentUserId = config.userId;\n }\n\n reconfigure(config: ReconfigureConfig): void {\n if (config.userId) {\n this.currentUserId = config.userId;\n this.httpClient.setHeader(\"X-User-Id\", config.userId);\n }\n if (config.userName) {\n this.config = { ...this.config, userName: config.userName };\n this.httpClient.setHeader(\"X-User-Name\", config.userName);\n }\n if (config.verifyToken) {\n this.config = { ...this.config, verifyToken: config.verifyToken };\n this.httpClient.setHeader(\"X-Verify-Token\", config.verifyToken);\n }\n if (config.conversationId) {\n this.conversationId = config.conversationId;\n }\n if (config.headers) {\n Object.entries(config.headers).forEach(([key, value]) => {\n this.httpClient.setHeader(key, value);\n });\n }\n }\n\n setLocaleHeader(locale: string): void {\n this.httpClient.setHeader(\"X-Locale\", locale);\n this.httpClient.setHeader(\"X-Language\", locale.split(\"-\")[0] ?? locale);\n }\n\n setTimezoneHeader(timezone: string): void {\n this.httpClient.setHeader(\"X-Timezone\", timezone);\n }\n\n async connect(): Promise<void> {\n if (this.broadcastClient) {\n this.broadcastClient.connect();\n\n const threadId = this.getThreadId();\n const threadEvents: EventHandlers = {\n onMessagePosted: (event) => this.handleMessagePosted(event),\n };\n\n if (this.config.features?.editMessages) {\n threadEvents.onMessageEdited = (event) => this.handleMessageEdited(event);\n }\n if (this.config.features?.deleteMessages) {\n threadEvents.onMessageDeleted = (event) => this.handleMessageDeleted(event);\n }\n if (this.config.features?.reactions) {\n threadEvents.onReactionAdded = (event) => this.handleReactionAdded(event);\n threadEvents.onReactionRemoved = (event) => this.handleReactionRemoved(event);\n }\n\n await this.broadcastClient.subscribe(threadId, threadEvents);\n\n this.unsubscribeUserChannel = await this.broadcastClient.subscribeToUser(\n threadId,\n this.currentUserId,\n {\n onTypingStarted: (event) => this.handleTypingStarted(event),\n onStreamingChunk: (event) => this.handleStreamingChunk(event),\n onDMRequested: (event) => this.handleDMRequested(event),\n },\n );\n }\n }\n\n disconnect(): void {\n this.unsubscribeUserChannel?.();\n this.unsubscribeUserChannel = undefined;\n this.broadcastClient?.disconnect();\n this.streamingMessages.clear();\n }\n\n async loadMessages(\n options?: LoadMessagesOptions,\n signal?: AbortSignal,\n ): Promise<LoadMessagesResult> {\n const endpoint = this.config.endpoints?.loadMessages ?? \"/api/chat/messages\";\n const threadId = this.getThreadId();\n const params = new URLSearchParams({\n threadId,\n limit: String(options?.limit ?? 50),\n });\n if (options?.before) params.set(\"before\", String(options.before));\n if (options?.after) params.set(\"after\", String(options.after));\n\n const response = (await this.httpClient.get(\n `${endpoint}?${params.toString()}`,\n signal,\n )) as Record<string, unknown>;\n const rawMessages = (response.messages as Record<string, unknown>[]) ?? [];\n const messages: Message[] = rawMessages.map((msg) => ({\n id: msg.id as string,\n threadId,\n content: {\n text: msg.text as string,\n cards: msg.card ? ([msg.card as Record<string, unknown>] as never[]) : undefined,\n },\n author: {\n id: (msg.author as Record<string, unknown>).id as string,\n name: (msg.author as Record<string, unknown>).name as string,\n isBot: ((msg.author as Record<string, unknown>).isBot as boolean) ?? false,\n isMe: (msg.author as Record<string, unknown>).id === this.currentUserId,\n },\n timestamp: msg.timestamp as number,\n attachments: (msg.attachments as Record<string, unknown>[])?.map((a) => ({\n id: `att-${msg.id as string}-${a.url as string}`,\n url: a.url as string,\n name: a.name as string,\n type: a.type as string,\n mimeType: a.mime_type as string,\n size: a.size as number,\n })),\n reactions: (msg.reactions as { emoji: string; count: number; users: string[] }[]) ?? [],\n }));\n\n if (!options?.before && !options?.after && !options?.skipStateSeed) {\n this.messages = messages;\n this.notifySubscribers(\"messages:loaded\", messages);\n }\n\n return {\n messages,\n hasMore: (response.hasMore as boolean) ?? false,\n nextCursor: response.nextCursor as number | undefined,\n prevCursor: response.prevCursor as number | undefined,\n };\n }\n\n async sendMessage(text: string, attachments: AttachmentInput[] = []): Promise<void> {\n const messageId = generateId();\n\n const userMessage: Message = {\n id: messageId,\n threadId: this.getThreadId(),\n content: { text },\n author: { id: this.currentUserId, name: this.config.userName, isMe: true },\n timestamp: Date.now(),\n attachments:\n attachments.length > 0\n ? attachments.map((a, i) => ({\n id: `att-${messageId}-${i}`,\n name: a.name ?? \"\",\n url: a.url,\n size: a.size,\n mimeType: a.mimeType,\n }))\n : undefined,\n };\n\n this.messages.push(userMessage);\n this.notifySubscribers(\"message:added\", userMessage);\n\n const endpoint = this.config.endpoints?.sendMessage ?? \"/api/webhooks/web\";\n const response = await this.httpClient.sendMessage(\n [\n {\n id: messageId,\n role: \"user\",\n text,\n attachments: attachments.map((a) => ({\n url: a.url,\n name: a.name,\n mime_type: a.mimeType,\n size: a.size,\n })),\n },\n ],\n endpoint,\n this.conversationId,\n );\n\n if (response.events) {\n response.events.forEach((eventData) => {\n const event = parseChatEvent(eventData);\n this.dispatchEvent(event);\n });\n }\n\n if (response.text && !response.events?.some((e) => e.type === \"message.posted\")) {\n const assistantMessage: Message = {\n id: response.id ?? generateId(),\n threadId: this.getThreadId(),\n content: { text: response.text },\n author: { id: \"assistant\", name: \"Assistant\", isBot: true },\n timestamp: Date.now(),\n attachments: (response.attachments as Record<string, unknown>[])?.map((a, i) => ({\n id: `att-${response.id ?? \"msg\"}-${i}`,\n name: (a.name as string) ?? \"\",\n url: (a.url as string) ?? \"\",\n type: a.type as string,\n mimeType: a.mime_type as string,\n size: a.size as number,\n })),\n };\n this.messages.push(assistantMessage);\n this.notifySubscribers(\"message:added\", assistantMessage);\n }\n }\n\n async sendAction(messageId: string, actionId: string, value: string): Promise<void> {\n const endpoint = this.config.endpoints?.sendMessage ?? \"/api/webhooks/web\";\n const response = await this.httpClient.sendAction(\n actionId,\n value,\n messageId,\n this.conversationId,\n endpoint,\n );\n\n if (response.events) {\n (response.events as Array<Record<string, unknown>>).forEach((eventData) => {\n const event = parseChatEvent(eventData);\n this.dispatchEvent(event);\n });\n }\n }\n\n async editMessage(messageId: string, newText: string): Promise<void> {\n if (!this.config.features?.editMessages) {\n throw new Error(\"Edit messages not enabled. Set features.editMessages = true in config.\");\n }\n const endpoint = this.config.endpoints?.editMessage ?? \"/api/chat/messages/{id}/edit\";\n await this.httpClient.editMessage(messageId, newText, endpoint);\n }\n\n async deleteMessage(messageId: string): Promise<void> {\n if (!this.config.features?.deleteMessages) {\n throw new Error(\"Delete messages not enabled. Set features.deleteMessages = true in config.\");\n }\n const endpoint = this.config.endpoints?.deleteMessage ?? \"/api/chat/messages/{id}\";\n await this.httpClient.deleteMessage(messageId, endpoint);\n }\n\n async addReaction(messageId: string, emoji: string): Promise<void> {\n if (!this.config.features?.reactions) {\n throw new Error(\"Reactions not enabled. Set features.reactions = true in config.\");\n }\n const endpoint = this.config.endpoints?.addReaction ?? \"/api/chat/messages/{id}/reactions\";\n await this.httpClient.addReaction(messageId, emoji, endpoint);\n }\n\n async removeReaction(messageId: string, emoji: string): Promise<void> {\n if (!this.config.features?.reactions) {\n throw new Error(\"Reactions not enabled. Set features.reactions = true in config.\");\n }\n const endpoint =\n this.config.endpoints?.removeReaction ?? \"/api/chat/messages/{id}/reactions/{emoji}\";\n await this.httpClient.removeReaction(messageId, emoji, endpoint);\n }\n\n onMessagePosted(handler: (event: MessagePostedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message.posted\", handler);\n }\n\n onMessageEdited(handler: (event: MessageEditedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message:edited\", handler);\n }\n\n onMessageDeleted(handler: (event: MessageDeletedEvent) => void): Unsubscribe {\n return this.addEventListener(\"message:deleted\", handler);\n }\n\n onReactionAdded(handler: (event: ReactionAddedEvent) => void): Unsubscribe {\n return this.addEventListener(\"reaction:added\", handler);\n }\n\n onReactionRemoved(handler: (event: ReactionRemovedEvent) => void): Unsubscribe {\n return this.addEventListener(\"reaction:removed\", handler);\n }\n\n onStreamingChunk(handler: (event: StreamingChunkEvent) => void): Unsubscribe {\n return this.addEventListener(\"streaming:chunk\", handler);\n }\n\n onTypingStarted(handler: (event: TypingStartedEvent) => void): Unsubscribe {\n return this.addEventListener(\"typing:started\", handler);\n }\n\n getConversationId(): string {\n return this.conversationId;\n }\n getMessages(): Message[] {\n return [...this.messages];\n }\n getThreadId(): string {\n return `web:${this.currentUserId}:${this.conversationId}`;\n }\n getCurrentUserId(): string {\n return this.currentUserId;\n }\n getFeatures(): NonNullable<WebChatClientConfig[\"features\"]> {\n return this.config.features ?? {};\n }\n getEndpoints(): NonNullable<WebChatClientConfig[\"endpoints\"]> {\n return this.config.endpoints ?? {};\n }\n getHttpClient(): HttpClient {\n return this.httpClient;\n }\n\n addEventListener<T = unknown>(eventType: string, handler: (event: T) => void): Unsubscribe {\n if (!this.subscribers.has(eventType)) this.subscribers.set(eventType, []);\n this.subscribers.get(eventType)!.push(handler as (event: unknown) => void);\n return () => {\n const handlers = this.subscribers.get(eventType);\n if (handlers) {\n const index = handlers.indexOf(handler as (event: unknown) => void);\n if (index !== -1) handlers.splice(index, 1);\n }\n };\n }\n\n private handleMessagePosted(event: MessagePostedEvent): void {\n if (this.messages.some((m) => m.id === event.messageId)) return;\n if (this.streamingMessages.has(event.messageId)) return;\n\n const message: Message = {\n id: event.messageId,\n threadId: event.threadId,\n content: { text: event.text, cards: event.card ? [event.card] : undefined },\n author: event.author,\n timestamp: event.timestamp,\n attachments: event.attachments?.map((a) => ({\n id: `att-${event.messageId}-${Math.random().toString(36).slice(2, 8)}`,\n name: a.name ?? \"\",\n url: a.url ?? \"\",\n type: a.type,\n mimeType: a.mimeType,\n size: a.size ?? undefined,\n })),\n };\n this.messages.push(message);\n this.notifySubscribers(\"message:added\", message);\n this.notifySubscribers(\"message.posted\", event);\n }\n\n private handleMessageEdited(event: MessageEditedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (message?.content) {\n message.content.text = event.newText;\n this.notifySubscribers(\"message:edited\", event);\n }\n }\n\n private handleMessageDeleted(event: MessageDeletedEvent): void {\n const index = this.messages.findIndex((m) => m.id === event.messageId);\n if (index !== -1) {\n this.messages.splice(index, 1);\n this.notifySubscribers(\"message:deleted\", event);\n }\n }\n\n private handleReactionAdded(event: ReactionAddedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (!message) return;\n if (!message.reactions) message.reactions = [];\n\n const existing = message.reactions.find((r) => r.emoji === event.emoji);\n if (existing) {\n existing.count++;\n existing.users.push(event.user.id);\n } else {\n message.reactions.push({ emoji: event.emoji, count: 1, users: [event.user.id] });\n }\n this.notifySubscribers(\"reaction:added\", event);\n }\n\n private handleReactionRemoved(event: ReactionRemovedEvent): void {\n const message = this.messages.find((m) => m.id === event.messageId);\n if (!message?.reactions) return;\n\n const index = message.reactions.findIndex((r) => r.emoji === event.emoji);\n if (index !== -1) {\n const reaction = message.reactions[index]!;\n reaction.count--;\n reaction.users = reaction.users.filter((id) => id !== event.user.id);\n if (reaction.count === 0) message.reactions.splice(index, 1);\n }\n this.notifySubscribers(\"reaction:removed\", event);\n }\n\n private handleStreamingChunk(event: StreamingChunkEvent): void {\n const { messageId, chunk, isFinal } = event;\n\n if (!this.streamingMessages.has(messageId)) {\n this.streamingMessages.set(messageId, { messageId, accumulatedText: \"\", isComplete: false });\n this.notifySubscribers(\"streaming:started\", event);\n }\n\n const state = this.streamingMessages.get(messageId)!;\n state.accumulatedText += chunk;\n\n if (isFinal) {\n state.isComplete = true;\n if (!this.messages.some((m) => m.id === messageId)) {\n const message: Message = {\n id: messageId,\n threadId: event.threadId,\n content: { text: state.accumulatedText },\n author: { id: \"assistant\", name: \"Assistant\", isBot: true },\n timestamp: event.timestamp,\n };\n this.messages.push(message);\n this.notifySubscribers(\"message:added\", message);\n }\n this.streamingMessages.delete(messageId);\n this.notifySubscribers(\"streaming:complete\", { messageId, text: state.accumulatedText });\n } else {\n this.notifySubscribers(\"streaming:chunk\", event);\n }\n }\n\n private handleTypingStarted(event: TypingStartedEvent): void {\n if (this.pendingTyping) clearTimeout(this.pendingTyping);\n this.notifySubscribers(\"typing:started\", event);\n this.pendingTyping = setTimeout(() => {\n this.notifySubscribers(\"typing:stopped\", { userId: event.userId });\n }, 3000);\n }\n\n private handleDMRequested(event: DMRequestedEvent): void {\n this.notifySubscribers(\"dm.requested\", event);\n }\n\n private notifySubscribers<T>(eventType: string, data: T): void {\n this.subscribers.get(eventType)?.forEach((handler) => handler(data));\n }\n\n private dispatchEvent(event: ChatEvent): void {\n switch (event.type) {\n case \"message.posted\":\n this.handleMessagePosted(event as MessagePostedEvent);\n break;\n case \"message.edited\":\n this.handleMessageEdited(event as MessageEditedEvent);\n break;\n case \"message.deleted\":\n this.handleMessageDeleted(event as MessageDeletedEvent);\n break;\n case \"reaction.added\":\n this.handleReactionAdded(event as ReactionAddedEvent);\n break;\n case \"reaction.removed\":\n this.handleReactionRemoved(event as ReactionRemovedEvent);\n break;\n case \"typing.started\":\n this.handleTypingStarted(event as TypingStartedEvent);\n break;\n case \"streaming.chunk\":\n this.handleStreamingChunk(event as StreamingChunkEvent);\n break;\n case \"dm.requested\":\n this.handleDMRequested(event as DMRequestedEvent);\n break;\n }\n }\n}\n","import {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./BroadcastClient\";\nimport { ChatEvent } from \"../events/base/ChatEvent\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type Pusher from \"pusher-js\";\nimport type { Channel as PusherChannel } from \"pusher-js\";\n\nexport interface PusherConfig {\n key: string;\n cluster?: string;\n host?: string;\n port?: number;\n forceTLS?: boolean;\n authEndpoint?: string;\n}\n\nexport class PusherBroadcastClient implements BroadcastClient {\n private pusher: Pusher;\n private channelPrefix: string;\n private threadChannelType: \"public\" | \"private\" | \"presence\";\n private userChannelType: \"private\" | \"presence\";\n private useHashChannel: boolean;\n private subscriptions: Map<string, PusherChannel> = new Map();\n\n constructor(pusher: Pusher, channelPrefix?: string, channelTypes?: ChannelTypeConfig);\n constructor(config: PusherConfig, channelPrefix?: string, channelTypes?: ChannelTypeConfig);\n constructor(\n pusherOrConfig: Pusher | PusherConfig,\n channelPrefix: string = \"chat\",\n channelTypes?: ChannelTypeConfig,\n ) {\n this.channelPrefix = channelPrefix;\n this.threadChannelType = channelTypes?.threadChannel ?? \"public\";\n this.userChannelType = channelTypes?.userChannel ?? \"private\";\n this.useHashChannel = channelTypes?.useHashChannel ?? false;\n\n if (\"key\" in pusherOrConfig) {\n const PusherCtor = (globalThis as any).Pusher ?? (globalThis as any).pusherJs;\n if (!PusherCtor) {\n throw new Error(\"pusher-js not found. Install it or pass a Pusher instance.\");\n }\n this.pusher = new PusherCtor((pusherOrConfig as PusherConfig).key, pusherOrConfig) as Pusher;\n } else {\n this.pusher = pusherOrConfig as Pusher;\n }\n }\n\n private buildChannelName(base: string, type: \"public\" | \"private\" | \"presence\"): string {\n switch (type) {\n case \"private\":\n return `private-${base}`;\n case \"presence\":\n return `presence-${base}`;\n default:\n return base;\n }\n }\n\n protected async buildResolvedChannelName(threadId: string): Promise<string> {\n const name = this.useHashChannel ? await this.hashChannelName(threadId) : threadId;\n\n return `${this.channelPrefix}.${name}`;\n }\n\n private async hashChannelName(name: string): Promise<string> {\n if (typeof crypto?.subtle?.digest !== \"function\") {\n throw new Error(\"Web Crypto API not available. Cannot hash channel names.\");\n }\n const encoder = new TextEncoder();\n const data = encoder.encode(name);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n\n connect(): void {\n if (this.pusher.connection?.state !== \"connected\") {\n this.pusher.connect();\n }\n }\n\n disconnect(): void {\n this.subscriptions.forEach((channel) => channel.unbind_all?.() ?? channel.unsubscribe?.());\n this.subscriptions.clear();\n this.pusher.disconnect?.();\n }\n\n async subscribe(threadId: string, handlers: EventHandlers): Promise<Unsubscribe> {\n const baseName = await this.buildResolvedChannelName(threadId);\n const channelName = this.buildChannelName(baseName, this.threadChannelType);\n const channel = this.pusher.subscribe(channelName);\n const key = `thread:${threadId}`;\n this.subscriptions.set(key, channel);\n\n const threadEvents = [\n \"message.posted\",\n \"message.edited\",\n \"message.deleted\",\n \"reaction.added\",\n \"reaction.removed\",\n ] as const;\n\n threadEvents.forEach((eventType) => {\n const eventName = `${this.channelPrefix}.${eventType}`;\n channel.bind(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n this.dispatchToHandler(event, handlers);\n });\n });\n\n return () => {\n channel.unbind_all?.();\n this.pusher.unsubscribe(channelName);\n this.subscriptions.delete(key);\n };\n }\n\n async subscribeToUser(\n threadId: string,\n userId: string,\n handlers: EventHandlers,\n ): Promise<Unsubscribe> {\n const baseName = `${await this.buildResolvedChannelName(threadId)}.${userId}`;\n const channelName = this.buildChannelName(baseName, this.userChannelType);\n const channel = this.pusher.subscribe(channelName);\n const key = `user:${threadId}:${userId}`;\n this.subscriptions.set(key, channel);\n\n const userEvents = [\"typing.started\", \"streaming.chunk\", \"dm.requested\"] as const;\n\n userEvents.forEach((eventType) => {\n const eventName = `${this.channelPrefix}.${eventType}`;\n channel.bind(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n this.dispatchToHandler(event, handlers);\n });\n });\n\n return () => {\n channel.unbind_all?.();\n this.pusher.unsubscribe(channelName);\n this.subscriptions.delete(key);\n };\n }\n\n isConnected(): boolean {\n return this.pusher.connection?.state === \"connected\";\n }\n\n private dispatchToHandler(event: ChatEvent, handlers: EventHandlers): void {\n switch (event.type) {\n case \"message.posted\":\n handlers.onMessagePosted?.(event as any);\n break;\n case \"message.edited\":\n handlers.onMessageEdited?.(event as any);\n break;\n case \"message.deleted\":\n handlers.onMessageDeleted?.(event as any);\n break;\n case \"reaction.added\":\n handlers.onReactionAdded?.(event as any);\n break;\n case \"reaction.removed\":\n handlers.onReactionRemoved?.(event as any);\n break;\n case \"typing.started\":\n handlers.onTypingStarted?.(event as any);\n break;\n case \"streaming.chunk\":\n handlers.onStreamingChunk?.(event as any);\n break;\n case \"dm.requested\":\n handlers.onDMRequested?.(event as any);\n break;\n }\n }\n}\n","import {\n type BroadcastClient,\n type EventHandlers,\n type Unsubscribe,\n type ChannelTypeConfig,\n} from \"./BroadcastClient\";\nimport { parseChatEvent } from \"../events/ChatEventFactory\";\nimport type Echo from \"laravel-echo\";\n\ninterface EchoChannel {\n listen(event: string, callback: (data: unknown) => void): this;\n unsubscribe(): void;\n stopListening(event?: string, callback?: (data: unknown) => void): this;\n}\n\nexport class LaravelEchoBroadcastClient implements BroadcastClient {\n private echo: Echo<any>;\n private channelPrefix: string;\n private threadChannelType: \"public\" | \"private\" | \"presence\";\n private userChannelType: \"private\" | \"presence\";\n private useHashChannel: boolean;\n private subscriptions: Map<string, EchoChannel> = new Map();\n\n constructor(echo: Echo<any>, channelPrefix: string = \"chat\", channelTypes?: ChannelTypeConfig) {\n this.echo = echo;\n this.channelPrefix = channelPrefix;\n this.threadChannelType = channelTypes?.threadChannel ?? \"public\";\n this.userChannelType = channelTypes?.userChannel ?? \"private\";\n this.useHashChannel = channelTypes?.useHashChannel ?? false;\n }\n\n private subscribeToEcho(name: string, type: \"public\" | \"private\" | \"presence\"): EchoChannel {\n switch (type) {\n case \"private\":\n return this.echo.private(name) as unknown as EchoChannel;\n case \"presence\":\n return this.echo.join(name) as unknown as EchoChannel;\n default:\n return this.echo.channel(name) as unknown as EchoChannel;\n }\n }\n\n connect(): void | Promise<void> {\n return Promise.resolve();\n }\n\n disconnect(): void {\n this.subscriptions.forEach((channel) => {\n channel.unsubscribe?.();\n channel.stopListening?.();\n });\n this.subscriptions.clear();\n }\n\n protected async buildResolvedChannelName(threadId: string): Promise<string> {\n const name = this.useHashChannel ? await this.hashChannelName(threadId) : threadId;\n\n return `${this.channelPrefix}.${name}`;\n }\n\n private async hashChannelName(name: string): Promise<string> {\n if (typeof crypto?.subtle?.digest !== \"function\") {\n throw new Error(\"Web Crypto API not available. Cannot hash channel names.\");\n }\n const encoder = new TextEncoder();\n const data = encoder.encode(name);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n }\n\n async subscribe(threadId: string, handlers: EventHandlers): Promise<Unsubscribe> {\n const channelName = await this.buildResolvedChannelName(threadId);\n const channel = this.subscribeToEcho(channelName, this.threadChannelType);\n const key = `thread:${threadId}`;\n this.subscriptions.set(key, channel);\n\n const threadEvents: Array<{ type: string; handler: keyof EventHandlers }> = [\n { type: \"message.posted\", handler: \"onMessagePosted\" },\n { type: \"message.edited\", handler: \"onMessageEdited\" },\n { type: \"message.deleted\", handler: \"onMessageDeleted\" },\n { type: \"reaction.added\", handler: \"onReactionAdded\" },\n { type: \"reaction.removed\", handler: \"onReactionRemoved\" },\n ];\n\n threadEvents.forEach(({ type, handler }) => {\n const eventName = `.${this.channelPrefix}.${type}`;\n channel.listen(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n (handlers[handler] as any)?.(event);\n });\n });\n\n return () => {\n channel.unsubscribe?.();\n this.subscriptions.delete(key);\n };\n }\n\n async subscribeToUser(\n threadId: string,\n userId: string,\n handlers: EventHandlers,\n ): Promise<Unsubscribe> {\n const channelName = `${await this.buildResolvedChannelName(threadId)}.${userId}`;\n const channel = this.subscribeToEcho(channelName, this.userChannelType);\n const key = `user:${threadId}:${userId}`;\n this.subscriptions.set(key, channel);\n\n const userEvents: Array<{ type: string; handler: keyof EventHandlers }> = [\n { type: \"typing.started\", handler: \"onTypingStarted\" },\n { type: \"streaming.chunk\", handler: \"onStreamingChunk\" },\n { type: \"dm.requested\", handler: \"onDMRequested\" },\n ];\n\n userEvents.forEach(({ type, handler }) => {\n const eventName = `.${this.channelPrefix}.${type}`;\n channel.listen(eventName, (data: unknown) => {\n const event = parseChatEvent(data as Record<string, unknown>);\n (handlers[handler] as any)?.(event);\n });\n });\n\n return () => {\n channel.unsubscribe?.();\n this.subscriptions.delete(key);\n };\n }\n\n isConnected(): boolean {\n try {\n const connector = (this.echo as any).connector;\n if (!connector) return false;\n\n if (connector.pusher?.connection?.state === \"connected\") return true;\n if (connector.socket?.connected) return true;\n\n return false;\n } catch {\n return false;\n }\n }\n}\n","import type { PushConfig, PushSubscriptionStatus, PushEventData } from \"./types\";\n\nexport class PushManager {\n private config: PushConfig;\n private registration: ServiceWorkerRegistration | null = null;\n private status: PushSubscriptionStatus = \"unsupported\";\n private statusListeners: Set<(status: PushSubscriptionStatus) => void> = new Set();\n private messageListeners: Set<(data: PushEventData) => void> = new Set();\n\n constructor(config: PushConfig) {\n this.config = config;\n }\n\n static isSupported(): boolean {\n return (\n typeof navigator !== \"undefined\" &&\n \"serviceWorker\" in navigator &&\n \"PushManager\" in window &&\n \"Notification\" in window\n );\n }\n\n getStatus(): PushSubscriptionStatus {\n return this.status;\n }\n\n onStatusChange(listener: (status: PushSubscriptionStatus) => void): () => void {\n this.statusListeners.add(listener);\n return () => {\n this.statusListeners.delete(listener);\n };\n }\n\n onMessage(listener: (data: PushEventData) => void): () => void {\n this.messageListeners.add(listener);\n return () => {\n this.messageListeners.delete(listener);\n };\n }\n\n async initialize(): Promise<void> {\n if (!PushManager.isSupported()) {\n this.setStatus(\"unsupported\");\n return;\n }\n if (Notification.permission === \"denied\") {\n this.setStatus(\"denied\");\n return;\n }\n\n try {\n this.registration = await navigator.serviceWorker.register(\n this.config.serviceWorkerUrl || \"/chat-service-worker.js\",\n {\n scope: this.config.serviceWorkerScope || \"/\",\n type: this.config.serviceWorkerType,\n },\n );\n await navigator.serviceWorker.ready;\n\n navigator.serviceWorker.addEventListener(\"message\", (event: MessageEvent) => {\n const msg = event.data as Record<string, unknown>;\n if (msg?.type === \"chat-widget:push-data\") {\n const pushData = msg.data as PushEventData;\n this.messageListeners.forEach((listener) => listener(pushData));\n }\n });\n\n const subscription = await this.registration.pushManager.getSubscription();\n this.setStatus(subscription ? \"subscribed\" : \"default\");\n } catch {\n this.setStatus(\"error\");\n }\n }\n\n async subscribe(): Promise<void> {\n if (!this.registration)\n throw new Error(\"PushManager not initialized. Call initialize() first.\");\n\n this.setStatus(\"subscribing\");\n\n try {\n let subscription = await this.registration.pushManager.getSubscription();\n\n if (!subscription) {\n const permission = await Notification.requestPermission();\n if (permission !== \"granted\") {\n this.setStatus(permission === \"denied\" ? \"denied\" : \"default\");\n return;\n }\n\n const vapidPublicKey = await this.config.getVapidPublicKey();\n const convertedKey = this.urlBase64ToUint8Array(vapidPublicKey);\n subscription = await this.registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: convertedKey.buffer as ArrayBuffer,\n });\n }\n\n await this.config.onSubscribe(subscription.toJSON());\n this.setStatus(\"subscribed\");\n } catch {\n this.setStatus(\"error\");\n throw new Error(\"Push subscription failed\");\n }\n }\n\n async unsubscribe(): Promise<void> {\n if (!this.registration) return;\n\n try {\n const subscription = await this.registration.pushManager.getSubscription();\n if (subscription) {\n await this.config.onUnsubscribe(subscription.toJSON());\n await subscription.unsubscribe();\n }\n this.setStatus(\"default\");\n } catch {\n this.setStatus(\"error\");\n throw new Error(\"Push unsubscription failed\");\n }\n }\n\n private urlBase64ToUint8Array(base64String: string): Uint8Array {\n const padding = \"=\".repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding).replace(/-/g, \"+\").replace(/_/g, \"/\");\n const rawData = atob(base64);\n return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0)));\n }\n\n private setStatus(status: PushSubscriptionStatus): void {\n this.status = status;\n this.statusListeners.forEach((listener) => listener(status));\n }\n}\n","import { HttpClient } from \"../client/HttpClient\";\nimport type { PushConfig } from \"./types\";\n\nexport function createPushSubscriptionHandlers(\n httpClient: HttpClient,\n userId: string,\n): Pick<PushConfig, \"onSubscribe\" | \"onUnsubscribe\"> {\n return {\n onSubscribe: async (subscription: PushSubscriptionJSON) => {\n await httpClient.post(\"/api/push/subscriptions\", {\n userId,\n subscription,\n userAgent: navigator.userAgent,\n });\n },\n onUnsubscribe: async (subscription: PushSubscriptionJSON) => {\n await httpClient.delete(\n `/api/push/subscriptions?userId=${encodeURIComponent(userId)}&endpoint=${encodeURIComponent(subscription.endpoint || \"\")}`,\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED