open-chat-studio-widget 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{index-fFSp-Z_h.js → index-DMXmZhVD.js} +3 -3
- package/dist/cjs/index-DMXmZhVD.js.map +1 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/open-chat-studio-widget.cjs.entry.js +1251 -314
- package/dist/cjs/open-chat-studio-widget.cjs.entry.js.map +1 -1
- package/dist/cjs/open-chat-studio-widget.cjs.js +2 -2
- package/dist/cjs/open-chat-studio-widget.entry.cjs.js.map +1 -1
- package/dist/collection/components/ocs-chat/ocs-chat.js +90 -5
- package/dist/collection/components/ocs-chat/ocs-chat.js.map +1 -1
- package/dist/collection/services/chat-session-service.js +5 -0
- package/dist/collection/services/chat-session-service.js.map +1 -1
- package/dist/components/open-chat-studio-widget.js +1251 -313
- package/dist/components/open-chat-studio-widget.js.map +1 -1
- package/dist/esm/{index-ythTKHg-.js → index-JDApwJx_.js} +3 -3
- package/dist/esm/index-JDApwJx_.js.map +1 -0
- package/dist/esm/loader.js +3 -3
- package/dist/esm/open-chat-studio-widget.entry.js +1251 -314
- package/dist/esm/open-chat-studio-widget.entry.js.map +1 -1
- package/dist/esm/open-chat-studio-widget.js +3 -3
- package/dist/open-chat-studio-widget/open-chat-studio-widget.entry.esm.js.map +1 -1
- package/dist/open-chat-studio-widget/open-chat-studio-widget.esm.js +1 -1
- package/dist/open-chat-studio-widget/{p-ythTKHg-.js → p-JDApwJx_.js} +2 -2
- package/dist/open-chat-studio-widget/p-JDApwJx_.js.map +1 -0
- package/dist/open-chat-studio-widget/p-c2d3b2d1.entry.js +4 -0
- package/dist/open-chat-studio-widget/p-c2d3b2d1.entry.js.map +1 -0
- package/dist/types/components/ocs-chat/ocs-chat.d.ts +15 -0
- package/dist/types/services/chat-session-service.d.ts +2 -0
- package/package.json +2 -2
- package/dist/cjs/index-fFSp-Z_h.js.map +0 -1
- package/dist/esm/index-ythTKHg-.js.map +0 -1
- package/dist/open-chat-studio-widget/p-2d31a15c.entry.js +0 -4
- package/dist/open-chat-studio-widget/p-2d31a15c.entry.js.map +0 -1
- package/dist/open-chat-studio-widget/p-ythTKHg-.js.map +0 -1
|
@@ -139,12 +139,17 @@ export class ChatSessionService {
|
|
|
139
139
|
}
|
|
140
140
|
startMessagePolling(sessionId, callbacks) {
|
|
141
141
|
const poll = async () => {
|
|
142
|
+
var _a;
|
|
142
143
|
try {
|
|
143
144
|
const since = callbacks.getSince();
|
|
144
145
|
const data = await this.fetchMessages(sessionId, since);
|
|
145
146
|
if (data.messages.length > 0) {
|
|
146
147
|
callbacks.onMessages(data.messages);
|
|
147
148
|
}
|
|
149
|
+
if (data.session_status === 'ended') {
|
|
150
|
+
this.stopMessagePolling();
|
|
151
|
+
(_a = callbacks.onSessionEnded) === null || _a === void 0 ? void 0 : _a.call(callbacks);
|
|
152
|
+
}
|
|
148
153
|
}
|
|
149
154
|
catch (error) {
|
|
150
155
|
if (callbacks.onError) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-session-service.js","sourceRoot":"","sources":["../../src/services/chat-session-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { getCSRFToken } from '../utils/cookies';\n\nexport class SessionAccessError extends Error {\n readonly status: number;\n readonly code?: string;\n\n constructor(status: number, code: string | undefined, message: string) {\n super(message);\n this.name = 'SessionAccessError';\n this.status = status;\n this.code = code;\n }\n}\n\nexport type ChatRole = 'system' | 'user' | 'assistant';\n\nexport interface ChatAttachment {\n name: string;\n content_type: string;\n size: number;\n}\n\nexport interface ChatMessage {\n created_at: string;\n role: ChatRole;\n content: string;\n metadata?: unknown;\n attachments?: ChatAttachment[];\n}\n\nexport interface ChatStartSessionResponse {\n session_id: string;\n session_token?: string | null;\n chatbot: unknown;\n participant: unknown;\n}\n\nexport interface ChatSendMessageResponse {\n task_id: string;\n status: 'processing' | 'completed' | 'error';\n error?: string;\n}\n\nexport interface ChatTaskPollResponse {\n message?: ChatMessage;\n status: 'processing' | 'complete';\n error?: string;\n}\n\nexport interface ChatPollResponse {\n messages: ChatMessage[];\n has_more: boolean;\n session_status: 'active' | 'ended';\n}\n\nexport interface ChatSessionServiceOptions {\n apiBaseUrl: string;\n embedKey?: string;\n widgetVersion: string;\n sessionToken?: string;\n csrfTokenProvider?: (apiBaseUrl: string) => string | undefined;\n taskPollingIntervalMs?: number;\n taskPollingMaxAttempts?: number;\n messagePollingIntervalMs?: number;\n}\n\nexport interface TaskPollingCallbacks {\n onMessage: (message: ChatMessage) => void;\n onProgress?: (message: string) => void;\n onTimeout?: () => void;\n onError?: (error: Error) => void;\n}\n\nexport interface TaskPollingHandle {\n cancel: () => void;\n}\n\nexport interface MessagePollingCallbacks {\n getSince: () => string | undefined;\n onMessages: (messages: ChatMessage[]) => void;\n onError?: (error: Error) => void;\n}\n\nexport interface MessagePollingHandle {\n stop: () => void;\n}\n\nexport class ChatSessionService {\n private readonly apiBaseUrl: string;\n private readonly embedKey?: string;\n private readonly widgetVersion: string;\n private sessionToken?: string;\n private readonly csrfTokenProvider: (apiBaseUrl: string) => string | undefined;\n private readonly taskPollingIntervalMs: number;\n private readonly taskPollingMaxAttempts: number;\n private readonly messagePollingIntervalMs: number;\n private messagePollingTimer?: ReturnType<typeof setInterval>;\n private loggedSunsetLevel?: 'warn' | 'error';\n private static readonly MAX_HISTORY_PAGES = 40;\n\n constructor(options: ChatSessionServiceOptions) {\n this.apiBaseUrl = options.apiBaseUrl;\n this.embedKey = options.embedKey;\n this.widgetVersion = options.widgetVersion;\n this.sessionToken = options.sessionToken;\n this.csrfTokenProvider = options.csrfTokenProvider ?? getCSRFToken;\n this.taskPollingIntervalMs = options.taskPollingIntervalMs ?? 1000;\n this.taskPollingMaxAttempts = options.taskPollingMaxAttempts ?? 120;\n this.messagePollingIntervalMs = options.messagePollingIntervalMs ?? 30000;\n }\n\n async startSession(requestBody: Record<string, unknown>): Promise<ChatStartSessionResponse> {\n const response = await this.request(`${this.apiBaseUrl}/api/chat/start/`, {\n method: 'POST',\n headers: this.getJsonHeaders(),\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n await this.raiseForStatus(response, 'Failed to start session');\n }\n\n return response.json() as Promise<ChatStartSessionResponse>;\n }\n\n async sendMessage(sessionId: string, payload: Record<string, unknown>): Promise<ChatSendMessageResponse> {\n const response = await this.request(`${this.apiBaseUrl}/api/chat/${sessionId}/message/`, {\n method: 'POST',\n headers: this.getJsonHeaders(),\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n await this.raiseForStatus(response, 'Failed to send message');\n }\n\n return response.json() as Promise<ChatSendMessageResponse>;\n }\n\n async pollTaskOnce(sessionId: string, taskId: string): Promise<ChatTaskPollResponse> {\n const response = await this.request(`${this.apiBaseUrl}/api/chat/${sessionId}/${taskId}/poll/`, {\n headers: this.getCommonHeaders(),\n });\n\n if (!response.ok) {\n await this.raiseForStatus(response, 'Failed to poll task');\n }\n\n return response.json() as Promise<ChatTaskPollResponse>;\n }\n\n pollTask(sessionId: string, taskId: string, callbacks: TaskPollingCallbacks): TaskPollingHandle {\n let attempts = 0;\n let cancelled = false;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const scheduleNextPoll = () => {\n timeoutId = setTimeout(() => {\n void poll();\n }, this.taskPollingIntervalMs);\n };\n\n const poll = async () => {\n if (cancelled) {\n return;\n }\n\n try {\n const data = await this.pollTaskOnce(sessionId, taskId);\n\n if (data.error) {\n throw new Error(data.error);\n }\n\n if (data.status === 'complete' && data.message) {\n callbacks.onMessage(data.message);\n return;\n }\n\n if (data.status === 'processing' && data.message?.content && callbacks.onProgress) {\n callbacks.onProgress(data.message.content);\n }\n\n attempts += 1;\n if (attempts >= this.taskPollingMaxAttempts) {\n if (callbacks.onTimeout) {\n callbacks.onTimeout();\n }\n return;\n }\n\n scheduleNextPoll();\n } catch (error) {\n if (callbacks.onError) {\n callbacks.onError(error instanceof Error ? error : new Error('Failed to get response'));\n }\n }\n };\n\n void poll();\n\n return {\n cancel: () => {\n cancelled = true;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n },\n };\n }\n\n async fetchMessages(sessionId: string, since?: string): Promise<ChatPollResponse> {\n const url = new URL(`${this.apiBaseUrl}/api/chat/${sessionId}/poll/`);\n if (since) {\n url.searchParams.set('since', since);\n }\n\n const response = await this.request(url.toString(), {\n headers: this.getCommonHeaders(),\n });\n if (!response.ok) {\n await this.raiseForStatus(response, 'Failed to poll messages');\n }\n\n return response.json() as Promise<ChatPollResponse>;\n }\n\n /**\n * Fetch the complete message history for a session by paging through the\n * poll endpoint until no more messages remain.\n */\n async fetchAllMessages(sessionId: string): Promise<ChatMessage[]> {\n const allMessages: ChatMessage[] = [];\n let since: string | undefined;\n let hasMore = true;\n\n for (let page = 0; hasMore && page < ChatSessionService.MAX_HISTORY_PAGES; page++) {\n const data = await this.fetchMessages(sessionId, since);\n allMessages.push(...data.messages);\n hasMore = data.has_more && data.messages.length > 0;\n // The server returns pages in ascending created_at order and `since` is\n // exclusive (created_at > since), so the last message's timestamp is the\n // next page cursor.\n since = data.messages.at(-1)?.created_at;\n }\n\n if (hasMore) {\n console.warn('Chat history truncated after', ChatSessionService.MAX_HISTORY_PAGES, 'pages');\n }\n\n return allMessages;\n }\n\n startMessagePolling(sessionId: string, callbacks: MessagePollingCallbacks): MessagePollingHandle {\n const poll = async () => {\n try {\n const since = callbacks.getSince();\n const data = await this.fetchMessages(sessionId, since);\n if (data.messages.length > 0) {\n callbacks.onMessages(data.messages);\n }\n } catch (error) {\n if (callbacks.onError) {\n callbacks.onError(error instanceof Error ? error : new Error('Failed to poll messages'));\n }\n }\n };\n\n // perform an initial poll immediately\n void poll();\n\n this.messagePollingTimer = setInterval(() => {\n void poll();\n }, this.messagePollingIntervalMs);\n\n return {\n stop: () => this.stopMessagePolling(),\n };\n }\n\n stopMessagePolling(): void {\n if (this.messagePollingTimer) {\n clearInterval(this.messagePollingTimer);\n this.messagePollingTimer = undefined;\n }\n }\n\n setSessionToken(token?: string): void {\n this.sessionToken = token;\n }\n\n private async request(input: string, init?: RequestInit): Promise<Response> {\n const response = await fetch(input, init);\n this.checkSunsetHeaders(response);\n return response;\n }\n\n /**\n * Log a deprecation warning (RFC 8594 `Deprecation`/`Sunset`/`Link` headers)\n * when the server reports that this widget version is deprecated. Warns\n * during the deprecation window and errors once the sunset date has passed.\n * Logs at most once per level so polling does not flood the console.\n */\n private checkSunsetHeaders(response: Response): void {\n const headers = response?.headers;\n if (!headers || typeof headers.get !== 'function') {\n return;\n }\n if (headers.get('Deprecation') !== 'true') {\n return;\n }\n\n const sunsetAt = this.parseSunsetDate(headers.get('Sunset'));\n const pastSunset = sunsetAt !== null && Date.now() >= sunsetAt.getTime();\n const level: 'warn' | 'error' = pastSunset ? 'error' : 'warn';\n if (this.loggedSunsetLevel === level) {\n return;\n }\n this.loggedSunsetLevel = level;\n\n const upgradeUrl = this.parseSuccessorUrl(headers.get('Link'));\n const upgradeSuffix = upgradeUrl ? ` Upgrade: ${upgradeUrl}` : '';\n const sunsetText = sunsetAt ? sunsetAt.toUTCString() : 'an upcoming date';\n if (level === 'error') {\n console.error(`[open-chat-studio-widget] Widget version ${this.widgetVersion} is past its sunset date ` + `(${sunsetText}) and may stop working.${upgradeSuffix}`);\n } else {\n console.warn(`[open-chat-studio-widget] Widget version ${this.widgetVersion} is deprecated and will stop ` + `working after ${sunsetText}.${upgradeSuffix}`);\n }\n }\n\n private parseSunsetDate(sunset: string | null): Date | null {\n if (!sunset) {\n return null;\n }\n const parsed = new Date(sunset);\n return Number.isNaN(parsed.getTime()) ? null : parsed;\n }\n\n private parseSuccessorUrl(link: string | null): string | undefined {\n const match = link?.match(/<([^>]+)>\\s*;\\s*rel=\"?successor-version\"?/);\n return match?.[1];\n }\n\n private async raiseForStatus(response: Response, fallbackPrefix: string): Promise<never> {\n let message = `${fallbackPrefix}: ${response.statusText}`;\n let code: string | undefined;\n try {\n const data = (await response.json()) as { error?: string; code?: string };\n if (data?.error) {\n message = data.error;\n }\n code = data?.code;\n } catch {\n // non-JSON body; keep statusText fallback\n }\n if (response.status === 403) {\n throw new SessionAccessError(response.status, code, message);\n }\n throw new Error(message);\n }\n\n /** Headers for multipart requests (no Content-Type — fetch sets the boundary). */\n getUploadHeaders(): Record<string, string> {\n const headers = this.getCommonHeaders();\n\n const csrfToken = this.csrfTokenProvider(this.apiBaseUrl);\n if (csrfToken) {\n headers['X-CSRFToken'] = csrfToken;\n }\n\n return headers;\n }\n\n private getJsonHeaders(): Record<string, string> {\n const headers = this.getUploadHeaders();\n headers['Content-Type'] = 'application/json';\n return headers;\n }\n\n private getCommonHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'x-ocs-widget-version': this.widgetVersion,\n };\n\n if (this.embedKey) {\n headers['X-Embed-Key'] = this.embedKey;\n }\n\n if (this.sessionToken) {\n headers['X-Session-Token'] = this.sessionToken;\n }\n\n return headers;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chat-session-service.js","sourceRoot":"","sources":["../../src/services/chat-session-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { getCSRFToken } from '../utils/cookies';\n\nexport class SessionAccessError extends Error {\n readonly status: number;\n readonly code?: string;\n\n constructor(status: number, code: string | undefined, message: string) {\n super(message);\n this.name = 'SessionAccessError';\n this.status = status;\n this.code = code;\n }\n}\n\nexport type ChatRole = 'system' | 'user' | 'assistant';\n\nexport interface ChatAttachment {\n name: string;\n content_type: string;\n size: number;\n}\n\nexport interface ChatMessage {\n created_at: string;\n role: ChatRole;\n content: string;\n metadata?: unknown;\n attachments?: ChatAttachment[];\n}\n\nexport interface ChatStartSessionResponse {\n session_id: string;\n session_token?: string | null;\n chatbot: unknown;\n participant: unknown;\n}\n\nexport interface ChatSendMessageResponse {\n task_id: string;\n status: 'processing' | 'completed' | 'error';\n error?: string;\n}\n\nexport interface ChatTaskPollResponse {\n message?: ChatMessage;\n status: 'processing' | 'complete';\n error?: string;\n}\n\nexport interface ChatPollResponse {\n messages: ChatMessage[];\n has_more: boolean;\n session_status: 'active' | 'ended';\n}\n\nexport interface ChatSessionServiceOptions {\n apiBaseUrl: string;\n embedKey?: string;\n widgetVersion: string;\n sessionToken?: string;\n csrfTokenProvider?: (apiBaseUrl: string) => string | undefined;\n taskPollingIntervalMs?: number;\n taskPollingMaxAttempts?: number;\n messagePollingIntervalMs?: number;\n}\n\nexport interface TaskPollingCallbacks {\n onMessage: (message: ChatMessage) => void;\n onProgress?: (message: string) => void;\n onTimeout?: () => void;\n onError?: (error: Error) => void;\n}\n\nexport interface TaskPollingHandle {\n cancel: () => void;\n}\n\nexport interface MessagePollingCallbacks {\n getSince: () => string | undefined;\n onMessages: (messages: ChatMessage[]) => void;\n /** Called once when the server reports the session has ended; polling stops first. */\n onSessionEnded?: () => void;\n onError?: (error: Error) => void;\n}\n\nexport interface MessagePollingHandle {\n stop: () => void;\n}\n\nexport class ChatSessionService {\n private readonly apiBaseUrl: string;\n private readonly embedKey?: string;\n private readonly widgetVersion: string;\n private sessionToken?: string;\n private readonly csrfTokenProvider: (apiBaseUrl: string) => string | undefined;\n private readonly taskPollingIntervalMs: number;\n private readonly taskPollingMaxAttempts: number;\n private readonly messagePollingIntervalMs: number;\n private messagePollingTimer?: ReturnType<typeof setInterval>;\n private loggedSunsetLevel?: 'warn' | 'error';\n private static readonly MAX_HISTORY_PAGES = 40;\n\n constructor(options: ChatSessionServiceOptions) {\n this.apiBaseUrl = options.apiBaseUrl;\n this.embedKey = options.embedKey;\n this.widgetVersion = options.widgetVersion;\n this.sessionToken = options.sessionToken;\n this.csrfTokenProvider = options.csrfTokenProvider ?? getCSRFToken;\n this.taskPollingIntervalMs = options.taskPollingIntervalMs ?? 1000;\n this.taskPollingMaxAttempts = options.taskPollingMaxAttempts ?? 120;\n this.messagePollingIntervalMs = options.messagePollingIntervalMs ?? 30000;\n }\n\n async startSession(requestBody: Record<string, unknown>): Promise<ChatStartSessionResponse> {\n const response = await this.request(`${this.apiBaseUrl}/api/chat/start/`, {\n method: 'POST',\n headers: this.getJsonHeaders(),\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n await this.raiseForStatus(response, 'Failed to start session');\n }\n\n return response.json() as Promise<ChatStartSessionResponse>;\n }\n\n async sendMessage(sessionId: string, payload: Record<string, unknown>): Promise<ChatSendMessageResponse> {\n const response = await this.request(`${this.apiBaseUrl}/api/chat/${sessionId}/message/`, {\n method: 'POST',\n headers: this.getJsonHeaders(),\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n await this.raiseForStatus(response, 'Failed to send message');\n }\n\n return response.json() as Promise<ChatSendMessageResponse>;\n }\n\n async pollTaskOnce(sessionId: string, taskId: string): Promise<ChatTaskPollResponse> {\n const response = await this.request(`${this.apiBaseUrl}/api/chat/${sessionId}/${taskId}/poll/`, {\n headers: this.getCommonHeaders(),\n });\n\n if (!response.ok) {\n await this.raiseForStatus(response, 'Failed to poll task');\n }\n\n return response.json() as Promise<ChatTaskPollResponse>;\n }\n\n pollTask(sessionId: string, taskId: string, callbacks: TaskPollingCallbacks): TaskPollingHandle {\n let attempts = 0;\n let cancelled = false;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const scheduleNextPoll = () => {\n timeoutId = setTimeout(() => {\n void poll();\n }, this.taskPollingIntervalMs);\n };\n\n const poll = async () => {\n if (cancelled) {\n return;\n }\n\n try {\n const data = await this.pollTaskOnce(sessionId, taskId);\n\n if (data.error) {\n throw new Error(data.error);\n }\n\n if (data.status === 'complete' && data.message) {\n callbacks.onMessage(data.message);\n return;\n }\n\n if (data.status === 'processing' && data.message?.content && callbacks.onProgress) {\n callbacks.onProgress(data.message.content);\n }\n\n attempts += 1;\n if (attempts >= this.taskPollingMaxAttempts) {\n if (callbacks.onTimeout) {\n callbacks.onTimeout();\n }\n return;\n }\n\n scheduleNextPoll();\n } catch (error) {\n if (callbacks.onError) {\n callbacks.onError(error instanceof Error ? error : new Error('Failed to get response'));\n }\n }\n };\n\n void poll();\n\n return {\n cancel: () => {\n cancelled = true;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n },\n };\n }\n\n async fetchMessages(sessionId: string, since?: string): Promise<ChatPollResponse> {\n const url = new URL(`${this.apiBaseUrl}/api/chat/${sessionId}/poll/`);\n if (since) {\n url.searchParams.set('since', since);\n }\n\n const response = await this.request(url.toString(), {\n headers: this.getCommonHeaders(),\n });\n if (!response.ok) {\n await this.raiseForStatus(response, 'Failed to poll messages');\n }\n\n return response.json() as Promise<ChatPollResponse>;\n }\n\n /**\n * Fetch the complete message history for a session by paging through the\n * poll endpoint until no more messages remain.\n */\n async fetchAllMessages(sessionId: string): Promise<ChatMessage[]> {\n const allMessages: ChatMessage[] = [];\n let since: string | undefined;\n let hasMore = true;\n\n for (let page = 0; hasMore && page < ChatSessionService.MAX_HISTORY_PAGES; page++) {\n const data = await this.fetchMessages(sessionId, since);\n allMessages.push(...data.messages);\n hasMore = data.has_more && data.messages.length > 0;\n // The server returns pages in ascending created_at order and `since` is\n // exclusive (created_at > since), so the last message's timestamp is the\n // next page cursor.\n since = data.messages.at(-1)?.created_at;\n }\n\n if (hasMore) {\n console.warn('Chat history truncated after', ChatSessionService.MAX_HISTORY_PAGES, 'pages');\n }\n\n return allMessages;\n }\n\n startMessagePolling(sessionId: string, callbacks: MessagePollingCallbacks): MessagePollingHandle {\n const poll = async () => {\n try {\n const since = callbacks.getSince();\n const data = await this.fetchMessages(sessionId, since);\n if (data.messages.length > 0) {\n callbacks.onMessages(data.messages);\n }\n if (data.session_status === 'ended') {\n this.stopMessagePolling();\n callbacks.onSessionEnded?.();\n }\n } catch (error) {\n if (callbacks.onError) {\n callbacks.onError(error instanceof Error ? error : new Error('Failed to poll messages'));\n }\n }\n };\n\n // perform an initial poll immediately\n void poll();\n\n this.messagePollingTimer = setInterval(() => {\n void poll();\n }, this.messagePollingIntervalMs);\n\n return {\n stop: () => this.stopMessagePolling(),\n };\n }\n\n stopMessagePolling(): void {\n if (this.messagePollingTimer) {\n clearInterval(this.messagePollingTimer);\n this.messagePollingTimer = undefined;\n }\n }\n\n setSessionToken(token?: string): void {\n this.sessionToken = token;\n }\n\n private async request(input: string, init?: RequestInit): Promise<Response> {\n const response = await fetch(input, init);\n this.checkSunsetHeaders(response);\n return response;\n }\n\n /**\n * Log a deprecation warning (RFC 8594 `Deprecation`/`Sunset`/`Link` headers)\n * when the server reports that this widget version is deprecated. Warns\n * during the deprecation window and errors once the sunset date has passed.\n * Logs at most once per level so polling does not flood the console.\n */\n private checkSunsetHeaders(response: Response): void {\n const headers = response?.headers;\n if (!headers || typeof headers.get !== 'function') {\n return;\n }\n if (headers.get('Deprecation') !== 'true') {\n return;\n }\n\n const sunsetAt = this.parseSunsetDate(headers.get('Sunset'));\n const pastSunset = sunsetAt !== null && Date.now() >= sunsetAt.getTime();\n const level: 'warn' | 'error' = pastSunset ? 'error' : 'warn';\n if (this.loggedSunsetLevel === level) {\n return;\n }\n this.loggedSunsetLevel = level;\n\n const upgradeUrl = this.parseSuccessorUrl(headers.get('Link'));\n const upgradeSuffix = upgradeUrl ? ` Upgrade: ${upgradeUrl}` : '';\n const sunsetText = sunsetAt ? sunsetAt.toUTCString() : 'an upcoming date';\n if (level === 'error') {\n console.error(`[open-chat-studio-widget] Widget version ${this.widgetVersion} is past its sunset date ` + `(${sunsetText}) and may stop working.${upgradeSuffix}`);\n } else {\n console.warn(`[open-chat-studio-widget] Widget version ${this.widgetVersion} is deprecated and will stop ` + `working after ${sunsetText}.${upgradeSuffix}`);\n }\n }\n\n private parseSunsetDate(sunset: string | null): Date | null {\n if (!sunset) {\n return null;\n }\n const parsed = new Date(sunset);\n return Number.isNaN(parsed.getTime()) ? null : parsed;\n }\n\n private parseSuccessorUrl(link: string | null): string | undefined {\n const match = link?.match(/<([^>]+)>\\s*;\\s*rel=\"?successor-version\"?/);\n return match?.[1];\n }\n\n private async raiseForStatus(response: Response, fallbackPrefix: string): Promise<never> {\n let message = `${fallbackPrefix}: ${response.statusText}`;\n let code: string | undefined;\n try {\n const data = (await response.json()) as { error?: string; code?: string };\n if (data?.error) {\n message = data.error;\n }\n code = data?.code;\n } catch {\n // non-JSON body; keep statusText fallback\n }\n if (response.status === 403) {\n throw new SessionAccessError(response.status, code, message);\n }\n throw new Error(message);\n }\n\n /** Headers for multipart requests (no Content-Type — fetch sets the boundary). */\n getUploadHeaders(): Record<string, string> {\n const headers = this.getCommonHeaders();\n\n const csrfToken = this.csrfTokenProvider(this.apiBaseUrl);\n if (csrfToken) {\n headers['X-CSRFToken'] = csrfToken;\n }\n\n return headers;\n }\n\n private getJsonHeaders(): Record<string, string> {\n const headers = this.getUploadHeaders();\n headers['Content-Type'] = 'application/json';\n return headers;\n }\n\n private getCommonHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'x-ocs-widget-version': this.widgetVersion,\n };\n\n if (this.embedKey) {\n headers['X-Embed-Key'] = this.embedKey;\n }\n\n if (this.sessionToken) {\n headers['X-Session-Token'] = this.sessionToken;\n }\n\n return headers;\n }\n}\n"]}
|