@cossistant/core 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.d.ts +14 -2
- package/client.d.ts.map +1 -1
- package/client.js +25 -4
- package/client.js.map +1 -1
- package/env.d.ts +1 -0
- package/index.d.ts +7 -4
- package/index.js +6 -3
- package/package.json +1 -1
- package/realtime-client.d.ts +85 -0
- package/realtime-client.d.ts.map +1 -0
- package/realtime-client.js +463 -0
- package/realtime-client.js.map +1 -0
- package/realtime-event-filter.d.ts +15 -0
- package/realtime-event-filter.d.ts.map +1 -0
- package/realtime-event-filter.js +40 -0
- package/realtime-event-filter.js.map +1 -0
- package/resolve-public-key.d.ts +31 -0
- package/resolve-public-key.d.ts.map +1 -0
- package/resolve-public-key.js +52 -0
- package/resolve-public-key.js.map +1 -0
- package/rest-client.d.ts.map +1 -1
- package/rest-client.js +3 -2
- package/rest-client.js.map +1 -1
- package/store/seen-store.d.ts +1 -1
- package/store/timeline-items-store.d.ts.map +1 -1
- package/store/timeline-items-store.js +1 -1
- package/store/typing-store.d.ts +1 -1
- package/types/src/api/contact.js +297 -0
- package/types/src/api/contact.js.map +1 -0
- package/types/src/api/timeline-item.js +1 -1
- package/types/src/api/visitor.js +301 -0
- package/types/src/api/visitor.js.map +1 -0
- package/types/src/enums.js +12 -1
- package/types/src/enums.js.map +1 -1
- package/types/src/realtime-events.d.ts +2 -1
- package/types/src/realtime-events.d.ts.map +1 -1
- package/types/src/realtime-events.js +349 -0
- package/types/src/realtime-events.js.map +1 -0
- package/types/src/schemas.js +49 -0
- package/types/src/schemas.js.map +1 -0
- package/types/src/trpc/conversation.js +124 -0
- package/types/src/trpc/conversation.js.map +1 -0
- package/utils.d.ts.map +1 -1
package/client.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { CreateConversationRequestBody, CreateConversationResponseBody, GetConversationRequest, GetConversationResponse, ListConversationsRequest, ListConversationsResponse, MarkConversationSeenRequestBody, MarkConversationSeenResponseBody, SetConversationTypingResponseBody, SubmitConversationRatingRequestBody, SubmitConversationRatingResponseBody } from "./types/src/api/conversation.js";
|
|
2
2
|
import { GetConversationTimelineItemsRequest, GetConversationTimelineItemsResponse, SendTimelineItemRequest, SendTimelineItemResponse, TimelineItem as TimelineItem$1 } from "./types/src/api/timeline-item.js";
|
|
3
3
|
import { Conversation } from "./types/src/schemas.js";
|
|
4
|
+
import { RealtimeClient } from "./realtime-client.js";
|
|
4
5
|
import { types_d_exports } from "./types.js";
|
|
5
6
|
import { CossistantRestClient } from "./rest-client.js";
|
|
6
7
|
import { ConversationsStore } from "./store/conversations-store.js";
|
|
8
|
+
import { SeenStore } from "./store/seen-store.js";
|
|
7
9
|
import { TimelineItemsStore } from "./store/timeline-items-store.js";
|
|
10
|
+
import { TypingStore } from "./store/typing-store.js";
|
|
8
11
|
import { WebsiteStore } from "./store/website-store.js";
|
|
9
12
|
import { AnyRealtimeEvent, DefaultMessage, IdentifyContactResponse, RealtimeEvent } from "@cossistant/types";
|
|
10
13
|
|
|
@@ -22,6 +25,12 @@ type InitiateConversationResult = {
|
|
|
22
25
|
conversation: Conversation;
|
|
23
26
|
defaultTimelineItems: TimelineItem$1[];
|
|
24
27
|
};
|
|
28
|
+
type CossistantClientOptions = {
|
|
29
|
+
/** Supply an external seen store so the client shares state with callers. */
|
|
30
|
+
seenStore?: SeenStore;
|
|
31
|
+
/** Supply an external typing store so the client shares state with callers. */
|
|
32
|
+
typingStore?: TypingStore;
|
|
33
|
+
};
|
|
25
34
|
declare class CossistantClient {
|
|
26
35
|
private restClient;
|
|
27
36
|
private config;
|
|
@@ -30,7 +39,10 @@ declare class CossistantClient {
|
|
|
30
39
|
readonly conversationsStore: ConversationsStore;
|
|
31
40
|
readonly timelineItemsStore: TimelineItemsStore;
|
|
32
41
|
readonly websiteStore: WebsiteStore;
|
|
33
|
-
|
|
42
|
+
readonly seenStore: SeenStore;
|
|
43
|
+
readonly typingStore: TypingStore;
|
|
44
|
+
readonly realtime: RealtimeClient;
|
|
45
|
+
constructor(config: types_d_exports.CossistantConfig, options?: CossistantClientOptions);
|
|
34
46
|
updateConfiguration(config: Partial<types_d_exports.CossistantConfig>): void;
|
|
35
47
|
getConfiguration(): types_d_exports.CossistantConfig;
|
|
36
48
|
isConversationPending(conversationId: string | null | undefined): boolean;
|
|
@@ -136,5 +148,5 @@ declare class CossistantClient {
|
|
|
136
148
|
destroy(): void;
|
|
137
149
|
}
|
|
138
150
|
//#endregion
|
|
139
|
-
export { CossistantClient };
|
|
151
|
+
export { CossistantClient, CossistantClientOptions };
|
|
140
152
|
//# sourceMappingURL=client.d.ts.map
|
package/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","names":[],"sources":["../src/client.ts"],"sourcesContent":[],"mappings":"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"}
|
package/client.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { ConversationStatus, ConversationTimelineType, SenderType, TimelineItemVisibility } from "./types/src/enums.js";
|
|
2
|
+
import { RealtimeClient } from "./realtime-client.js";
|
|
3
|
+
import { shouldDeliverEvent } from "./realtime-event-filter.js";
|
|
2
4
|
import { generateConversationId, generateMessageId } from "./utils.js";
|
|
3
5
|
import { CossistantRestClient } from "./rest-client.js";
|
|
4
6
|
import { createConversationsStore } from "./store/conversations-store.js";
|
|
7
|
+
import { applyConversationSeenEvent, createSeenStore } from "./store/seen-store.js";
|
|
5
8
|
import { createTimelineItemsStore } from "./store/timeline-items-store.js";
|
|
9
|
+
import { applyConversationTypingEvent, clearTypingFromTimelineItem, createTypingStore } from "./store/typing-store.js";
|
|
6
10
|
import { createWebsiteStore } from "./store/website-store.js";
|
|
7
11
|
|
|
8
12
|
//#region src/client.ts
|
|
@@ -14,12 +18,21 @@ var CossistantClient = class {
|
|
|
14
18
|
conversationsStore;
|
|
15
19
|
timelineItemsStore;
|
|
16
20
|
websiteStore;
|
|
17
|
-
|
|
21
|
+
seenStore;
|
|
22
|
+
typingStore;
|
|
23
|
+
realtime;
|
|
24
|
+
constructor(config, options) {
|
|
18
25
|
this.config = config;
|
|
19
26
|
this.restClient = new CossistantRestClient(config);
|
|
20
27
|
this.conversationsStore = createConversationsStore();
|
|
21
28
|
this.timelineItemsStore = createTimelineItemsStore();
|
|
22
29
|
this.websiteStore = createWebsiteStore();
|
|
30
|
+
this.seenStore = options?.seenStore ?? createSeenStore();
|
|
31
|
+
this.typingStore = options?.typingStore ?? createTypingStore();
|
|
32
|
+
this.realtime = new RealtimeClient({
|
|
33
|
+
wsUrl: config.wsUrl,
|
|
34
|
+
onEvent: (event) => this.handleRealtimeEvent(event)
|
|
35
|
+
});
|
|
23
36
|
}
|
|
24
37
|
updateConfiguration(config) {
|
|
25
38
|
this.config = {
|
|
@@ -223,13 +236,17 @@ var CossistantClient = class {
|
|
|
223
236
|
}
|
|
224
237
|
}
|
|
225
238
|
handleRealtimeEvent(event) {
|
|
239
|
+
const websiteId = this.restClient.getCurrentWebsiteId();
|
|
240
|
+
const visitorId = this.restClient.getCurrentVisitorId();
|
|
241
|
+
if (!shouldDeliverEvent(event, websiteId, visitorId)) return;
|
|
226
242
|
if (event.type === "conversationCreated") {
|
|
227
|
-
const { conversation
|
|
243
|
+
const { conversation } = event.payload;
|
|
228
244
|
this.conversationsStore.ingestConversation({
|
|
229
245
|
...conversation,
|
|
230
246
|
lastTimelineItem: conversation.lastTimelineItem ?? void 0
|
|
231
247
|
});
|
|
232
248
|
} else if (event.type === "timelineItemCreated") {
|
|
249
|
+
clearTypingFromTimelineItem(this.typingStore, event);
|
|
233
250
|
const timelineItem = this.timelineItemsStore.ingestRealtimeTimelineItem(event);
|
|
234
251
|
const existingConversation = this.conversationsStore.getState().byId[timelineItem.conversationId];
|
|
235
252
|
if (existingConversation) {
|
|
@@ -242,7 +259,9 @@ var CossistantClient = class {
|
|
|
242
259
|
};
|
|
243
260
|
this.conversationsStore.ingestConversation(nextConversation);
|
|
244
261
|
}
|
|
245
|
-
}
|
|
262
|
+
} else if (event.type === "conversationSeen") applyConversationSeenEvent(this.seenStore, event, { ignoreVisitorId: visitorId });
|
|
263
|
+
else if (event.type === "conversationTyping") applyConversationTypingEvent(this.typingStore, event, { ignoreVisitorId: visitorId });
|
|
264
|
+
else if (event.type === "conversationUpdated") this.handleConversationUpdated(event);
|
|
246
265
|
}
|
|
247
266
|
/**
|
|
248
267
|
* Extract conversation status from an event timeline item.
|
|
@@ -293,7 +312,9 @@ var CossistantClient = class {
|
|
|
293
312
|
async uploadFilesForMessage(files, conversationId) {
|
|
294
313
|
return this.restClient.uploadFilesForMessage(files, conversationId);
|
|
295
314
|
}
|
|
296
|
-
destroy() {
|
|
315
|
+
destroy() {
|
|
316
|
+
this.realtime.destroy();
|
|
317
|
+
}
|
|
297
318
|
};
|
|
298
319
|
function normalizeBootstrapTimelineItem(conversationId, item) {
|
|
299
320
|
if (isDefaultMessage(item)) {
|
package/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["current: WebsiteState","conversation: Conversation","optimisticTimelineItem: TimelineItem","payload: SendTimelineItemRequest","createdAt"],"sources":["../src/client.ts"],"sourcesContent":["import {\n\ttype AnyRealtimeEvent,\n\ttype DefaultMessage,\n\tgetEventPayload,\n\ttype IdentifyContactResponse,\n\ttype RealtimeEvent,\n} from \"@cossistant/types\";\nimport type {\n\tCreateConversationRequestBody,\n\tCreateConversationResponseBody,\n\tGetConversationRequest,\n\tGetConversationResponse,\n\tListConversationsRequest,\n\tListConversationsResponse,\n\tMarkConversationSeenRequestBody,\n\tMarkConversationSeenResponseBody,\n\tSetConversationTypingResponseBody,\n\tSubmitConversationRatingRequestBody,\n\tSubmitConversationRatingResponseBody,\n} from \"@cossistant/types/api/conversation\";\nimport type {\n\tGetConversationTimelineItemsRequest,\n\tGetConversationTimelineItemsResponse,\n\tSendTimelineItemRequest,\n\tSendTimelineItemResponse,\n\tTimelineItem,\n} from \"@cossistant/types/api/timeline-item\";\nimport {\n\tConversationStatus,\n\tConversationTimelineType,\n\tSenderType,\n\tTimelineItemVisibility,\n} from \"@cossistant/types/enums\";\nimport type { Conversation } from \"@cossistant/types/schemas\";\nimport { CossistantRestClient } from \"./rest-client\";\nimport {\n\ttype ConversationsStore,\n\tcreateConversationsStore,\n} from \"./store/conversations-store\";\nimport {\n\tcreateTimelineItemsStore,\n\ttype TimelineItemsStore,\n} from \"./store/timeline-items-store\";\nimport {\n\tcreateWebsiteStore,\n\ttype WebsiteState,\n\ttype WebsiteStore,\n} from \"./store/website-store\";\nimport type {\n\tCossistantConfig,\n\tPublicWebsiteResponse,\n\tVisitorMetadata,\n\tVisitorResponse,\n} from \"./types\";\nimport { generateConversationId, generateMessageId } from \"./utils\";\n\ntype PendingConversation = {\n\tconversation: Conversation;\n\tinitialTimelineItems: TimelineItem[];\n};\n\ntype InitiateConversationParams = {\n\tconversationId?: string;\n\tvisitorId?: string | null;\n\twebsiteId?: string | null;\n\ttitle?: string;\n\tstatus?: Conversation[\"status\"];\n\tdefaultTimelineItems?: Array<DefaultMessage | TimelineItem>;\n};\n\ntype InitiateConversationResult = {\n\tconversationId: string;\n\tconversation: Conversation;\n\tdefaultTimelineItems: TimelineItem[];\n};\n\nexport class CossistantClient {\n\tprivate restClient: CossistantRestClient;\n\tprivate config: CossistantConfig;\n\tprivate pendingConversations = new Map<string, PendingConversation>();\n\tprivate websiteRequest: Promise<PublicWebsiteResponse> | null = null;\n\treadonly conversationsStore: ConversationsStore;\n\treadonly timelineItemsStore: TimelineItemsStore;\n\treadonly websiteStore: WebsiteStore;\n\n\tconstructor(config: CossistantConfig) {\n\t\tthis.config = config;\n\t\tthis.restClient = new CossistantRestClient(config);\n\t\tthis.conversationsStore = createConversationsStore();\n\t\tthis.timelineItemsStore = createTimelineItemsStore();\n\t\tthis.websiteStore = createWebsiteStore();\n\t}\n\n\t// Configuration updates\n\tupdateConfiguration(config: Partial<CossistantConfig>): void {\n\t\tthis.config = { ...this.config, ...config };\n\t\tthis.restClient.updateConfiguration(config);\n\t}\n\n\t// Utility methods\n\tgetConfiguration(): CossistantConfig {\n\t\treturn { ...this.config };\n\t}\n\n\tisConversationPending(conversationId: string | null | undefined): boolean {\n\t\tif (!conversationId) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.pendingConversations.has(conversationId);\n\t}\n\n\t// Website information\n\tasync fetchWebsite(\n\t\tparams: { force?: boolean } = {}\n\t): Promise<PublicWebsiteResponse> {\n\t\tconst { force = false } = params;\n\t\tconst current: WebsiteState = this.websiteStore.getState();\n\n\t\tif (!force) {\n\t\t\tif (current.status === \"success\" && current.website) {\n\t\t\t\treturn current.website;\n\t\t\t}\n\t\t\tif (this.websiteRequest) {\n\t\t\t\treturn this.websiteRequest;\n\t\t\t}\n\t\t}\n\n\t\tthis.websiteStore.setLoading();\n\n\t\tconst request = this.restClient\n\t\t\t.getWebsite()\n\t\t\t.then((website) => {\n\t\t\t\tthis.websiteStore.setWebsite(website);\n\t\t\t\treturn website;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.websiteStore.setError(error);\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (this.websiteRequest === request) {\n\t\t\t\t\tthis.websiteRequest = null;\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.websiteRequest = request;\n\n\t\treturn request;\n\t}\n\n\tasync getWebsite(): Promise<PublicWebsiteResponse> {\n\t\treturn this.fetchWebsite({ force: true });\n\t}\n\n\tsetWebsiteContext(websiteId: string, visitorId?: string): void {\n\t\tthis.restClient.setWebsiteContext(websiteId, visitorId);\n\t}\n\n\tsetVisitorBlocked(isBlocked: boolean): void {\n\t\tthis.restClient.setVisitorBlocked(isBlocked);\n\t}\n\n\tasync updateVisitorMetadata(\n\t\tmetadata: VisitorMetadata\n\t): Promise<VisitorResponse> {\n\t\treturn this.restClient.updateVisitorMetadata(metadata);\n\t}\n\n\tasync identify(params: {\n\t\texternalId?: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t\tcontactOrganizationId?: string;\n\t}): Promise<IdentifyContactResponse> {\n\t\treturn this.restClient.identify(params);\n\t}\n\n\tasync updateContactMetadata(\n\t\tmetadata: Record<string, unknown>\n\t): Promise<VisitorResponse> {\n\t\treturn this.restClient.updateContactMetadata(metadata);\n\t}\n\n\t// Conversation management\n\tinitiateConversation(\n\t\tparams: InitiateConversationParams = {}\n\t): InitiateConversationResult {\n\t\tconst conversationId = params.conversationId ?? generateConversationId();\n\t\tconst now = typeof window !== \"undefined\" ? new Date().toISOString() : \"\";\n\t\tconst timelineItems = (params.defaultTimelineItems ?? []).map((item) =>\n\t\t\tnormalizeBootstrapTimelineItem(conversationId, item)\n\t\t);\n\t\tconst existing = this.conversationsStore.getState().byId[conversationId];\n\t\tconst baseVisitorId =\n\t\t\tparams.visitorId ?? this.restClient.getCurrentVisitorId() ?? \"\";\n\t\tconst baseWebsiteId =\n\t\t\tparams.websiteId ?? this.restClient.getCurrentWebsiteId() ?? \"\";\n\n\t\tconst conversation: Conversation = existing\n\t\t\t? {\n\t\t\t\t\t...existing,\n\t\t\t\t\ttitle: params.title ?? existing.title,\n\t\t\t\t\tstatus: params.status ?? existing.status,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t\tlastTimelineItem: timelineItems.at(-1) ?? existing.lastTimelineItem,\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tid: conversationId,\n\t\t\t\t\ttitle: params.title,\n\t\t\t\t\tcreatedAt: now,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t\tvisitorId: baseVisitorId,\n\t\t\t\t\twebsiteId: baseWebsiteId,\n\t\t\t\t\tstatus: params.status ?? ConversationStatus.OPEN,\n\t\t\t\t\tdeletedAt: null,\n\t\t\t\t\tlastTimelineItem: timelineItems.at(-1),\n\t\t\t\t};\n\n\t\tthis.conversationsStore.ingestConversation(conversation);\n\n\t\tif (timelineItems.length > 0) {\n\t\t\tthis.timelineItemsStore.ingestPage(conversationId, {\n\t\t\t\titems: timelineItems,\n\t\t\t\thasNextPage: false,\n\t\t\t\tnextCursor: undefined,\n\t\t\t});\n\t\t}\n\n\t\tif (!existing || this.pendingConversations.has(conversationId)) {\n\t\t\tthis.pendingConversations.set(conversationId, {\n\t\t\t\tconversation,\n\t\t\t\tinitialTimelineItems: timelineItems,\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\tconversationId,\n\t\t\tconversation,\n\t\t\tdefaultTimelineItems: timelineItems,\n\t\t};\n\t}\n\n\tasync createConversation(\n\t\tparams?: Partial<CreateConversationRequestBody>\n\t): Promise<CreateConversationResponseBody> {\n\t\tconst response = await this.restClient.createConversation(params);\n\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\treturn response;\n\t}\n\n\tasync listConversations(\n\t\tparams?: Partial<ListConversationsRequest>\n\t): Promise<ListConversationsResponse> {\n\t\tconst response = await this.restClient.listConversations(params);\n\t\tthis.conversationsStore.ingestList(response);\n\t\treturn response;\n\t}\n\n\tasync getConversation(\n\t\tparams: GetConversationRequest\n\t): Promise<GetConversationResponse> {\n\t\tconst response = await this.restClient.getConversation(params);\n\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\treturn response;\n\t}\n\n\tasync markConversationSeen(\n\t\tparams: {\n\t\t\tconversationId: string;\n\t\t} & Partial<MarkConversationSeenRequestBody>\n\t): Promise<MarkConversationSeenResponseBody> {\n\t\treturn this.restClient.markConversationSeen(params);\n\t}\n\n\tasync getConversationSeenData(params: { conversationId: string }) {\n\t\treturn this.restClient.getConversationSeenData(params);\n\t}\n\n\tasync setVisitorTyping(params: {\n\t\tconversationId: string;\n\t\tisTyping: boolean;\n\t\tvisitorPreview?: string | null;\n\t\tvisitorId?: string;\n\t}): Promise<SetConversationTypingResponseBody> {\n\t\treturn this.restClient.setConversationTyping(params);\n\t}\n\n\tasync submitConversationRating(\n\t\tparams: {\n\t\t\tconversationId: string;\n\t\t} & SubmitConversationRatingRequestBody\n\t): Promise<SubmitConversationRatingResponseBody> {\n\t\tconst response = await this.restClient.submitConversationRating(params);\n\n\t\tconst existing =\n\t\t\tthis.conversationsStore.getState().byId[response.conversationId];\n\n\t\tif (existing) {\n\t\t\tthis.conversationsStore.ingestConversation({\n\t\t\t\t...existing,\n\t\t\t\tvisitorRating: response.rating,\n\t\t\t\tvisitorRatingAt: response.ratedAt,\n\t\t\t});\n\t\t}\n\n\t\treturn response;\n\t}\n\n\t// Timeline items management\n\n\tasync getConversationTimelineItems(\n\t\tparams: GetConversationTimelineItemsRequest & { conversationId: string }\n\t): Promise<GetConversationTimelineItemsResponse> {\n\t\tconst response = await this.restClient.getConversationTimelineItems(params);\n\t\tthis.timelineItemsStore.ingestPage(params.conversationId, {\n\t\t\titems: response.items,\n\t\t\thasNextPage: response.hasNextPage,\n\t\t\tnextCursor: response.nextCursor ?? undefined,\n\t\t});\n\t\treturn response;\n\t}\n\n\tasync sendMessage(\n\t\tparams: SendTimelineItemRequest & { createIfPending?: boolean }\n\t): Promise<\n\t\tSendTimelineItemResponse & {\n\t\t\tconversation?: Conversation;\n\t\t\tinitialTimelineItems?: TimelineItem[];\n\t\t\twasConversationCreated?: boolean;\n\t\t}\n\t> {\n\t\tconst { createIfPending, ...rest } = params;\n\t\tconst optimisticId = rest.item.id ?? generateMessageId();\n\t\tconst createdAt = rest.item.createdAt\n\t\t\t? rest.item.createdAt\n\t\t\t: typeof window !== \"undefined\"\n\t\t\t\t? new Date().toISOString()\n\t\t\t\t: \"\";\n\n\t\t// Add optimistic timeline item\n\t\tconst optimisticTimelineItem: TimelineItem = {\n\t\t\tid: optimisticId,\n\t\t\tconversationId: rest.conversationId,\n\t\t\torganizationId: \"\", // Not available yet\n\t\t\tvisibility: rest.item.visibility ?? TimelineItemVisibility.PUBLIC,\n\t\t\ttype: rest.item.type ?? ConversationTimelineType.MESSAGE,\n\t\t\ttext: rest.item.text,\n\t\t\ttool: rest.item.tool ?? null,\n\t\t\tparts:\n\t\t\t\trest.item.parts && rest.item.parts.length > 0\n\t\t\t\t\t? rest.item.parts\n\t\t\t\t\t: rest.item.text\n\t\t\t\t\t\t? [{ type: \"text\" as const, text: rest.item.text }]\n\t\t\t\t\t\t: [],\n\t\t\tuserId: rest.item.userId ?? null,\n\t\t\tvisitorId: rest.item.visitorId ?? null,\n\t\t\taiAgentId: rest.item.aiAgentId ?? null,\n\t\t\tcreatedAt,\n\t\t\tdeletedAt: null,\n\t\t};\n\n\t\tthis.timelineItemsStore.ingestTimelineItem(optimisticTimelineItem);\n\n\t\tconst pending = this.pendingConversations.get(rest.conversationId);\n\n\t\tif (pending && createIfPending !== false) {\n\t\t\ttry {\n\t\t\t\tconst response = await this.restClient.createConversation({\n\t\t\t\t\tconversationId: rest.conversationId,\n\t\t\t\t\tvisitorId: pending.conversation.visitorId || undefined,\n\t\t\t\t\tdefaultTimelineItems: [\n\t\t\t\t\t\t...pending.initialTimelineItems,\n\t\t\t\t\t\toptimisticTimelineItem,\n\t\t\t\t\t],\n\t\t\t\t});\n\n\t\t\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\t\trest.conversationId,\n\t\t\t\t\toptimisticId\n\t\t\t\t);\n\t\t\t\tthis.timelineItemsStore.clearConversation(rest.conversationId);\n\n\t\t\t\tthis.timelineItemsStore.ingestPage(rest.conversationId, {\n\t\t\t\t\titems: response.initialTimelineItems,\n\t\t\t\t\thasNextPage: false,\n\t\t\t\t\tnextCursor: undefined,\n\t\t\t\t});\n\n\t\t\t\tthis.pendingConversations.delete(rest.conversationId);\n\n\t\t\t\tconst item =\n\t\t\t\t\tresponse.initialTimelineItems.at(-1) ??\n\t\t\t\t\tresponse.initialTimelineItems[0];\n\n\t\t\t\treturn {\n\t\t\t\t\titem: item as TimelineItem,\n\t\t\t\t\tconversation: response.conversation,\n\t\t\t\t\tinitialTimelineItems: response.initialTimelineItems,\n\t\t\t\t\twasConversationCreated: true,\n\t\t\t\t} satisfies SendTimelineItemResponse & {\n\t\t\t\t\tconversation: Conversation;\n\t\t\t\t\tinitialTimelineItems: TimelineItem[];\n\t\t\t\t\twasConversationCreated: true;\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\t\trest.conversationId,\n\t\t\t\t\toptimisticId\n\t\t\t\t);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\tconst { createdAt: _createdAt, ...restItem } = rest.item;\n\n\t\tconst payload: SendTimelineItemRequest = {\n\t\t\t...rest,\n\t\t\titem: {\n\t\t\t\t...restItem,\n\t\t\t\tid: optimisticId,\n\t\t\t},\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this.restClient.sendMessage(payload);\n\n\t\t\t// Finalize the timeline item\n\t\t\tthis.timelineItemsStore.finalizeTimelineItem(\n\t\t\t\trest.conversationId,\n\t\t\t\toptimisticId,\n\t\t\t\tresponse.item\n\t\t\t);\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\trest.conversationId,\n\t\t\t\toptimisticId\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\thandleRealtimeEvent(event: AnyRealtimeEvent): void {\n\t\tif (event.type === \"conversationCreated\") {\n\t\t\tconst { conversation, header } = event.payload;\n\n\t\t\tthis.conversationsStore.ingestConversation({\n\t\t\t\t...conversation,\n\t\t\t\tlastTimelineItem: conversation.lastTimelineItem ?? undefined,\n\t\t\t});\n\t\t} else if (event.type === \"timelineItemCreated\") {\n\t\t\t// Ingest timeline item into store\n\t\t\tconst timelineItem =\n\t\t\t\tthis.timelineItemsStore.ingestRealtimeTimelineItem(event);\n\n\t\t\t// Update conversation with last timeline item\n\t\t\tconst existingConversation =\n\t\t\t\tthis.conversationsStore.getState().byId[timelineItem.conversationId];\n\n\t\t\tif (existingConversation) {\n\t\t\t\t// Check if this is a status-changing event timeline item\n\t\t\t\tconst newStatus = this.extractStatusFromEventTimelineItem(timelineItem);\n\n\t\t\t\tconst nextConversation = {\n\t\t\t\t\t...existingConversation,\n\t\t\t\t\tupdatedAt: timelineItem.createdAt,\n\t\t\t\t\tlastTimelineItem: timelineItem,\n\t\t\t\t\t...(newStatus && { status: newStatus }),\n\t\t\t\t};\n\n\t\t\t\tthis.conversationsStore.ingestConversation(nextConversation);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Extract conversation status from an event timeline item.\n\t * Returns the new status if this is a status-changing event, otherwise null.\n\t */\n\tprivate extractStatusFromEventTimelineItem(\n\t\ttimelineItem: TimelineItem\n\t): ConversationStatus | null {\n\t\tif (timelineItem.type !== ConversationTimelineType.EVENT) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Find the event part in the timeline item\n\t\tconst eventPart = timelineItem.parts?.find(\n\t\t\t(part) =>\n\t\t\t\ttypeof part === \"object\" &&\n\t\t\t\tpart !== null &&\n\t\t\t\t\"type\" in part &&\n\t\t\t\tpart.type === \"event\"\n\t\t);\n\n\t\tif (\n\t\t\t!eventPart ||\n\t\t\ttypeof eventPart !== \"object\" ||\n\t\t\t!(\"eventType\" in eventPart)\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst eventType = (eventPart as { eventType: string }).eventType;\n\n\t\t// Map event types to conversation status\n\t\tswitch (eventType) {\n\t\t\tcase \"resolved\":\n\t\t\t\treturn ConversationStatus.RESOLVED;\n\t\t\tcase \"reopened\":\n\t\t\t\treturn ConversationStatus.OPEN;\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Handle conversationUpdated event from realtime\n\t * Updates conversation with new title (sentiment and escalation are dashboard-only)\n\t */\n\thandleConversationUpdated(event: RealtimeEvent<\"conversationUpdated\">): void {\n\t\tconst { conversationId, updates } = event.payload;\n\n\t\tconst existingConversation =\n\t\t\tthis.conversationsStore.getState().byId[conversationId];\n\n\t\tif (!existingConversation) {\n\t\t\t// Conversation not in store, ignore update\n\t\t\treturn;\n\t\t}\n\n\t\t// Build the updated conversation\n\t\t// (sentiment and escalation are dashboard-only fields)\n\t\tconst nextConversation = {\n\t\t\t...existingConversation,\n\t\t\t...(updates.title !== undefined && { title: updates.title ?? undefined }),\n\t\t\t...(updates.status !== undefined && { status: updates.status }),\n\t\t\t...(updates.deletedAt !== undefined && {\n\t\t\t\tdeletedAt: updates.deletedAt,\n\t\t\t}),\n\t\t\tupdatedAt: new Date().toISOString(),\n\t\t};\n\n\t\tthis.conversationsStore.ingestConversation(nextConversation);\n\t}\n\n\t// File upload methods\n\t/**\n\t * Generate a presigned URL for uploading a file to S3.\n\t */\n\tasync generateUploadUrl(\n\t\tparams: Omit<\n\t\t\tParameters<CossistantRestClient[\"generateUploadUrl\"]>[0],\n\t\t\t\"websiteId\"\n\t\t>\n\t) {\n\t\treturn this.restClient.generateUploadUrl(params);\n\t}\n\n\t/**\n\t * Upload a file to S3 using a presigned URL.\n\t */\n\tasync uploadFile(file: File, uploadUrl: string, contentType: string) {\n\t\treturn this.restClient.uploadFile(file, uploadUrl, contentType);\n\t}\n\n\t/**\n\t * Upload multiple files for a conversation message.\n\t */\n\tasync uploadFilesForMessage(files: File[], conversationId: string) {\n\t\treturn this.restClient.uploadFilesForMessage(files, conversationId);\n\t}\n\n\t// Cleanup method\n\tdestroy(): void {\n\t\t// No cleanup needed for REST client\n\t}\n}\n\nfunction normalizeBootstrapTimelineItem(\n\tconversationId: string,\n\titem: DefaultMessage | TimelineItem\n): TimelineItem {\n\tif (isDefaultMessage(item)) {\n\t\tconst createdAt =\n\t\t\ttypeof window !== \"undefined\" ? new Date().toISOString() : \"\";\n\n\t\treturn {\n\t\t\tid: generateMessageId(),\n\t\t\tconversationId,\n\t\t\torganizationId: \"\", // Not available at this point\n\t\t\ttype: ConversationTimelineType.MESSAGE,\n\t\t\ttext: item.content,\n\t\t\tparts: [{ type: \"text\" as const, text: item.content }],\n\t\t\tvisibility: TimelineItemVisibility.PUBLIC,\n\t\t\tuserId:\n\t\t\t\titem.senderType === SenderType.TEAM_MEMBER\n\t\t\t\t\t? (item.senderId ?? null)\n\t\t\t\t\t: null,\n\t\t\taiAgentId:\n\t\t\t\titem.senderType === SenderType.AI ? (item.senderId ?? null) : null,\n\t\t\tvisitorId:\n\t\t\t\titem.senderType === SenderType.VISITOR ? (item.senderId ?? null) : null,\n\t\t\tcreatedAt,\n\t\t\tdeletedAt: null,\n\t\t} satisfies TimelineItem;\n\t}\n\n\tconst createdAt = item.createdAt\n\t\t? item.createdAt\n\t\t: typeof window !== \"undefined\"\n\t\t\t? new Date().toISOString()\n\t\t\t: \"\";\n\n\treturn {\n\t\t...item,\n\t\tid: item.id ?? generateMessageId(),\n\t\tconversationId,\n\t\torganizationId: item.organizationId || \"\",\n\t\ttype: item.type ?? ConversationTimelineType.MESSAGE,\n\t\ttool: item.tool ?? null,\n\t\tcreatedAt,\n\t\tdeletedAt: item.deletedAt ?? null,\n\t\tuserId: item.userId ?? null,\n\t\taiAgentId: item.aiAgentId ?? null,\n\t\tvisitorId: item.visitorId ?? null,\n\t\tvisibility: item.visibility ?? TimelineItemVisibility.PUBLIC,\n\t} satisfies TimelineItem;\n}\n\nfunction isDefaultMessage(\n\titem: DefaultMessage | TimelineItem\n): item is DefaultMessage {\n\treturn (item as DefaultMessage).content !== undefined;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["current: WebsiteState","conversation: Conversation","optimisticTimelineItem: TimelineItem","payload: SendTimelineItemRequest","createdAt"],"sources":["../src/client.ts"],"sourcesContent":["import type {\n\tAnyRealtimeEvent,\n\tDefaultMessage,\n\tIdentifyContactResponse,\n\tRealtimeEvent,\n} from \"@cossistant/types\";\nimport type {\n\tCreateConversationRequestBody,\n\tCreateConversationResponseBody,\n\tGetConversationRequest,\n\tGetConversationResponse,\n\tListConversationsRequest,\n\tListConversationsResponse,\n\tMarkConversationSeenRequestBody,\n\tMarkConversationSeenResponseBody,\n\tSetConversationTypingResponseBody,\n\tSubmitConversationRatingRequestBody,\n\tSubmitConversationRatingResponseBody,\n} from \"@cossistant/types/api/conversation\";\nimport type {\n\tGetConversationTimelineItemsRequest,\n\tGetConversationTimelineItemsResponse,\n\tSendTimelineItemRequest,\n\tSendTimelineItemResponse,\n\tTimelineItem,\n} from \"@cossistant/types/api/timeline-item\";\nimport {\n\tConversationStatus,\n\tConversationTimelineType,\n\tSenderType,\n\tTimelineItemVisibility,\n} from \"@cossistant/types/enums\";\nimport type { Conversation } from \"@cossistant/types/schemas\";\nimport { RealtimeClient } from \"./realtime-client\";\nimport { shouldDeliverEvent } from \"./realtime-event-filter\";\nimport { CossistantRestClient } from \"./rest-client\";\nimport {\n\ttype ConversationsStore,\n\tcreateConversationsStore,\n} from \"./store/conversations-store\";\nimport {\n\tapplyConversationSeenEvent,\n\tcreateSeenStore,\n\ttype SeenStore,\n} from \"./store/seen-store\";\nimport {\n\tcreateTimelineItemsStore,\n\ttype TimelineItemsStore,\n} from \"./store/timeline-items-store\";\nimport {\n\tapplyConversationTypingEvent,\n\tclearTypingFromTimelineItem,\n\tcreateTypingStore,\n\ttype TypingStore,\n} from \"./store/typing-store\";\nimport {\n\tcreateWebsiteStore,\n\ttype WebsiteState,\n\ttype WebsiteStore,\n} from \"./store/website-store\";\nimport type {\n\tCossistantConfig,\n\tPublicWebsiteResponse,\n\tVisitorMetadata,\n\tVisitorResponse,\n} from \"./types\";\nimport { generateConversationId, generateMessageId } from \"./utils\";\n\ntype PendingConversation = {\n\tconversation: Conversation;\n\tinitialTimelineItems: TimelineItem[];\n};\n\ntype InitiateConversationParams = {\n\tconversationId?: string;\n\tvisitorId?: string | null;\n\twebsiteId?: string | null;\n\ttitle?: string;\n\tstatus?: Conversation[\"status\"];\n\tdefaultTimelineItems?: Array<DefaultMessage | TimelineItem>;\n};\n\ntype InitiateConversationResult = {\n\tconversationId: string;\n\tconversation: Conversation;\n\tdefaultTimelineItems: TimelineItem[];\n};\n\nexport type CossistantClientOptions = {\n\t/** Supply an external seen store so the client shares state with callers. */\n\tseenStore?: SeenStore;\n\t/** Supply an external typing store so the client shares state with callers. */\n\ttypingStore?: TypingStore;\n};\n\nexport class CossistantClient {\n\tprivate restClient: CossistantRestClient;\n\tprivate config: CossistantConfig;\n\tprivate pendingConversations = new Map<string, PendingConversation>();\n\tprivate websiteRequest: Promise<PublicWebsiteResponse> | null = null;\n\treadonly conversationsStore: ConversationsStore;\n\treadonly timelineItemsStore: TimelineItemsStore;\n\treadonly websiteStore: WebsiteStore;\n\treadonly seenStore: SeenStore;\n\treadonly typingStore: TypingStore;\n\treadonly realtime: RealtimeClient;\n\n\tconstructor(config: CossistantConfig, options?: CossistantClientOptions) {\n\t\tthis.config = config;\n\t\tthis.restClient = new CossistantRestClient(config);\n\t\tthis.conversationsStore = createConversationsStore();\n\t\tthis.timelineItemsStore = createTimelineItemsStore();\n\t\tthis.websiteStore = createWebsiteStore();\n\t\tthis.seenStore = options?.seenStore ?? createSeenStore();\n\t\tthis.typingStore = options?.typingStore ?? createTypingStore();\n\t\tthis.realtime = new RealtimeClient({\n\t\t\twsUrl: config.wsUrl,\n\t\t\tonEvent: (event) => this.handleRealtimeEvent(event),\n\t\t});\n\t}\n\n\t// Configuration updates\n\tupdateConfiguration(config: Partial<CossistantConfig>): void {\n\t\tthis.config = { ...this.config, ...config };\n\t\tthis.restClient.updateConfiguration(config);\n\t}\n\n\t// Utility methods\n\tgetConfiguration(): CossistantConfig {\n\t\treturn { ...this.config };\n\t}\n\n\tisConversationPending(conversationId: string | null | undefined): boolean {\n\t\tif (!conversationId) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.pendingConversations.has(conversationId);\n\t}\n\n\t// Website information\n\tasync fetchWebsite(\n\t\tparams: { force?: boolean } = {}\n\t): Promise<PublicWebsiteResponse> {\n\t\tconst { force = false } = params;\n\t\tconst current: WebsiteState = this.websiteStore.getState();\n\n\t\tif (!force) {\n\t\t\tif (current.status === \"success\" && current.website) {\n\t\t\t\treturn current.website;\n\t\t\t}\n\t\t\tif (this.websiteRequest) {\n\t\t\t\treturn this.websiteRequest;\n\t\t\t}\n\t\t}\n\n\t\tthis.websiteStore.setLoading();\n\n\t\tconst request = this.restClient\n\t\t\t.getWebsite()\n\t\t\t.then((website) => {\n\t\t\t\tthis.websiteStore.setWebsite(website);\n\t\t\t\treturn website;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.websiteStore.setError(error);\n\t\t\t\tthrow error;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (this.websiteRequest === request) {\n\t\t\t\t\tthis.websiteRequest = null;\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.websiteRequest = request;\n\n\t\treturn request;\n\t}\n\n\tasync getWebsite(): Promise<PublicWebsiteResponse> {\n\t\treturn this.fetchWebsite({ force: true });\n\t}\n\n\tsetWebsiteContext(websiteId: string, visitorId?: string): void {\n\t\tthis.restClient.setWebsiteContext(websiteId, visitorId);\n\t}\n\n\tsetVisitorBlocked(isBlocked: boolean): void {\n\t\tthis.restClient.setVisitorBlocked(isBlocked);\n\t}\n\n\tasync updateVisitorMetadata(\n\t\tmetadata: VisitorMetadata\n\t): Promise<VisitorResponse> {\n\t\treturn this.restClient.updateVisitorMetadata(metadata);\n\t}\n\n\tasync identify(params: {\n\t\texternalId?: string;\n\t\temail?: string;\n\t\tname?: string;\n\t\timage?: string;\n\t\tmetadata?: Record<string, unknown>;\n\t\tcontactOrganizationId?: string;\n\t}): Promise<IdentifyContactResponse> {\n\t\treturn this.restClient.identify(params);\n\t}\n\n\tasync updateContactMetadata(\n\t\tmetadata: Record<string, unknown>\n\t): Promise<VisitorResponse> {\n\t\treturn this.restClient.updateContactMetadata(metadata);\n\t}\n\n\t// Conversation management\n\tinitiateConversation(\n\t\tparams: InitiateConversationParams = {}\n\t): InitiateConversationResult {\n\t\tconst conversationId = params.conversationId ?? generateConversationId();\n\t\tconst now = typeof window !== \"undefined\" ? new Date().toISOString() : \"\";\n\t\tconst timelineItems = (params.defaultTimelineItems ?? []).map((item) =>\n\t\t\tnormalizeBootstrapTimelineItem(conversationId, item)\n\t\t);\n\t\tconst existing = this.conversationsStore.getState().byId[conversationId];\n\t\tconst baseVisitorId =\n\t\t\tparams.visitorId ?? this.restClient.getCurrentVisitorId() ?? \"\";\n\t\tconst baseWebsiteId =\n\t\t\tparams.websiteId ?? this.restClient.getCurrentWebsiteId() ?? \"\";\n\n\t\tconst conversation: Conversation = existing\n\t\t\t? {\n\t\t\t\t\t...existing,\n\t\t\t\t\ttitle: params.title ?? existing.title,\n\t\t\t\t\tstatus: params.status ?? existing.status,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t\tlastTimelineItem: timelineItems.at(-1) ?? existing.lastTimelineItem,\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tid: conversationId,\n\t\t\t\t\ttitle: params.title,\n\t\t\t\t\tcreatedAt: now,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t\tvisitorId: baseVisitorId,\n\t\t\t\t\twebsiteId: baseWebsiteId,\n\t\t\t\t\tstatus: params.status ?? ConversationStatus.OPEN,\n\t\t\t\t\tdeletedAt: null,\n\t\t\t\t\tlastTimelineItem: timelineItems.at(-1),\n\t\t\t\t};\n\n\t\tthis.conversationsStore.ingestConversation(conversation);\n\n\t\tif (timelineItems.length > 0) {\n\t\t\tthis.timelineItemsStore.ingestPage(conversationId, {\n\t\t\t\titems: timelineItems,\n\t\t\t\thasNextPage: false,\n\t\t\t\tnextCursor: undefined,\n\t\t\t});\n\t\t}\n\n\t\tif (!existing || this.pendingConversations.has(conversationId)) {\n\t\t\tthis.pendingConversations.set(conversationId, {\n\t\t\t\tconversation,\n\t\t\t\tinitialTimelineItems: timelineItems,\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\tconversationId,\n\t\t\tconversation,\n\t\t\tdefaultTimelineItems: timelineItems,\n\t\t};\n\t}\n\n\tasync createConversation(\n\t\tparams?: Partial<CreateConversationRequestBody>\n\t): Promise<CreateConversationResponseBody> {\n\t\tconst response = await this.restClient.createConversation(params);\n\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\treturn response;\n\t}\n\n\tasync listConversations(\n\t\tparams?: Partial<ListConversationsRequest>\n\t): Promise<ListConversationsResponse> {\n\t\tconst response = await this.restClient.listConversations(params);\n\t\tthis.conversationsStore.ingestList(response);\n\t\treturn response;\n\t}\n\n\tasync getConversation(\n\t\tparams: GetConversationRequest\n\t): Promise<GetConversationResponse> {\n\t\tconst response = await this.restClient.getConversation(params);\n\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\treturn response;\n\t}\n\n\tasync markConversationSeen(\n\t\tparams: {\n\t\t\tconversationId: string;\n\t\t} & Partial<MarkConversationSeenRequestBody>\n\t): Promise<MarkConversationSeenResponseBody> {\n\t\treturn this.restClient.markConversationSeen(params);\n\t}\n\n\tasync getConversationSeenData(params: { conversationId: string }) {\n\t\treturn this.restClient.getConversationSeenData(params);\n\t}\n\n\tasync setVisitorTyping(params: {\n\t\tconversationId: string;\n\t\tisTyping: boolean;\n\t\tvisitorPreview?: string | null;\n\t\tvisitorId?: string;\n\t}): Promise<SetConversationTypingResponseBody> {\n\t\treturn this.restClient.setConversationTyping(params);\n\t}\n\n\tasync submitConversationRating(\n\t\tparams: {\n\t\t\tconversationId: string;\n\t\t} & SubmitConversationRatingRequestBody\n\t): Promise<SubmitConversationRatingResponseBody> {\n\t\tconst response = await this.restClient.submitConversationRating(params);\n\n\t\tconst existing =\n\t\t\tthis.conversationsStore.getState().byId[response.conversationId];\n\n\t\tif (existing) {\n\t\t\tthis.conversationsStore.ingestConversation({\n\t\t\t\t...existing,\n\t\t\t\tvisitorRating: response.rating,\n\t\t\t\tvisitorRatingAt: response.ratedAt,\n\t\t\t});\n\t\t}\n\n\t\treturn response;\n\t}\n\n\t// Timeline items management\n\n\tasync getConversationTimelineItems(\n\t\tparams: GetConversationTimelineItemsRequest & { conversationId: string }\n\t): Promise<GetConversationTimelineItemsResponse> {\n\t\tconst response = await this.restClient.getConversationTimelineItems(params);\n\t\tthis.timelineItemsStore.ingestPage(params.conversationId, {\n\t\t\titems: response.items,\n\t\t\thasNextPage: response.hasNextPage,\n\t\t\tnextCursor: response.nextCursor ?? undefined,\n\t\t});\n\t\treturn response;\n\t}\n\n\tasync sendMessage(\n\t\tparams: SendTimelineItemRequest & { createIfPending?: boolean }\n\t): Promise<\n\t\tSendTimelineItemResponse & {\n\t\t\tconversation?: Conversation;\n\t\t\tinitialTimelineItems?: TimelineItem[];\n\t\t\twasConversationCreated?: boolean;\n\t\t}\n\t> {\n\t\tconst { createIfPending, ...rest } = params;\n\t\tconst optimisticId = rest.item.id ?? generateMessageId();\n\t\tconst createdAt = rest.item.createdAt\n\t\t\t? rest.item.createdAt\n\t\t\t: typeof window !== \"undefined\"\n\t\t\t\t? new Date().toISOString()\n\t\t\t\t: \"\";\n\n\t\t// Add optimistic timeline item\n\t\tconst optimisticTimelineItem: TimelineItem = {\n\t\t\tid: optimisticId,\n\t\t\tconversationId: rest.conversationId,\n\t\t\torganizationId: \"\", // Not available yet\n\t\t\tvisibility: rest.item.visibility ?? TimelineItemVisibility.PUBLIC,\n\t\t\ttype: rest.item.type ?? ConversationTimelineType.MESSAGE,\n\t\t\ttext: rest.item.text,\n\t\t\ttool: rest.item.tool ?? null,\n\t\t\tparts:\n\t\t\t\trest.item.parts && rest.item.parts.length > 0\n\t\t\t\t\t? rest.item.parts\n\t\t\t\t\t: rest.item.text\n\t\t\t\t\t\t? [{ type: \"text\" as const, text: rest.item.text }]\n\t\t\t\t\t\t: [],\n\t\t\tuserId: rest.item.userId ?? null,\n\t\t\tvisitorId: rest.item.visitorId ?? null,\n\t\t\taiAgentId: rest.item.aiAgentId ?? null,\n\t\t\tcreatedAt,\n\t\t\tdeletedAt: null,\n\t\t};\n\n\t\tthis.timelineItemsStore.ingestTimelineItem(optimisticTimelineItem);\n\n\t\tconst pending = this.pendingConversations.get(rest.conversationId);\n\n\t\tif (pending && createIfPending !== false) {\n\t\t\ttry {\n\t\t\t\tconst response = await this.restClient.createConversation({\n\t\t\t\t\tconversationId: rest.conversationId,\n\t\t\t\t\tvisitorId: pending.conversation.visitorId || undefined,\n\t\t\t\t\tdefaultTimelineItems: [\n\t\t\t\t\t\t...pending.initialTimelineItems,\n\t\t\t\t\t\toptimisticTimelineItem,\n\t\t\t\t\t],\n\t\t\t\t});\n\n\t\t\t\tthis.conversationsStore.ingestConversation(response.conversation);\n\t\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\t\trest.conversationId,\n\t\t\t\t\toptimisticId\n\t\t\t\t);\n\t\t\t\tthis.timelineItemsStore.clearConversation(rest.conversationId);\n\n\t\t\t\tthis.timelineItemsStore.ingestPage(rest.conversationId, {\n\t\t\t\t\titems: response.initialTimelineItems,\n\t\t\t\t\thasNextPage: false,\n\t\t\t\t\tnextCursor: undefined,\n\t\t\t\t});\n\n\t\t\t\tthis.pendingConversations.delete(rest.conversationId);\n\n\t\t\t\tconst item =\n\t\t\t\t\tresponse.initialTimelineItems.at(-1) ??\n\t\t\t\t\tresponse.initialTimelineItems[0];\n\n\t\t\t\treturn {\n\t\t\t\t\titem: item as TimelineItem,\n\t\t\t\t\tconversation: response.conversation,\n\t\t\t\t\tinitialTimelineItems: response.initialTimelineItems,\n\t\t\t\t\twasConversationCreated: true,\n\t\t\t\t} satisfies SendTimelineItemResponse & {\n\t\t\t\t\tconversation: Conversation;\n\t\t\t\t\tinitialTimelineItems: TimelineItem[];\n\t\t\t\t\twasConversationCreated: true;\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\t\trest.conversationId,\n\t\t\t\t\toptimisticId\n\t\t\t\t);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\tconst { createdAt: _createdAt, ...restItem } = rest.item;\n\n\t\tconst payload: SendTimelineItemRequest = {\n\t\t\t...rest,\n\t\t\titem: {\n\t\t\t\t...restItem,\n\t\t\t\tid: optimisticId,\n\t\t\t},\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this.restClient.sendMessage(payload);\n\n\t\t\t// Finalize the timeline item\n\t\t\tthis.timelineItemsStore.finalizeTimelineItem(\n\t\t\t\trest.conversationId,\n\t\t\t\toptimisticId,\n\t\t\t\tresponse.item\n\t\t\t);\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tthis.timelineItemsStore.removeTimelineItem(\n\t\t\t\trest.conversationId,\n\t\t\t\toptimisticId\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\thandleRealtimeEvent(event: AnyRealtimeEvent): void {\n\t\t// Apply website/visitor event filtering\n\t\tconst websiteId = this.restClient.getCurrentWebsiteId();\n\t\tconst visitorId = this.restClient.getCurrentVisitorId();\n\n\t\tif (!shouldDeliverEvent(event, websiteId, visitorId)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.type === \"conversationCreated\") {\n\t\t\tconst { conversation } = event.payload;\n\n\t\t\tthis.conversationsStore.ingestConversation({\n\t\t\t\t...conversation,\n\t\t\t\tlastTimelineItem: conversation.lastTimelineItem ?? undefined,\n\t\t\t});\n\t\t} else if (event.type === \"timelineItemCreated\") {\n\t\t\t// Clear typing state when a timeline item is created\n\t\t\tclearTypingFromTimelineItem(this.typingStore, event);\n\n\t\t\t// Ingest timeline item into store\n\t\t\tconst timelineItem =\n\t\t\t\tthis.timelineItemsStore.ingestRealtimeTimelineItem(event);\n\n\t\t\t// Update conversation with last timeline item\n\t\t\tconst existingConversation =\n\t\t\t\tthis.conversationsStore.getState().byId[timelineItem.conversationId];\n\n\t\t\tif (existingConversation) {\n\t\t\t\t// Check if this is a status-changing event timeline item\n\t\t\t\tconst newStatus = this.extractStatusFromEventTimelineItem(timelineItem);\n\n\t\t\t\tconst nextConversation = {\n\t\t\t\t\t...existingConversation,\n\t\t\t\t\tupdatedAt: timelineItem.createdAt,\n\t\t\t\t\tlastTimelineItem: timelineItem,\n\t\t\t\t\t...(newStatus && { status: newStatus }),\n\t\t\t\t};\n\n\t\t\t\tthis.conversationsStore.ingestConversation(nextConversation);\n\t\t\t}\n\t\t} else if (event.type === \"conversationSeen\") {\n\t\t\tapplyConversationSeenEvent(this.seenStore, event, {\n\t\t\t\tignoreVisitorId: visitorId,\n\t\t\t});\n\t\t} else if (event.type === \"conversationTyping\") {\n\t\t\tapplyConversationTypingEvent(this.typingStore, event, {\n\t\t\t\tignoreVisitorId: visitorId,\n\t\t\t});\n\t\t} else if (event.type === \"conversationUpdated\") {\n\t\t\tthis.handleConversationUpdated(event);\n\t\t}\n\t}\n\n\t/**\n\t * Extract conversation status from an event timeline item.\n\t * Returns the new status if this is a status-changing event, otherwise null.\n\t */\n\tprivate extractStatusFromEventTimelineItem(\n\t\ttimelineItem: TimelineItem\n\t): ConversationStatus | null {\n\t\tif (timelineItem.type !== ConversationTimelineType.EVENT) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Find the event part in the timeline item\n\t\tconst eventPart = timelineItem.parts?.find(\n\t\t\t(part) =>\n\t\t\t\ttypeof part === \"object\" &&\n\t\t\t\tpart !== null &&\n\t\t\t\t\"type\" in part &&\n\t\t\t\tpart.type === \"event\"\n\t\t);\n\n\t\tif (\n\t\t\t!eventPart ||\n\t\t\ttypeof eventPart !== \"object\" ||\n\t\t\t!(\"eventType\" in eventPart)\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst eventType = (eventPart as { eventType: string }).eventType;\n\n\t\t// Map event types to conversation status\n\t\tswitch (eventType) {\n\t\t\tcase \"resolved\":\n\t\t\t\treturn ConversationStatus.RESOLVED;\n\t\t\tcase \"reopened\":\n\t\t\t\treturn ConversationStatus.OPEN;\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Handle conversationUpdated event from realtime\n\t * Updates conversation with new title (sentiment and escalation are dashboard-only)\n\t */\n\thandleConversationUpdated(event: RealtimeEvent<\"conversationUpdated\">): void {\n\t\tconst { conversationId, updates } = event.payload;\n\n\t\tconst existingConversation =\n\t\t\tthis.conversationsStore.getState().byId[conversationId];\n\n\t\tif (!existingConversation) {\n\t\t\t// Conversation not in store, ignore update\n\t\t\treturn;\n\t\t}\n\n\t\t// Build the updated conversation\n\t\t// (sentiment and escalation are dashboard-only fields)\n\t\tconst nextConversation = {\n\t\t\t...existingConversation,\n\t\t\t...(updates.title !== undefined && { title: updates.title ?? undefined }),\n\t\t\t...(updates.status !== undefined && { status: updates.status }),\n\t\t\t...(updates.deletedAt !== undefined && {\n\t\t\t\tdeletedAt: updates.deletedAt,\n\t\t\t}),\n\t\t\tupdatedAt: new Date().toISOString(),\n\t\t};\n\n\t\tthis.conversationsStore.ingestConversation(nextConversation);\n\t}\n\n\t// File upload methods\n\t/**\n\t * Generate a presigned URL for uploading a file to S3.\n\t */\n\tasync generateUploadUrl(\n\t\tparams: Omit<\n\t\t\tParameters<CossistantRestClient[\"generateUploadUrl\"]>[0],\n\t\t\t\"websiteId\"\n\t\t>\n\t) {\n\t\treturn this.restClient.generateUploadUrl(params);\n\t}\n\n\t/**\n\t * Upload a file to S3 using a presigned URL.\n\t */\n\tasync uploadFile(file: File, uploadUrl: string, contentType: string) {\n\t\treturn this.restClient.uploadFile(file, uploadUrl, contentType);\n\t}\n\n\t/**\n\t * Upload multiple files for a conversation message.\n\t */\n\tasync uploadFilesForMessage(files: File[], conversationId: string) {\n\t\treturn this.restClient.uploadFilesForMessage(files, conversationId);\n\t}\n\n\t// Cleanup method\n\tdestroy(): void {\n\t\tthis.realtime.destroy();\n\t}\n}\n\nfunction normalizeBootstrapTimelineItem(\n\tconversationId: string,\n\titem: DefaultMessage | TimelineItem\n): TimelineItem {\n\tif (isDefaultMessage(item)) {\n\t\tconst createdAt =\n\t\t\ttypeof window !== \"undefined\" ? new Date().toISOString() : \"\";\n\n\t\treturn {\n\t\t\tid: generateMessageId(),\n\t\t\tconversationId,\n\t\t\torganizationId: \"\", // Not available at this point\n\t\t\ttype: ConversationTimelineType.MESSAGE,\n\t\t\ttext: item.content,\n\t\t\tparts: [{ type: \"text\" as const, text: item.content }],\n\t\t\tvisibility: TimelineItemVisibility.PUBLIC,\n\t\t\tuserId:\n\t\t\t\titem.senderType === SenderType.TEAM_MEMBER\n\t\t\t\t\t? (item.senderId ?? null)\n\t\t\t\t\t: null,\n\t\t\taiAgentId:\n\t\t\t\titem.senderType === SenderType.AI ? (item.senderId ?? null) : null,\n\t\t\tvisitorId:\n\t\t\t\titem.senderType === SenderType.VISITOR ? (item.senderId ?? null) : null,\n\t\t\tcreatedAt,\n\t\t\tdeletedAt: null,\n\t\t} satisfies TimelineItem;\n\t}\n\n\tconst createdAt = item.createdAt\n\t\t? item.createdAt\n\t\t: typeof window !== \"undefined\"\n\t\t\t? new Date().toISOString()\n\t\t\t: \"\";\n\n\treturn {\n\t\t...item,\n\t\tid: item.id ?? generateMessageId(),\n\t\tconversationId,\n\t\torganizationId: item.organizationId || \"\",\n\t\ttype: item.type ?? ConversationTimelineType.MESSAGE,\n\t\ttool: item.tool ?? null,\n\t\tcreatedAt,\n\t\tdeletedAt: item.deletedAt ?? null,\n\t\tuserId: item.userId ?? null,\n\t\taiAgentId: item.aiAgentId ?? null,\n\t\tvisitorId: item.visitorId ?? null,\n\t\tvisibility: item.visibility ?? TimelineItemVisibility.PUBLIC,\n\t} satisfies TimelineItem;\n}\n\nfunction isDefaultMessage(\n\titem: DefaultMessage | TimelineItem\n): item is DefaultMessage {\n\treturn (item as DefaultMessage).content !== undefined;\n}\n"],"mappings":"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"}
|
package/env.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/index.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { AISDKFilePart, AISDKPart, AISDKReasoningPart, AISDKSourceDocumentPart, AISDKSourceUrlPart, AISDKStepStartPart, AISDKTextPart, AISDKToolPart, CossistantMessageMetadata, CossistantPartMetadata, CossistantToolTimelineMetadata, CossistantUIMessage, FromUIMessageContext, extractSources, extractToolCalls, fromUIMessage, fromUIMessages, getCossistantPartMetadata, getCossistantToolTimelineMetadata, hasProcessingParts, isAISDKCompatiblePart, setCossistantPartMetadata, setCossistantToolTimelineMetadata, toUIMessage, toUIMessages } from "./ai-sdk-utils.js";
|
|
2
|
+
import { RealtimeAuthConfig, RealtimeClient, RealtimeClientOptions, RealtimeConnectionState, RealtimeConnectionStatus, SessionAuthConfig, VisitorAuthConfig } from "./realtime-client.js";
|
|
2
3
|
import { CossistantAPIError } from "./types.js";
|
|
3
4
|
import { CossistantRestClient } from "./rest-client.js";
|
|
4
5
|
import { ConversationPagination, ConversationWithSeen, ConversationsState, ConversationsStore, createConversationsStore, getConversationById, getConversationPagination, getConversations } from "./store/conversations-store.js";
|
|
6
|
+
import { ConversationSeenState, SeenActorType, SeenEntry, SeenState, SeenStore, applyConversationSeenEvent, createSeenStore, hydrateConversationSeen, upsertConversationSeen } from "./store/seen-store.js";
|
|
5
7
|
import { ConversationTimelineItemsState, TimelineItemsState, TimelineItemsStore, createTimelineItemsStore, getConversationTimelineItems } from "./store/timeline-items-store.js";
|
|
8
|
+
import { ConversationTypingState, TypingActorType, TypingEntry, TypingState, TypingStore, TypingStoreDependencies, applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, createTypingStore, getConversationTyping, setTypingState } from "./store/typing-store.js";
|
|
6
9
|
import { WebsiteError, WebsiteState, WebsiteStatus, WebsiteStore, createWebsiteStore, getWebsiteState } from "./store/website-store.js";
|
|
7
|
-
import { CossistantClient } from "./client.js";
|
|
10
|
+
import { CossistantClient, CossistantClientOptions } from "./client.js";
|
|
8
11
|
import { normalizeLocale } from "./locale-utils.js";
|
|
9
12
|
import { Audience, FilterOptions, PrivacyPresets, countVisibleParts, extractVisibleText, filterMessageForAudience, filterMessagesForAudience, filterTimelineItemForAudience, filterTimelineItemsForAudience, hasVisibleContent } from "./privacy-filter.js";
|
|
10
|
-
import {
|
|
13
|
+
import { getTargetVisitorId, shouldDeliverEvent } from "./realtime-event-filter.js";
|
|
14
|
+
import { Framework, detectFramework, getEnvVarName, resolvePublicKey } from "./resolve-public-key.js";
|
|
11
15
|
import { DefaultRoutes, NavigationState, RouteRegistry, SUPPORT_PAGES, SupportConfig, SupportNavigation, SupportPage, SupportStore, SupportStoreActions, SupportStoreOptions, SupportStoreState, SupportStoreStorage, createSupportStore } from "./store/support-store.js";
|
|
12
|
-
import { ConversationTypingState, TypingActorType, TypingEntry, TypingState, TypingStore, TypingStoreDependencies, applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, createTypingStore, getConversationTyping, setTypingState } from "./store/typing-store.js";
|
|
13
16
|
import { TYPING_KEEP_ALIVE_MS, TYPING_PREVIEW_MAX_LENGTH, TYPING_SEND_INTERVAL_MS, TYPING_STOP_DELAY_MS, TypingReporter, TypingReporterConfig, createTypingReporter } from "./typing-reporter.js";
|
|
14
17
|
import { ALLOWED_FILE_TYPES_DESCRIPTION, ALLOWED_MIME_TYPES, FILE_INPUT_ACCEPT, MAX_FILES_PER_MESSAGE, MAX_FILE_SIZE, formatFileSize, isAllowedMimeType, isImageMimeType, validateFile, validateFiles } from "./upload-constants.js";
|
|
15
18
|
import { generateConversationId, generateMessageId } from "./utils.js";
|
|
@@ -17,4 +20,4 @@ import { VisitorData, collectVisitorData } from "./visitor-data.js";
|
|
|
17
20
|
import { generateVisitorName, getVisitorNameWithFallback } from "./visitor-name.js";
|
|
18
21
|
import { clearAllVisitorIds, clearVisitorId, getVisitorId, setVisitorId } from "./visitor-tracker.js";
|
|
19
22
|
import { CossistantConfig, CossistantError } from "@cossistant/types";
|
|
20
|
-
export { type AISDKFilePart, type AISDKPart, type AISDKReasoningPart, type AISDKSourceDocumentPart, type AISDKSourceUrlPart, type AISDKStepStartPart, type AISDKTextPart, type AISDKToolPart, ALLOWED_FILE_TYPES_DESCRIPTION, ALLOWED_MIME_TYPES, type Audience, type ConversationPagination, type ConversationSeenState, type ConversationTimelineItemsState, type ConversationTypingState, type ConversationWithSeen, type ConversationsState, type ConversationsStore, CossistantAPIError, CossistantClient, type CossistantConfig, type CossistantError, type CossistantMessageMetadata, type CossistantPartMetadata, CossistantRestClient, type CossistantToolTimelineMetadata, type CossistantUIMessage, type DefaultRoutes, FILE_INPUT_ACCEPT, type FilterOptions, type FromUIMessageContext, MAX_FILES_PER_MESSAGE, MAX_FILE_SIZE, type NavigationState, PrivacyPresets, type RouteRegistry, type SUPPORT_PAGES, type SeenActorType, type SeenEntry, type SeenState, type SeenStore, type SupportConfig, type SupportNavigation, type SupportPage, type SupportStore, type SupportStoreActions, type SupportStoreOptions, type SupportStoreState, type SupportStoreStorage, TYPING_KEEP_ALIVE_MS, TYPING_PREVIEW_MAX_LENGTH, TYPING_SEND_INTERVAL_MS, TYPING_STOP_DELAY_MS, type TimelineItemsState, type TimelineItemsStore, type TypingActorType, type TypingEntry, type TypingReporter, type TypingReporterConfig, type TypingState, type TypingStore, type TypingStoreDependencies, type VisitorData, type WebsiteError, type WebsiteState, type WebsiteStatus, type WebsiteStore, applyConversationSeenEvent, applyConversationTypingEvent, clearAllVisitorIds, clearTypingFromTimelineItem, clearTypingState, clearVisitorId, collectVisitorData, countVisibleParts, createConversationsStore, createSeenStore, createSupportStore, createTimelineItemsStore, createTypingReporter, createTypingStore, createWebsiteStore, CossistantClient as default, extractSources, extractToolCalls, extractVisibleText, filterMessageForAudience, filterMessagesForAudience, filterTimelineItemForAudience, filterTimelineItemsForAudience, formatFileSize, fromUIMessage, fromUIMessages, generateConversationId, generateMessageId, generateVisitorName, getConversationById, getConversationPagination, getConversationTimelineItems, getConversationTyping, getConversations, getCossistantPartMetadata, getCossistantToolTimelineMetadata, getVisitorId, getVisitorNameWithFallback, getWebsiteState, hasProcessingParts, hasVisibleContent, hydrateConversationSeen, isAISDKCompatiblePart, isAllowedMimeType, isImageMimeType, normalizeLocale, setCossistantPartMetadata, setCossistantToolTimelineMetadata, setTypingState, setVisitorId, toUIMessage, toUIMessages, upsertConversationSeen, validateFile, validateFiles };
|
|
23
|
+
export { type AISDKFilePart, type AISDKPart, type AISDKReasoningPart, type AISDKSourceDocumentPart, type AISDKSourceUrlPart, type AISDKStepStartPart, type AISDKTextPart, type AISDKToolPart, ALLOWED_FILE_TYPES_DESCRIPTION, ALLOWED_MIME_TYPES, type Audience, type ConversationPagination, type ConversationSeenState, type ConversationTimelineItemsState, type ConversationTypingState, type ConversationWithSeen, type ConversationsState, type ConversationsStore, CossistantAPIError, CossistantClient, type CossistantClientOptions, type CossistantConfig, type CossistantError, type CossistantMessageMetadata, type CossistantPartMetadata, CossistantRestClient, type CossistantToolTimelineMetadata, type CossistantUIMessage, type DefaultRoutes, FILE_INPUT_ACCEPT, type FilterOptions, type Framework, type FromUIMessageContext, MAX_FILES_PER_MESSAGE, MAX_FILE_SIZE, type NavigationState, PrivacyPresets, type RealtimeAuthConfig, RealtimeClient, type RealtimeClientOptions, type RealtimeConnectionState, type RealtimeConnectionStatus, type RouteRegistry, type SUPPORT_PAGES, type SeenActorType, type SeenEntry, type SeenState, type SeenStore, type SessionAuthConfig, type SupportConfig, type SupportNavigation, type SupportPage, type SupportStore, type SupportStoreActions, type SupportStoreOptions, type SupportStoreState, type SupportStoreStorage, TYPING_KEEP_ALIVE_MS, TYPING_PREVIEW_MAX_LENGTH, TYPING_SEND_INTERVAL_MS, TYPING_STOP_DELAY_MS, type TimelineItemsState, type TimelineItemsStore, type TypingActorType, type TypingEntry, type TypingReporter, type TypingReporterConfig, type TypingState, type TypingStore, type TypingStoreDependencies, type VisitorAuthConfig, type VisitorData, type WebsiteError, type WebsiteState, type WebsiteStatus, type WebsiteStore, applyConversationSeenEvent, applyConversationTypingEvent, clearAllVisitorIds, clearTypingFromTimelineItem, clearTypingState, clearVisitorId, collectVisitorData, countVisibleParts, createConversationsStore, createSeenStore, createSupportStore, createTimelineItemsStore, createTypingReporter, createTypingStore, createWebsiteStore, CossistantClient as default, detectFramework, extractSources, extractToolCalls, extractVisibleText, filterMessageForAudience, filterMessagesForAudience, filterTimelineItemForAudience, filterTimelineItemsForAudience, formatFileSize, fromUIMessage, fromUIMessages, generateConversationId, generateMessageId, generateVisitorName, getConversationById, getConversationPagination, getConversationTimelineItems, getConversationTyping, getConversations, getCossistantPartMetadata, getCossistantToolTimelineMetadata, getEnvVarName, getTargetVisitorId, getVisitorId, getVisitorNameWithFallback, getWebsiteState, hasProcessingParts, hasVisibleContent, hydrateConversationSeen, isAISDKCompatiblePart, isAllowedMimeType, isImageMimeType, normalizeLocale, resolvePublicKey, setCossistantPartMetadata, setCossistantToolTimelineMetadata, setTypingState, setVisitorId, shouldDeliverEvent, toUIMessage, toUIMessages, upsertConversationSeen, validateFile, validateFiles };
|
package/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { extractSources, extractToolCalls, fromUIMessage, fromUIMessages, getCossistantPartMetadata, getCossistantToolTimelineMetadata, hasProcessingParts, isAISDKCompatiblePart, setCossistantPartMetadata, setCossistantToolTimelineMetadata, toUIMessage, toUIMessages } from "./ai-sdk-utils.js";
|
|
2
|
+
import { detectFramework, getEnvVarName, resolvePublicKey } from "./resolve-public-key.js";
|
|
3
|
+
import { RealtimeClient } from "./realtime-client.js";
|
|
4
|
+
import { getTargetVisitorId, shouldDeliverEvent } from "./realtime-event-filter.js";
|
|
2
5
|
import { CossistantAPIError } from "./types.js";
|
|
3
6
|
import { ALLOWED_FILE_TYPES_DESCRIPTION, ALLOWED_MIME_TYPES, FILE_INPUT_ACCEPT, MAX_FILES_PER_MESSAGE, MAX_FILE_SIZE, formatFileSize, isAllowedMimeType, isImageMimeType, validateFile, validateFiles } from "./upload-constants.js";
|
|
4
7
|
import { generateConversationId, generateMessageId } from "./utils.js";
|
|
@@ -6,15 +9,15 @@ import { collectVisitorData } from "./visitor-data.js";
|
|
|
6
9
|
import { clearAllVisitorIds, clearVisitorId, getVisitorId, setVisitorId } from "./visitor-tracker.js";
|
|
7
10
|
import { CossistantRestClient } from "./rest-client.js";
|
|
8
11
|
import { createConversationsStore, getConversationById, getConversationPagination, getConversations } from "./store/conversations-store.js";
|
|
12
|
+
import { applyConversationSeenEvent, createSeenStore, hydrateConversationSeen, upsertConversationSeen } from "./store/seen-store.js";
|
|
9
13
|
import { createTimelineItemsStore, getConversationTimelineItems } from "./store/timeline-items-store.js";
|
|
14
|
+
import { applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, createTypingStore, getConversationTyping, setTypingState } from "./store/typing-store.js";
|
|
10
15
|
import { createWebsiteStore, getWebsiteState } from "./store/website-store.js";
|
|
11
16
|
import { CossistantClient } from "./client.js";
|
|
12
17
|
import { normalizeLocale } from "./locale-utils.js";
|
|
13
18
|
import { PrivacyPresets, countVisibleParts, extractVisibleText, filterMessageForAudience, filterMessagesForAudience, filterTimelineItemForAudience, filterTimelineItemsForAudience, hasVisibleContent } from "./privacy-filter.js";
|
|
14
|
-
import { applyConversationSeenEvent, createSeenStore, hydrateConversationSeen, upsertConversationSeen } from "./store/seen-store.js";
|
|
15
19
|
import { createSupportStore } from "./store/support-store.js";
|
|
16
|
-
import { applyConversationTypingEvent, clearTypingFromTimelineItem, clearTypingState, createTypingStore, getConversationTyping, setTypingState } from "./store/typing-store.js";
|
|
17
20
|
import { TYPING_KEEP_ALIVE_MS, TYPING_PREVIEW_MAX_LENGTH, TYPING_SEND_INTERVAL_MS, TYPING_STOP_DELAY_MS, createTypingReporter } from "./typing-reporter.js";
|
|
18
21
|
import { generateVisitorName, getVisitorNameWithFallback } from "./visitor-name.js";
|
|
19
22
|
|
|
20
|
-
export { ALLOWED_FILE_TYPES_DESCRIPTION, ALLOWED_MIME_TYPES, CossistantAPIError, CossistantClient, CossistantRestClient, FILE_INPUT_ACCEPT, MAX_FILES_PER_MESSAGE, MAX_FILE_SIZE, PrivacyPresets, TYPING_KEEP_ALIVE_MS, TYPING_PREVIEW_MAX_LENGTH, TYPING_SEND_INTERVAL_MS, TYPING_STOP_DELAY_MS, applyConversationSeenEvent, applyConversationTypingEvent, clearAllVisitorIds, clearTypingFromTimelineItem, clearTypingState, clearVisitorId, collectVisitorData, countVisibleParts, createConversationsStore, createSeenStore, createSupportStore, createTimelineItemsStore, createTypingReporter, createTypingStore, createWebsiteStore, CossistantClient as default, extractSources, extractToolCalls, extractVisibleText, filterMessageForAudience, filterMessagesForAudience, filterTimelineItemForAudience, filterTimelineItemsForAudience, formatFileSize, fromUIMessage, fromUIMessages, generateConversationId, generateMessageId, generateVisitorName, getConversationById, getConversationPagination, getConversationTimelineItems, getConversationTyping, getConversations, getCossistantPartMetadata, getCossistantToolTimelineMetadata, getVisitorId, getVisitorNameWithFallback, getWebsiteState, hasProcessingParts, hasVisibleContent, hydrateConversationSeen, isAISDKCompatiblePart, isAllowedMimeType, isImageMimeType, normalizeLocale, setCossistantPartMetadata, setCossistantToolTimelineMetadata, setTypingState, setVisitorId, toUIMessage, toUIMessages, upsertConversationSeen, validateFile, validateFiles };
|
|
23
|
+
export { ALLOWED_FILE_TYPES_DESCRIPTION, ALLOWED_MIME_TYPES, CossistantAPIError, CossistantClient, CossistantRestClient, FILE_INPUT_ACCEPT, MAX_FILES_PER_MESSAGE, MAX_FILE_SIZE, PrivacyPresets, RealtimeClient, TYPING_KEEP_ALIVE_MS, TYPING_PREVIEW_MAX_LENGTH, TYPING_SEND_INTERVAL_MS, TYPING_STOP_DELAY_MS, applyConversationSeenEvent, applyConversationTypingEvent, clearAllVisitorIds, clearTypingFromTimelineItem, clearTypingState, clearVisitorId, collectVisitorData, countVisibleParts, createConversationsStore, createSeenStore, createSupportStore, createTimelineItemsStore, createTypingReporter, createTypingStore, createWebsiteStore, CossistantClient as default, detectFramework, extractSources, extractToolCalls, extractVisibleText, filterMessageForAudience, filterMessagesForAudience, filterTimelineItemForAudience, filterTimelineItemsForAudience, formatFileSize, fromUIMessage, fromUIMessages, generateConversationId, generateMessageId, generateVisitorName, getConversationById, getConversationPagination, getConversationTimelineItems, getConversationTyping, getConversations, getCossistantPartMetadata, getCossistantToolTimelineMetadata, getEnvVarName, getTargetVisitorId, getVisitorId, getVisitorNameWithFallback, getWebsiteState, hasProcessingParts, hasVisibleContent, hydrateConversationSeen, isAISDKCompatiblePart, isAllowedMimeType, isImageMimeType, normalizeLocale, resolvePublicKey, setCossistantPartMetadata, setCossistantToolTimelineMetadata, setTypingState, setVisitorId, shouldDeliverEvent, toUIMessage, toUIMessages, upsertConversationSeen, validateFile, validateFiles };
|
package/package.json
CHANGED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { AnyRealtimeEvent } from "./types/src/realtime-events.js";
|
|
2
|
+
|
|
3
|
+
//#region src/realtime-client.d.ts
|
|
4
|
+
type VisitorAuthConfig = {
|
|
5
|
+
kind: "visitor";
|
|
6
|
+
visitorId: string | null;
|
|
7
|
+
websiteId?: string | null;
|
|
8
|
+
publicKey?: string | null;
|
|
9
|
+
};
|
|
10
|
+
type SessionAuthConfig = {
|
|
11
|
+
kind: "session";
|
|
12
|
+
sessionToken: string | null;
|
|
13
|
+
websiteId?: string | null;
|
|
14
|
+
userId?: string | null;
|
|
15
|
+
};
|
|
16
|
+
type RealtimeAuthConfig = VisitorAuthConfig | SessionAuthConfig;
|
|
17
|
+
type RealtimeConnectionStatus = "disconnected" | "connecting" | "connected";
|
|
18
|
+
type RealtimeConnectionState = {
|
|
19
|
+
status: RealtimeConnectionStatus;
|
|
20
|
+
error: Error | null;
|
|
21
|
+
connectionId: string | null;
|
|
22
|
+
};
|
|
23
|
+
type SubscribeHandler = (event: AnyRealtimeEvent) => void;
|
|
24
|
+
type StateChangeListener = (state: RealtimeConnectionState) => void;
|
|
25
|
+
type RealtimeClientOptions = {
|
|
26
|
+
wsUrl?: string;
|
|
27
|
+
heartbeatIntervalMs?: number;
|
|
28
|
+
heartbeatTimeoutMs?: number;
|
|
29
|
+
onEvent?: (event: AnyRealtimeEvent) => void;
|
|
30
|
+
onConnect?: () => void;
|
|
31
|
+
onDisconnect?: () => void;
|
|
32
|
+
onError?: (error: Error) => void;
|
|
33
|
+
};
|
|
34
|
+
declare class RealtimeClient {
|
|
35
|
+
private wsUrl;
|
|
36
|
+
private heartbeatIntervalMs;
|
|
37
|
+
private heartbeatTimeoutMs;
|
|
38
|
+
private onEventCallback;
|
|
39
|
+
private onConnectCallback;
|
|
40
|
+
private onDisconnectCallback;
|
|
41
|
+
private onErrorCallback;
|
|
42
|
+
private socket;
|
|
43
|
+
private state;
|
|
44
|
+
private auth;
|
|
45
|
+
private reconnectAttempt;
|
|
46
|
+
private reconnectTimer;
|
|
47
|
+
private heartbeatTimer;
|
|
48
|
+
private lastHeartbeat;
|
|
49
|
+
private destroyed;
|
|
50
|
+
private presenceEnabled;
|
|
51
|
+
private presencePaused;
|
|
52
|
+
private presenceTimer;
|
|
53
|
+
private presenceIntervalMs;
|
|
54
|
+
private eventHandlers;
|
|
55
|
+
private stateListeners;
|
|
56
|
+
constructor(options?: RealtimeClientOptions);
|
|
57
|
+
connect(auth: RealtimeAuthConfig | null): void;
|
|
58
|
+
disconnect(): void;
|
|
59
|
+
reconnect(): void;
|
|
60
|
+
updateAuth(auth: RealtimeAuthConfig | null): void;
|
|
61
|
+
send(event: AnyRealtimeEvent): void;
|
|
62
|
+
sendRaw(data: string): void;
|
|
63
|
+
subscribe(handler: SubscribeHandler): () => void;
|
|
64
|
+
getState(): RealtimeConnectionState;
|
|
65
|
+
onStateChange(listener: StateChangeListener): () => void;
|
|
66
|
+
enablePresence(intervalMs: number): void;
|
|
67
|
+
pausePresence(): void;
|
|
68
|
+
resumePresence(): void;
|
|
69
|
+
destroy(): void;
|
|
70
|
+
private openSocket;
|
|
71
|
+
private closeSocket;
|
|
72
|
+
private handleMessage;
|
|
73
|
+
private dispatchEvent;
|
|
74
|
+
private startHeartbeat;
|
|
75
|
+
private stopHeartbeat;
|
|
76
|
+
private scheduleReconnect;
|
|
77
|
+
private clearReconnectTimer;
|
|
78
|
+
private sendPresencePing;
|
|
79
|
+
private startPresenceTimer;
|
|
80
|
+
private stopPresenceTimer;
|
|
81
|
+
private setState;
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
export { RealtimeAuthConfig, RealtimeClient, RealtimeClientOptions, RealtimeConnectionState, RealtimeConnectionStatus, SessionAuthConfig, VisitorAuthConfig };
|
|
85
|
+
//# sourceMappingURL=realtime-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime-client.d.ts","names":[],"sources":["../src/realtime-client.ts"],"sourcesContent":[],"mappings":";;;KA0BY,iBAAA;;EAAA,SAAA,EAAA,MAAA,GAAiB,IAAA;EAOjB,SAAA,CAAA,EAAA,MAAA,GAAiB,IAAA;EAOjB,SAAA,CAAA,EAAA,MAAA,GAAkB,IAAA;AAW9B,CAAA;AAKY,KAvBA,iBAAA,GAuBuB;EAM9B,IAAA,EAAA,SAAA;EACA,YAAA,EAAA,MAAA,GAAmB,IAAA;EAEZ,SAAA,CAAA,EAAA,MAAA,GAAA,IAAqB;EA6QpB,MAAA,CAAA,EAAA,MAAA,GAAc,IAAA;CA4BL;AAgBP,KAlVH,kBAAA,GAAqB,iBAkVlB,GAlVsC,iBAkVtC;AAiCG,KAxWN,wBAAA,GAwWM,cAAA,GAAA,YAAA,GAAA,WAAA;AAIL,KAvWD,uBAAA,GAuWC;EAgBO,MAAA,EAtXX,wBAsXW;EAOP,KAAA,EA5XL,KA4XK,GAAA,IAAA;EAIY,YAAA,EAAA,MAAA,GAAA,IAAA;CAAmB;KA5XvC,gBAAA,WAA2B;KAC3B,mBAAA,WAA8B;KAEvB,qBAAA;;;;oBAIO;;;oBAGA;;cAsQN,cAAA;;;;;;;;;;;;;;;;;;;;;;wBA4BS;gBAgBP;;;mBAiCG;cAIL;;qBAgBO;cAOP;0BAIY"}
|