{"version":3,"file":"ServerSentEventsTransport.js","sourceRoot":"","sources":["../../src/ServerSentEventsTransport.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) .NET Foundation. All rights reserved.\r\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\r\n\r\nimport { HttpClient } from \"./HttpClient\";\r\nimport { MessageHeaders } from \"./IHubProtocol\";\r\nimport { ILogger, LogLevel } from \"./ILogger\";\r\nimport { ITransport, TransferFormat } from \"./ITransport\";\r\nimport { EventSourceConstructor } from \"./Polyfills\";\r\nimport { Arg, getDataDetail, getUserAgentHeader, Platform, sendMessage } from \"./Utils\";\r\n\r\n/** @private */\r\nexport class ServerSentEventsTransport implements ITransport {\r\n private readonly httpClient: HttpClient;\r\n private readonly accessTokenFactory: (() => string | Promise) | undefined;\r\n private readonly logger: ILogger;\r\n private readonly logMessageContent: boolean;\r\n private readonly withCredentials: boolean;\r\n private readonly eventSourceConstructor: EventSourceConstructor;\r\n private eventSource?: EventSource;\r\n private url?: string;\r\n private headers: MessageHeaders;\r\n\r\n public onreceive: ((data: string | ArrayBuffer) => void) | null;\r\n public onclose: ((error?: Error) => void) | null;\r\n\r\n constructor(httpClient: HttpClient, accessTokenFactory: (() => string | Promise) | undefined, logger: ILogger,\r\n logMessageContent: boolean, eventSourceConstructor: EventSourceConstructor, withCredentials: boolean, headers: MessageHeaders) {\r\n this.httpClient = httpClient;\r\n this.accessTokenFactory = accessTokenFactory;\r\n this.logger = logger;\r\n this.logMessageContent = logMessageContent;\r\n this.withCredentials = withCredentials;\r\n this.eventSourceConstructor = eventSourceConstructor;\r\n this.headers = headers;\r\n\r\n this.onreceive = null;\r\n this.onclose = null;\r\n }\r\n\r\n public async connect(url: string, transferFormat: TransferFormat): Promise {\r\n Arg.isRequired(url, \"url\");\r\n Arg.isRequired(transferFormat, \"transferFormat\");\r\n Arg.isIn(transferFormat, TransferFormat, \"transferFormat\");\r\n\r\n this.logger.log(LogLevel.Trace, \"(SSE transport) Connecting.\");\r\n\r\n // set url before accessTokenFactory because this.url is only for send and we set the auth header instead of the query string for send\r\n this.url = url;\r\n\r\n if (this.accessTokenFactory) {\r\n const token = await this.accessTokenFactory();\r\n if (token) {\r\n url += (url.indexOf(\"?\") < 0 ? \"?\" : \"&\") + `access_token=${encodeURIComponent(token)}`;\r\n }\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n let opened = false;\r\n if (transferFormat !== TransferFormat.Text) {\r\n reject(new Error(\"The Server-Sent Events transport only supports the 'Text' transfer format\"));\r\n return;\r\n }\r\n\r\n let eventSource: EventSource;\r\n if (Platform.isBrowser || Platform.isWebWorker) {\r\n eventSource = new this.eventSourceConstructor(url, { withCredentials: this.withCredentials });\r\n } else {\r\n // Non-browser passes cookies via the dictionary\r\n const cookies = this.httpClient.getCookieString(url);\r\n const headers: MessageHeaders = {};\r\n headers.Cookie = cookies;\r\n const [name, value] = getUserAgentHeader();\r\n headers[name] = value;\r\n\r\n eventSource = new this.eventSourceConstructor(url, { withCredentials: this.withCredentials, headers: { ...headers, ...this.headers} } as EventSourceInit);\r\n }\r\n\r\n try {\r\n eventSource.onmessage = (e: MessageEvent) => {\r\n if (this.onreceive) {\r\n try {\r\n this.logger.log(LogLevel.Trace, `(SSE transport) data received. ${getDataDetail(e.data, this.logMessageContent)}.`);\r\n this.onreceive(e.data);\r\n } catch (error) {\r\n this.close(error);\r\n return;\r\n }\r\n }\r\n };\r\n\r\n eventSource.onerror = (e: MessageEvent) => {\r\n const error = new Error(e.data || \"Error occurred\");\r\n if (opened) {\r\n this.close(error);\r\n } else {\r\n reject(error);\r\n }\r\n };\r\n\r\n eventSource.onopen = () => {\r\n this.logger.log(LogLevel.Information, `SSE connected to ${this.url}`);\r\n this.eventSource = eventSource;\r\n opened = true;\r\n resolve();\r\n };\r\n } catch (e) {\r\n reject(e);\r\n return;\r\n }\r\n });\r\n }\r\n\r\n public async send(data: any): Promise {\r\n if (!this.eventSource) {\r\n return Promise.reject(new Error(\"Cannot send until the transport is connected\"));\r\n }\r\n return sendMessage(this.logger, \"SSE\", this.httpClient, this.url!, this.accessTokenFactory, data, this.logMessageContent, this.withCredentials, this.headers);\r\n }\r\n\r\n public stop(): Promise {\r\n this.close();\r\n return Promise.resolve();\r\n }\r\n\r\n private close(e?: Error) {\r\n if (this.eventSource) {\r\n this.eventSource.close();\r\n this.eventSource = undefined;\r\n\r\n if (this.onclose) {\r\n this.onclose(e);\r\n }\r\n }\r\n }\r\n}\r\n"]}