{"version":3,"sources":["webpack:///../../src/ILogger.ts","webpack:///../../src/TextMessageFormat.ts","webpack:///../../src/HttpClient.ts","webpack:///../../src/NodeHttpClient.ts","webpack:///../../src/HandshakeProtocol.ts","webpack:///../../src/Utils.ts","webpack:///../../src/Loggers.ts","webpack:///../../src/IHubProtocol.ts","webpack:///../../src/XhrHttpClient.ts","webpack:///../../src/DefaultHttpClient.ts","webpack:///../../src/HubConnection.ts","webpack:///../../src/Subject.ts","webpack:///../../src/ITransport.ts","webpack:///../../src/DefaultReconnectPolicy.ts","webpack:///../../src/AbortController.ts","webpack:///../../src/LongPollingTransport.ts","webpack:///../../src/ServerSentEventsTransport.ts","webpack:///../../src/WebSocketTransport.ts","webpack:///../../src/HttpConnection.ts","webpack:///../../src/JsonHubProtocol.ts","webpack:///../../src/HubConnectionBuilder.ts","webpack:///../../src/Errors.ts"],"names":["LogLevel","write","output","TextMessageFormat","RecordSeparator","parse","input","length","Error","messages","split","pop","RecordSeparatorCode","String","fromCharCode","statusCode","statusText","content","get","url","options","this","send","method","post","delete","getCookieString","requestModule","XMLHttpRequest","requireFunc","logger","cookieJar","jar","request","defaults","httpRequest","abortSignal","aborted","Promise","reject","resolve","requestBody","Buffer","from","currentRequest","body","encoding","responseType","headers","timeout","error","response","onabort","code","log","Warning","statusMessage","abort","writeHandshakeRequest","handshakeRequest","JSON","stringify","parseHandshakeResponse","data","responseMessage","messageData","remainingData","binaryData","Uint8Array","separatorIndex","indexOf","responseLength","apply","slice","byteLength","buffer","textData","substring","type","isRequired","val","name","undefined","isIn","values","window","self","isBrowser","isWebWorker","includeContent","detail","isArrayBuffer","formatArrayBuffer","view","str","forEach","num","pad","toString","substr","ArrayBuffer","constructor","transportName","httpClient","accessTokenFactory","logMessageContent","token","Trace","getDataDetail","ConsoleLogger","Information","instance","subject","observer","dispose","index","observers","splice","cancelCallback","catch","_","minimumLogLevel","outputConsole","console","logLevel","message","Critical","Date","toISOString","warn","info","_logLevel","_message","NullLogger","MessageType","xhr","open","withCredentials","setRequestHeader","Object","keys","header","onload","status","responseText","onerror","ontimeout","HttpClient","NodeHttpClient","HubConnectionState","next","item","err","complete","subscribe","push","DEFAULT_TIMEOUT_IN_MS","DEFAULT_PING_INTERVAL_IN_MS","HttpTransportType","TransferFormat","connection","protocol","reconnectPolicy","nextKeepAlive","serverTimeoutInMilliseconds","keepAliveIntervalInMilliseconds","handshakeProtocol","HandshakeProtocol","onreceive","processIncomingData","onclose","connectionClosed","callbacks","methods","closedCallbacks","reconnectingCallbacks","reconnectedCallbacks","invocationId","receivedHandshakeResponse","connectionState","Disconnected","connectionStarted","cachedPingMessage","writeMessage","Ping","create","HubConnection","connectionId","baseUrl","Reconnecting","start","startPromise","startWithStateTransitions","Connecting","Debug","startInternal","Connected","stopDuringStartError","handshakePromise","handshakeResolver","handshakeRejecter","transferFormat","version","sendMessage","cleanupTimeout","resetTimeoutPeriod","resetKeepAliveInterval","cleanupPingTimer","stop","stopPromise","stopInternal","Disconnecting","reconnectDelayHandle","clearTimeout","completeClose","stream","methodName","promiseQueue","streams","streamIds","invocationDescriptor","createStreamInvocation","args","cancelInvocation","createCancelInvocation","then","sendWithProtocol","invocationEvent","Completion","e","launchStreams","sendPromise","createInvocation","invoke","p","result","on","newMethod","toLowerCase","off","handlers","removeIdx","callback","onreconnecting","onreconnected","processHandshakeResponse","parseMessages","Invocation","invokeClientMethod","StreamItem","Close","allowReconnect","features","inherentKeepAlive","getTime","timeoutHandle","setTimeout","pingServerHandle","nextPing","serverTimeout","invocationMessage","target","m","cancelCallbacksWithError","reconnect","c","reconnectStartTime","now","previousReconnectAttempts","retryError","nextRetryDelay","getNextRetryDelay","previousRetryCount","elapsedMilliseconds","retryReason","nextRetryDelayInMilliseconds","key","nonblocking","arguments","streamId","createCompletionMessage","createStreamItemMessage","replaceStreamingParams","i","argument","isObservable","arg","StreamInvocation","id","CancelInvocation","DEFAULT_RETRY_DELAYS_IN_MILLISECONDS","retryDelays","retryContext","isAborted","pollAbort","AbortController","running","connect","Binary","pollOptions","signal","getAccessToken","updateHeaderToken","pollUrl","closeError","receiving","poll","pollAborted","raiseOnClose","deleteOptions","logMessage","eventSourceConstructor","encodeURIComponent","opened","Text","eventSource","cookies","Cookie","onmessage","close","onopen","webSocketConstructor","webSocket","replace","isNode","binaryType","_event","event","ErrorEvent","readyState","OPEN","wasClean","reason","MAX_REDIRECTS","WebSocketModule","EventSourceModule","stopPromiseResolver","negotiateVersion","resolveUrl","WebSocket","EventSource","startInternalPromise","sendQueue","TransportSendQueue","transport","stopError","stopConnection","skipNegotiation","WebSockets","constructTransport","startTransport","negotiateResponse","redirects","getNegotiationResponse","ProtocolVersion","accessToken","createTransport","negotiateUrl","resolveNegotiateUrl","connectionToken","createConnectUrl","requestedTransport","requestedTransferFormat","connectUrl","isITransport","transportExceptions","transports","availableTransports","negotiate","endpoint","transportOrError","resolveTransportOrError","join","ServerSentEvents","LongPolling","transportMatches","transferFormats","map","s","ex","lastIndexOf","document","aTag","createElement","href","actualTransport","executing","sendBufferedData","PromiseSource","transportResult","sendLoopPromise","sendLoop","bufferData","promise","concatBuffers","arrayBuffers","totalLength","b","reduce","a","offset","set","resolver","rejecter","JSON_HUB_PROTOCOL_NAME","hubMessages","parsedMessage","isInvocationMessage","isStreamItemMessage","isCompletionMessage","assertNotEmptyString","value","errorMessage","LogLevelNameMapping","trace","debug","information","warning","critical","none","None","parseLogLevel","mapping","configureLogging","logging","isLogger","withUrl","transportTypeOrOptions","httpConnectionOptions","withHubProtocol","withAutomaticReconnect","retryDelaysOrReconnectPolicy","Array","isArray","DefaultReconnectPolicy","build","trueProto","prototype","__proto__"],"mappings":"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","file":"js/chunk-vendors~4c8d9978.c396355b.js","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\n// These values are designed to match the ASP.NET Log Levels since that's the pattern we're emulating here.\r\n/** Indicates the severity of a log message.\r\n *\r\n * Log Levels are ordered in increasing severity. So `Debug` is more severe than `Trace`, etc.\r\n */\r\nexport enum LogLevel {\r\n /** Log level for very low severity diagnostic messages. */\r\n Trace = 0,\r\n /** Log level for low severity diagnostic messages. */\r\n Debug = 1,\r\n /** Log level for informational diagnostic messages. */\r\n Information = 2,\r\n /** Log level for diagnostic messages that indicate a non-fatal problem. */\r\n Warning = 3,\r\n /** Log level for diagnostic messages that indicate a failure in the current operation. */\r\n Error = 4,\r\n /** Log level for diagnostic messages that indicate a failure that will terminate the entire application. */\r\n Critical = 5,\r\n /** The highest possible log level. Used when configuring logging to indicate that no log messages should be emitted. */\r\n None = 6,\r\n}\r\n\r\n/** An abstraction that provides a sink for diagnostic messages. */\r\nexport interface ILogger {\r\n /** Called by the framework to emit a diagnostic message.\r\n *\r\n * @param {LogLevel} logLevel The severity level of the message.\r\n * @param {string} message The message.\r\n */\r\n log(logLevel: LogLevel, message: string): void;\r\n}\r\n","// 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\n// Not exported from index\r\n/** @private */\r\nexport class TextMessageFormat {\r\n public static RecordSeparatorCode = 0x1e;\r\n public static RecordSeparator = String.fromCharCode(TextMessageFormat.RecordSeparatorCode);\r\n\r\n public static write(output: string): string {\r\n return `${output}${TextMessageFormat.RecordSeparator}`;\r\n }\r\n\r\n public static parse(input: string): string[] {\r\n if (input[input.length - 1] !== TextMessageFormat.RecordSeparator) {\r\n throw new Error(\"Message is incomplete.\");\r\n }\r\n\r\n const messages = input.split(TextMessageFormat.RecordSeparator);\r\n messages.pop();\r\n return messages;\r\n }\r\n}\r\n","// 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 { AbortSignal } from \"./AbortController\";\r\n\r\n/** Represents an HTTP request. */\r\nexport interface HttpRequest {\r\n /** The HTTP method to use for the request. */\r\n method?: string;\r\n\r\n /** The URL for the request. */\r\n url?: string;\r\n\r\n /** The body content for the request. May be a string or an ArrayBuffer (for binary data). */\r\n content?: string | ArrayBuffer;\r\n\r\n /** An object describing headers to apply to the request. */\r\n headers?: { [key: string]: string };\r\n\r\n /** The XMLHttpRequestResponseType to apply to the request. */\r\n responseType?: XMLHttpRequestResponseType;\r\n\r\n /** An AbortSignal that can be monitored for cancellation. */\r\n abortSignal?: AbortSignal;\r\n\r\n /** The time to wait for the request to complete before throwing a TimeoutError. Measured in milliseconds. */\r\n timeout?: number;\r\n}\r\n\r\n/** Represents an HTTP response. */\r\nexport class HttpResponse {\r\n /** Constructs a new instance of {@link @microsoft/signalr.HttpResponse} with the specified status code.\r\n *\r\n * @param {number} statusCode The status code of the response.\r\n */\r\n constructor(statusCode: number);\r\n\r\n /** Constructs a new instance of {@link @microsoft/signalr.HttpResponse} with the specified status code and message.\r\n *\r\n * @param {number} statusCode The status code of the response.\r\n * @param {string} statusText The status message of the response.\r\n */\r\n constructor(statusCode: number, statusText: string);\r\n\r\n /** Constructs a new instance of {@link @microsoft/signalr.HttpResponse} with the specified status code, message and string content.\r\n *\r\n * @param {number} statusCode The status code of the response.\r\n * @param {string} statusText The status message of the response.\r\n * @param {string} content The content of the response.\r\n */\r\n constructor(statusCode: number, statusText: string, content: string);\r\n\r\n /** Constructs a new instance of {@link @microsoft/signalr.HttpResponse} with the specified status code, message and binary content.\r\n *\r\n * @param {number} statusCode The status code of the response.\r\n * @param {string} statusText The status message of the response.\r\n * @param {ArrayBuffer} content The content of the response.\r\n */\r\n constructor(statusCode: number, statusText: string, content: ArrayBuffer);\r\n constructor(\r\n public readonly statusCode: number,\r\n public readonly statusText?: string,\r\n public readonly content?: string | ArrayBuffer) {\r\n }\r\n}\r\n\r\n/** Abstraction over an HTTP client.\r\n *\r\n * This class provides an abstraction over an HTTP client so that a different implementation can be provided on different platforms.\r\n */\r\nexport abstract class HttpClient {\r\n /** Issues an HTTP GET request to the specified URL, returning a Promise that resolves with an {@link @microsoft/signalr.HttpResponse} representing the result.\r\n *\r\n * @param {string} url The URL for the request.\r\n * @returns {Promise} A Promise that resolves with an {@link @microsoft/signalr.HttpResponse} describing the response, or rejects with an Error indicating a failure.\r\n */\r\n public get(url: string): Promise;\r\n\r\n /** Issues an HTTP GET request to the specified URL, returning a Promise that resolves with an {@link @microsoft/signalr.HttpResponse} representing the result.\r\n *\r\n * @param {string} url The URL for the request.\r\n * @param {HttpRequest} options Additional options to configure the request. The 'url' field in this object will be overridden by the url parameter.\r\n * @returns {Promise} A Promise that resolves with an {@link @microsoft/signalr.HttpResponse} describing the response, or rejects with an Error indicating a failure.\r\n */\r\n public get(url: string, options: HttpRequest): Promise;\r\n public get(url: string, options?: HttpRequest): Promise {\r\n return this.send({\r\n ...options,\r\n method: \"GET\",\r\n url,\r\n });\r\n }\r\n\r\n /** Issues an HTTP POST request to the specified URL, returning a Promise that resolves with an {@link @microsoft/signalr.HttpResponse} representing the result.\r\n *\r\n * @param {string} url The URL for the request.\r\n * @returns {Promise} A Promise that resolves with an {@link @microsoft/signalr.HttpResponse} describing the response, or rejects with an Error indicating a failure.\r\n */\r\n public post(url: string): Promise;\r\n\r\n /** Issues an HTTP POST request to the specified URL, returning a Promise that resolves with an {@link @microsoft/signalr.HttpResponse} representing the result.\r\n *\r\n * @param {string} url The URL for the request.\r\n * @param {HttpRequest} options Additional options to configure the request. The 'url' field in this object will be overridden by the url parameter.\r\n * @returns {Promise} A Promise that resolves with an {@link @microsoft/signalr.HttpResponse} describing the response, or rejects with an Error indicating a failure.\r\n */\r\n public post(url: string, options: HttpRequest): Promise;\r\n public post(url: string, options?: HttpRequest): Promise {\r\n return this.send({\r\n ...options,\r\n method: \"POST\",\r\n url,\r\n });\r\n }\r\n\r\n /** Issues an HTTP DELETE request to the specified URL, returning a Promise that resolves with an {@link @microsoft/signalr.HttpResponse} representing the result.\r\n *\r\n * @param {string} url The URL for the request.\r\n * @returns {Promise} A Promise that resolves with an {@link @microsoft/signalr.HttpResponse} describing the response, or rejects with an Error indicating a failure.\r\n */\r\n public delete(url: string): Promise;\r\n\r\n /** Issues an HTTP DELETE request to the specified URL, returning a Promise that resolves with an {@link @microsoft/signalr.HttpResponse} representing the result.\r\n *\r\n * @param {string} url The URL for the request.\r\n * @param {HttpRequest} options Additional options to configure the request. The 'url' field in this object will be overridden by the url parameter.\r\n * @returns {Promise} A Promise that resolves with an {@link @microsoft/signalr.HttpResponse} describing the response, or rejects with an Error indicating a failure.\r\n */\r\n public delete(url: string, options: HttpRequest): Promise;\r\n public delete(url: string, options?: HttpRequest): Promise {\r\n return this.send({\r\n ...options,\r\n method: \"DELETE\",\r\n url,\r\n });\r\n }\r\n\r\n /** Issues an HTTP request to the specified URL, returning a {@link Promise} that resolves with an {@link @microsoft/signalr.HttpResponse} representing the result.\r\n *\r\n * @param {HttpRequest} request An {@link @microsoft/signalr.HttpRequest} describing the request to send.\r\n * @returns {Promise} A Promise that resolves with an HttpResponse describing the response, or rejects with an Error indicating a failure.\r\n */\r\n public abstract send(request: HttpRequest): Promise;\r\n\r\n /** Gets all cookies that apply to the specified URL.\r\n *\r\n * @param url The URL that the cookies are valid for.\r\n * @returns {string} A string containing all the key-value cookie pairs for the specified URL.\r\n */\r\n // @ts-ignore\r\n public getCookieString(url: string): string {\r\n return \"\";\r\n }\r\n}\r\n","// 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\n// @ts-ignore: This will be removed from built files and is here to make the types available during dev work\r\nimport * as Request from \"@types/request\";\r\n\r\nimport { AbortError, HttpError, TimeoutError } from \"./Errors\";\r\nimport { HttpClient, HttpRequest, HttpResponse } from \"./HttpClient\";\r\nimport { ILogger, LogLevel } from \"./ILogger\";\r\nimport { isArrayBuffer } from \"./Utils\";\r\n\r\nlet requestModule: Request.RequestAPI;\r\nif (typeof XMLHttpRequest === \"undefined\") {\r\n // In order to ignore the dynamic require in webpack builds we need to do this magic\r\n // @ts-ignore: TS doesn't know about these names\r\n const requireFunc = typeof __webpack_require__ === \"function\" ? __non_webpack_require__ : require;\r\n requestModule = requireFunc(\"request\");\r\n}\r\n\r\n/** @private */\r\nexport class NodeHttpClient extends HttpClient {\r\n private readonly logger: ILogger;\r\n private readonly request: typeof requestModule;\r\n private readonly cookieJar: Request.CookieJar;\r\n\r\n public constructor(logger: ILogger) {\r\n super();\r\n if (typeof requestModule === \"undefined\") {\r\n throw new Error(\"The 'request' module could not be loaded.\");\r\n }\r\n\r\n this.logger = logger;\r\n this.cookieJar = requestModule.jar();\r\n this.request = requestModule.defaults({ jar: this.cookieJar });\r\n }\r\n\r\n public send(httpRequest: HttpRequest): Promise {\r\n // Check that abort was not signaled before calling send\r\n if (httpRequest.abortSignal) {\r\n if (httpRequest.abortSignal.aborted) {\r\n return Promise.reject(new AbortError());\r\n }\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n\r\n let requestBody: Buffer | string;\r\n if (isArrayBuffer(httpRequest.content)) {\r\n requestBody = Buffer.from(httpRequest.content);\r\n } else {\r\n requestBody = httpRequest.content || \"\";\r\n }\r\n\r\n const currentRequest = this.request(httpRequest.url!, {\r\n body: requestBody,\r\n // If binary is expected 'null' should be used, otherwise for text 'utf8'\r\n encoding: httpRequest.responseType === \"arraybuffer\" ? null : \"utf8\",\r\n headers: {\r\n // Tell auth middleware to 401 instead of redirecting\r\n \"X-Requested-With\": \"XMLHttpRequest\",\r\n ...httpRequest.headers,\r\n },\r\n method: httpRequest.method,\r\n timeout: httpRequest.timeout,\r\n },\r\n (error, response, body) => {\r\n if (httpRequest.abortSignal) {\r\n httpRequest.abortSignal.onabort = null;\r\n }\r\n\r\n if (error) {\r\n if (error.code === \"ETIMEDOUT\") {\r\n this.logger.log(LogLevel.Warning, `Timeout from HTTP request.`);\r\n reject(new TimeoutError());\r\n }\r\n this.logger.log(LogLevel.Warning, `Error from HTTP request. ${error}`);\r\n reject(error);\r\n return;\r\n }\r\n\r\n if (response.statusCode >= 200 && response.statusCode < 300) {\r\n resolve(new HttpResponse(response.statusCode, response.statusMessage || \"\", body));\r\n } else {\r\n reject(new HttpError(response.statusMessage || \"\", response.statusCode || 0));\r\n }\r\n });\r\n\r\n if (httpRequest.abortSignal) {\r\n httpRequest.abortSignal.onabort = () => {\r\n currentRequest.abort();\r\n reject(new AbortError());\r\n };\r\n }\r\n });\r\n }\r\n\r\n public getCookieString(url: string): string {\r\n return this.cookieJar.getCookieString(url);\r\n }\r\n}\r\n","// 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 { TextMessageFormat } from \"./TextMessageFormat\";\r\nimport { isArrayBuffer } from \"./Utils\";\r\n\r\n/** @private */\r\nexport interface HandshakeRequestMessage {\r\n readonly protocol: string;\r\n readonly version: number;\r\n}\r\n\r\n/** @private */\r\nexport interface HandshakeResponseMessage {\r\n readonly error: string;\r\n readonly minorVersion: number;\r\n}\r\n\r\n/** @private */\r\nexport class HandshakeProtocol {\r\n // Handshake request is always JSON\r\n public writeHandshakeRequest(handshakeRequest: HandshakeRequestMessage): string {\r\n return TextMessageFormat.write(JSON.stringify(handshakeRequest));\r\n }\r\n\r\n public parseHandshakeResponse(data: any): [any, HandshakeResponseMessage] {\r\n let responseMessage: HandshakeResponseMessage;\r\n let messageData: string;\r\n let remainingData: any;\r\n\r\n if (isArrayBuffer(data) || (typeof Buffer !== \"undefined\" && data instanceof Buffer)) {\r\n // Format is binary but still need to read JSON text from handshake response\r\n const binaryData = new Uint8Array(data);\r\n const separatorIndex = binaryData.indexOf(TextMessageFormat.RecordSeparatorCode);\r\n if (separatorIndex === -1) {\r\n throw new Error(\"Message is incomplete.\");\r\n }\r\n\r\n // content before separator is handshake response\r\n // optional content after is additional messages\r\n const responseLength = separatorIndex + 1;\r\n messageData = String.fromCharCode.apply(null, binaryData.slice(0, responseLength));\r\n remainingData = (binaryData.byteLength > responseLength) ? binaryData.slice(responseLength).buffer : null;\r\n } else {\r\n const textData: string = data;\r\n const separatorIndex = textData.indexOf(TextMessageFormat.RecordSeparator);\r\n if (separatorIndex === -1) {\r\n throw new Error(\"Message is incomplete.\");\r\n }\r\n\r\n // content before separator is handshake response\r\n // optional content after is additional messages\r\n const responseLength = separatorIndex + 1;\r\n messageData = textData.substring(0, responseLength);\r\n remainingData = (textData.length > responseLength) ? textData.substring(responseLength) : null;\r\n }\r\n\r\n // At this point we should have just the single handshake message\r\n const messages = TextMessageFormat.parse(messageData);\r\n const response = JSON.parse(messages[0]);\r\n if (response.type) {\r\n throw new Error(\"Expected a handshake response from the server.\");\r\n }\r\n responseMessage = response;\r\n\r\n // multiple messages could have arrived with handshake\r\n // return additional data to be parsed as usual, or null if all parsed\r\n return [remainingData, responseMessage];\r\n }\r\n}\r\n","// 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 { ILogger, LogLevel } from \"./ILogger\";\r\nimport { NullLogger } from \"./Loggers\";\r\nimport { IStreamSubscriber, ISubscription } from \"./Stream\";\r\nimport { Subject } from \"./Subject\";\r\n\r\n/** @private */\r\nexport class Arg {\r\n public static isRequired(val: any, name: string): void {\r\n if (val === null || val === undefined) {\r\n throw new Error(`The '${name}' argument is required.`);\r\n }\r\n }\r\n\r\n public static isIn(val: any, values: any, name: string): void {\r\n // TypeScript enums have keys for **both** the name and the value of each enum member on the type itself.\r\n if (!(val in values)) {\r\n throw new Error(`Unknown ${name} value: ${val}.`);\r\n }\r\n }\r\n}\r\n\r\n/** @private */\r\nexport class Platform {\r\n\r\n public static get isBrowser(): boolean {\r\n return typeof window === \"object\";\r\n }\r\n\r\n public static get isWebWorker(): boolean {\r\n return typeof self === \"object\" && \"importScripts\" in self;\r\n }\r\n\r\n public static get isNode(): boolean {\r\n return !this.isBrowser && !this.isWebWorker;\r\n }\r\n}\r\n\r\n/** @private */\r\nexport function getDataDetail(data: any, includeContent: boolean): string {\r\n let detail = \"\";\r\n if (isArrayBuffer(data)) {\r\n detail = `Binary data of length ${data.byteLength}`;\r\n if (includeContent) {\r\n detail += `. Content: '${formatArrayBuffer(data)}'`;\r\n }\r\n } else if (typeof data === \"string\") {\r\n detail = `String data of length ${data.length}`;\r\n if (includeContent) {\r\n detail += `. Content: '${data}'`;\r\n }\r\n }\r\n return detail;\r\n}\r\n\r\n/** @private */\r\nexport function formatArrayBuffer(data: ArrayBuffer): string {\r\n const view = new Uint8Array(data);\r\n\r\n // Uint8Array.map only supports returning another Uint8Array?\r\n let str = \"\";\r\n view.forEach((num) => {\r\n const pad = num < 16 ? \"0\" : \"\";\r\n str += `0x${pad}${num.toString(16)} `;\r\n });\r\n\r\n // Trim of trailing space.\r\n return str.substr(0, str.length - 1);\r\n}\r\n\r\n// Also in signalr-protocol-msgpack/Utils.ts\r\n/** @private */\r\nexport function isArrayBuffer(val: any): val is ArrayBuffer {\r\n return val && typeof ArrayBuffer !== \"undefined\" &&\r\n (val instanceof ArrayBuffer ||\r\n // Sometimes we get an ArrayBuffer that doesn't satisfy instanceof\r\n (val.constructor && val.constructor.name === \"ArrayBuffer\"));\r\n}\r\n\r\n/** @private */\r\nexport async function sendMessage(logger: ILogger, transportName: string, httpClient: HttpClient, url: string, accessTokenFactory: (() => string | Promise) | undefined, content: string | ArrayBuffer, logMessageContent: boolean): Promise {\r\n let headers;\r\n if (accessTokenFactory) {\r\n const token = await accessTokenFactory();\r\n if (token) {\r\n headers = {\r\n [\"Authorization\"]: `Bearer ${token}`,\r\n };\r\n }\r\n }\r\n\r\n logger.log(LogLevel.Trace, `(${transportName} transport) sending data. ${getDataDetail(content, logMessageContent)}.`);\r\n\r\n const responseType = isArrayBuffer(content) ? \"arraybuffer\" : \"text\";\r\n const response = await httpClient.post(url, {\r\n content,\r\n headers,\r\n responseType,\r\n });\r\n\r\n logger.log(LogLevel.Trace, `(${transportName} transport) request complete. Response status: ${response.statusCode}.`);\r\n}\r\n\r\n/** @private */\r\nexport function createLogger(logger?: ILogger | LogLevel) {\r\n if (logger === undefined) {\r\n return new ConsoleLogger(LogLevel.Information);\r\n }\r\n\r\n if (logger === null) {\r\n return NullLogger.instance;\r\n }\r\n\r\n if ((logger as ILogger).log) {\r\n return logger as ILogger;\r\n }\r\n\r\n return new ConsoleLogger(logger as LogLevel);\r\n}\r\n\r\n/** @private */\r\nexport class SubjectSubscription implements ISubscription {\r\n private subject: Subject;\r\n private observer: IStreamSubscriber;\r\n\r\n constructor(subject: Subject, observer: IStreamSubscriber) {\r\n this.subject = subject;\r\n this.observer = observer;\r\n }\r\n\r\n public dispose(): void {\r\n const index: number = this.subject.observers.indexOf(this.observer);\r\n if (index > -1) {\r\n this.subject.observers.splice(index, 1);\r\n }\r\n\r\n if (this.subject.observers.length === 0 && this.subject.cancelCallback) {\r\n this.subject.cancelCallback().catch((_) => { });\r\n }\r\n }\r\n}\r\n\r\n/** @private */\r\nexport class ConsoleLogger implements ILogger {\r\n private readonly minimumLogLevel: LogLevel;\r\n\r\n // Public for testing purposes.\r\n public outputConsole: {\r\n error(message: any): void,\r\n warn(message: any): void,\r\n info(message: any): void,\r\n log(message: any): void,\r\n };\r\n\r\n constructor(minimumLogLevel: LogLevel) {\r\n this.minimumLogLevel = minimumLogLevel;\r\n this.outputConsole = console;\r\n }\r\n\r\n public log(logLevel: LogLevel, message: string): void {\r\n if (logLevel >= this.minimumLogLevel) {\r\n switch (logLevel) {\r\n case LogLevel.Critical:\r\n case LogLevel.Error:\r\n this.outputConsole.error(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);\r\n break;\r\n case LogLevel.Warning:\r\n this.outputConsole.warn(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);\r\n break;\r\n case LogLevel.Information:\r\n this.outputConsole.info(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);\r\n break;\r\n default:\r\n // console.debug only goes to attached debuggers in Node, so we use console.log for Trace and Debug\r\n this.outputConsole.log(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n","// 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 { ILogger, LogLevel } from \"./ILogger\";\r\n\r\n/** A logger that does nothing when log messages are sent to it. */\r\nexport class NullLogger implements ILogger {\r\n /** The singleton instance of the {@link @microsoft/signalr.NullLogger}. */\r\n public static instance: ILogger = new NullLogger();\r\n\r\n private constructor() {}\r\n\r\n /** @inheritDoc */\r\n // tslint:disable-next-line\r\n public log(_logLevel: LogLevel, _message: string): void {\r\n }\r\n}\r\n","// 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 { ILogger } from \"./ILogger\";\r\nimport { TransferFormat } from \"./ITransport\";\r\n\r\n/** Defines the type of a Hub Message. */\r\nexport enum MessageType {\r\n /** Indicates the message is an Invocation message and implements the {@link @microsoft/signalr.InvocationMessage} interface. */\r\n Invocation = 1,\r\n /** Indicates the message is a StreamItem message and implements the {@link @microsoft/signalr.StreamItemMessage} interface. */\r\n StreamItem = 2,\r\n /** Indicates the message is a Completion message and implements the {@link @microsoft/signalr.CompletionMessage} interface. */\r\n Completion = 3,\r\n /** Indicates the message is a Stream Invocation message and implements the {@link @microsoft/signalr.StreamInvocationMessage} interface. */\r\n StreamInvocation = 4,\r\n /** Indicates the message is a Cancel Invocation message and implements the {@link @microsoft/signalr.CancelInvocationMessage} interface. */\r\n CancelInvocation = 5,\r\n /** Indicates the message is a Ping message and implements the {@link @microsoft/signalr.PingMessage} interface. */\r\n Ping = 6,\r\n /** Indicates the message is a Close message and implements the {@link @microsoft/signalr.CloseMessage} interface. */\r\n Close = 7,\r\n}\r\n\r\n/** Defines a dictionary of string keys and string values representing headers attached to a Hub message. */\r\nexport interface MessageHeaders {\r\n /** Gets or sets the header with the specified key. */\r\n [key: string]: string;\r\n}\r\n\r\n/** Union type of all known Hub messages. */\r\nexport type HubMessage =\r\n InvocationMessage |\r\n StreamInvocationMessage |\r\n StreamItemMessage |\r\n CompletionMessage |\r\n CancelInvocationMessage |\r\n PingMessage |\r\n CloseMessage;\r\n\r\n/** Defines properties common to all Hub messages. */\r\nexport interface HubMessageBase {\r\n /** A {@link @microsoft/signalr.MessageType} value indicating the type of this message. */\r\n readonly type: MessageType;\r\n}\r\n\r\n/** Defines properties common to all Hub messages relating to a specific invocation. */\r\nexport interface HubInvocationMessage extends HubMessageBase {\r\n /** A {@link @microsoft/signalr.MessageHeaders} dictionary containing headers attached to the message. */\r\n readonly headers?: MessageHeaders;\r\n /** The ID of the invocation relating to this message.\r\n *\r\n * This is expected to be present for {@link @microsoft/signalr.StreamInvocationMessage} and {@link @microsoft/signalr.CompletionMessage}. It may\r\n * be 'undefined' for an {@link @microsoft/signalr.InvocationMessage} if the sender does not expect a response.\r\n */\r\n readonly invocationId?: string;\r\n}\r\n\r\n/** A hub message representing a non-streaming invocation. */\r\nexport interface InvocationMessage extends HubInvocationMessage {\r\n /** @inheritDoc */\r\n readonly type: MessageType.Invocation;\r\n /** The target method name. */\r\n readonly target: string;\r\n /** The target method arguments. */\r\n readonly arguments: any[];\r\n /** The target methods stream IDs. */\r\n readonly streamIds: string[];\r\n}\r\n\r\n/** A hub message representing a streaming invocation. */\r\nexport interface StreamInvocationMessage extends HubInvocationMessage {\r\n /** @inheritDoc */\r\n readonly type: MessageType.StreamInvocation;\r\n\r\n /** The invocation ID. */\r\n readonly invocationId: string;\r\n /** The target method name. */\r\n readonly target: string;\r\n /** The target method arguments. */\r\n readonly arguments: any[];\r\n /** The target methods stream IDs. */\r\n readonly streamIds: string[];\r\n}\r\n\r\n/** A hub message representing a single item produced as part of a result stream. */\r\nexport interface StreamItemMessage extends HubInvocationMessage {\r\n /** @inheritDoc */\r\n readonly type: MessageType.StreamItem;\r\n\r\n /** The invocation ID. */\r\n readonly invocationId: string;\r\n\r\n /** The item produced by the server. */\r\n readonly item?: any;\r\n}\r\n\r\n/** A hub message representing the result of an invocation. */\r\nexport interface CompletionMessage extends HubInvocationMessage {\r\n /** @inheritDoc */\r\n readonly type: MessageType.Completion;\r\n /** The invocation ID. */\r\n readonly invocationId: string;\r\n /** The error produced by the invocation, if any.\r\n *\r\n * Either {@link @microsoft/signalr.CompletionMessage.error} or {@link @microsoft/signalr.CompletionMessage.result} must be defined, but not both.\r\n */\r\n readonly error?: string;\r\n /** The result produced by the invocation, if any.\r\n *\r\n * Either {@link @microsoft/signalr.CompletionMessage.error} or {@link @microsoft/signalr.CompletionMessage.result} must be defined, but not both.\r\n */\r\n readonly result?: any;\r\n}\r\n\r\n/** A hub message indicating that the sender is still active. */\r\nexport interface PingMessage extends HubMessageBase {\r\n /** @inheritDoc */\r\n readonly type: MessageType.Ping;\r\n}\r\n\r\n/** A hub message indicating that the sender is closing the connection.\r\n *\r\n * If {@link @microsoft/signalr.CloseMessage.error} is defined, the sender is closing the connection due to an error.\r\n */\r\nexport interface CloseMessage extends HubMessageBase {\r\n /** @inheritDoc */\r\n readonly type: MessageType.Close;\r\n /** The error that triggered the close, if any.\r\n *\r\n * If this property is undefined, the connection was closed normally and without error.\r\n */\r\n readonly error?: string;\r\n\r\n /** If true, clients with automatic reconnects enabled should attempt to reconnect after receiving the CloseMessage. Otherwise, they should not. */\r\n readonly allowReconnect?: boolean;\r\n}\r\n\r\n/** A hub message sent to request that a streaming invocation be canceled. */\r\nexport interface CancelInvocationMessage extends HubInvocationMessage {\r\n /** @inheritDoc */\r\n readonly type: MessageType.CancelInvocation;\r\n /** The invocation ID. */\r\n readonly invocationId: string;\r\n}\r\n\r\n/** A protocol abstraction for communicating with SignalR Hubs. */\r\nexport interface IHubProtocol {\r\n /** The name of the protocol. This is used by SignalR to resolve the protocol between the client and server. */\r\n readonly name: string;\r\n /** The version of the protocol. */\r\n readonly version: number;\r\n /** The {@link @microsoft/signalr.TransferFormat} of the protocol. */\r\n readonly transferFormat: TransferFormat;\r\n\r\n /** Creates an array of {@link @microsoft/signalr.HubMessage} objects from the specified serialized representation.\r\n *\r\n * If {@link @microsoft/signalr.IHubProtocol.transferFormat} is 'Text', the `input` parameter must be a string, otherwise it must be an ArrayBuffer.\r\n *\r\n * @param {string | ArrayBuffer | Buffer} input A string, ArrayBuffer, or Buffer containing the serialized representation.\r\n * @param {ILogger} logger A logger that will be used to log messages that occur during parsing.\r\n */\r\n parseMessages(input: string | ArrayBuffer | Buffer, logger: ILogger): HubMessage[];\r\n\r\n /** Writes the specified {@link @microsoft/signalr.HubMessage} to a string or ArrayBuffer and returns it.\r\n *\r\n * If {@link @microsoft/signalr.IHubProtocol.transferFormat} is 'Text', the result of this method will be a string, otherwise it will be an ArrayBuffer.\r\n *\r\n * @param {HubMessage} message The message to write.\r\n * @returns {string | ArrayBuffer} A string or ArrayBuffer containing the serialized representation of the message.\r\n */\r\n writeMessage(message: HubMessage): string | ArrayBuffer;\r\n}\r\n","// 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 { AbortError, HttpError, TimeoutError } from \"./Errors\";\r\nimport { HttpClient, HttpRequest, HttpResponse } from \"./HttpClient\";\r\nimport { ILogger, LogLevel } from \"./ILogger\";\r\n\r\nexport class XhrHttpClient extends HttpClient {\r\n private readonly logger: ILogger;\r\n\r\n public constructor(logger: ILogger) {\r\n super();\r\n this.logger = logger;\r\n }\r\n\r\n /** @inheritDoc */\r\n public send(request: HttpRequest): Promise {\r\n // Check that abort was not signaled before calling send\r\n if (request.abortSignal && request.abortSignal.aborted) {\r\n return Promise.reject(new AbortError());\r\n }\r\n\r\n if (!request.method) {\r\n return Promise.reject(new Error(\"No method defined.\"));\r\n }\r\n if (!request.url) {\r\n return Promise.reject(new Error(\"No url defined.\"));\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n const xhr = new XMLHttpRequest();\r\n\r\n xhr.open(request.method!, request.url!, true);\r\n xhr.withCredentials = true;\r\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\r\n // Explicitly setting the Content-Type header for React Native on Android platform.\r\n xhr.setRequestHeader(\"Content-Type\", \"text/plain;charset=UTF-8\");\r\n\r\n const headers = request.headers;\r\n if (headers) {\r\n Object.keys(headers)\r\n .forEach((header) => {\r\n xhr.setRequestHeader(header, headers[header]);\r\n });\r\n }\r\n\r\n if (request.responseType) {\r\n xhr.responseType = request.responseType;\r\n }\r\n\r\n if (request.abortSignal) {\r\n request.abortSignal.onabort = () => {\r\n xhr.abort();\r\n reject(new AbortError());\r\n };\r\n }\r\n\r\n if (request.timeout) {\r\n xhr.timeout = request.timeout;\r\n }\r\n\r\n xhr.onload = () => {\r\n if (request.abortSignal) {\r\n request.abortSignal.onabort = null;\r\n }\r\n\r\n if (xhr.status >= 200 && xhr.status < 300) {\r\n resolve(new HttpResponse(xhr.status, xhr.statusText, xhr.response || xhr.responseText));\r\n } else {\r\n reject(new HttpError(xhr.statusText, xhr.status));\r\n }\r\n };\r\n\r\n xhr.onerror = () => {\r\n this.logger.log(LogLevel.Warning, `Error from HTTP request. ${xhr.status}: ${xhr.statusText}.`);\r\n reject(new HttpError(xhr.statusText, xhr.status));\r\n };\r\n\r\n xhr.ontimeout = () => {\r\n this.logger.log(LogLevel.Warning, `Timeout from HTTP request.`);\r\n reject(new TimeoutError());\r\n };\r\n\r\n xhr.send(request.content || \"\");\r\n });\r\n }\r\n}\r\n","// 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 { AbortError } from \"./Errors\";\r\nimport { HttpClient, HttpRequest, HttpResponse } from \"./HttpClient\";\r\nimport { ILogger } from \"./ILogger\";\r\nimport { NodeHttpClient } from \"./NodeHttpClient\";\r\nimport { XhrHttpClient } from \"./XhrHttpClient\";\r\n\r\n/** Default implementation of {@link @microsoft/signalr.HttpClient}. */\r\nexport class DefaultHttpClient extends HttpClient {\r\n private readonly httpClient: HttpClient;\r\n\r\n /** Creates a new instance of the {@link @microsoft/signalr.DefaultHttpClient}, using the provided {@link @microsoft/signalr.ILogger} to log messages. */\r\n public constructor(logger: ILogger) {\r\n super();\r\n\r\n if (typeof XMLHttpRequest !== \"undefined\") {\r\n this.httpClient = new XhrHttpClient(logger);\r\n } else {\r\n this.httpClient = new NodeHttpClient(logger);\r\n }\r\n }\r\n\r\n /** @inheritDoc */\r\n public send(request: HttpRequest): Promise {\r\n // Check that abort was not signaled before calling send\r\n if (request.abortSignal && request.abortSignal.aborted) {\r\n return Promise.reject(new AbortError());\r\n }\r\n\r\n if (!request.method) {\r\n return Promise.reject(new Error(\"No method defined.\"));\r\n }\r\n if (!request.url) {\r\n return Promise.reject(new Error(\"No url defined.\"));\r\n }\r\n\r\n return this.httpClient.send(request);\r\n }\r\n\r\n public getCookieString(url: string): string {\r\n return this.httpClient.getCookieString(url);\r\n }\r\n}\r\n","// 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 { HandshakeProtocol, HandshakeRequestMessage, HandshakeResponseMessage } from \"./HandshakeProtocol\";\r\nimport { IConnection } from \"./IConnection\";\r\nimport { CancelInvocationMessage, CompletionMessage, IHubProtocol, InvocationMessage, MessageType, StreamInvocationMessage, StreamItemMessage } from \"./IHubProtocol\";\r\nimport { ILogger, LogLevel } from \"./ILogger\";\r\nimport { IRetryPolicy } from \"./IRetryPolicy\";\r\nimport { IStreamResult } from \"./Stream\";\r\nimport { Subject } from \"./Subject\";\r\nimport { Arg } from \"./Utils\";\r\n\r\nconst DEFAULT_TIMEOUT_IN_MS: number = 30 * 1000;\r\nconst DEFAULT_PING_INTERVAL_IN_MS: number = 15 * 1000;\r\n\r\n/** Describes the current state of the {@link HubConnection} to the server. */\r\nexport enum HubConnectionState {\r\n /** The hub connection is disconnected. */\r\n Disconnected = \"Disconnected\",\r\n /** The hub connection is connecting. */\r\n Connecting = \"Connecting\",\r\n /** The hub connection is connected. */\r\n Connected = \"Connected\",\r\n /** The hub connection is disconnecting. */\r\n Disconnecting = \"Disconnecting\",\r\n /** The hub connection is reconnecting. */\r\n Reconnecting = \"Reconnecting\",\r\n}\r\n\r\n/** Represents a connection to a SignalR Hub. */\r\nexport class HubConnection {\r\n private readonly cachedPingMessage: string | ArrayBuffer;\r\n private readonly connection: IConnection;\r\n private readonly logger: ILogger;\r\n private readonly reconnectPolicy?: IRetryPolicy;\r\n private protocol: IHubProtocol;\r\n private handshakeProtocol: HandshakeProtocol;\r\n private callbacks: { [invocationId: string]: (invocationEvent: StreamItemMessage | CompletionMessage | null, error?: Error) => void };\r\n private methods: { [name: string]: Array<(...args: any[]) => void> };\r\n private invocationId: number;\r\n\r\n private closedCallbacks: Array<(error?: Error) => void>;\r\n private reconnectingCallbacks: Array<(error?: Error) => void>;\r\n private reconnectedCallbacks: Array<(connectionId?: string) => void>;\r\n\r\n private receivedHandshakeResponse: boolean;\r\n private handshakeResolver!: (value?: PromiseLike<{}>) => void;\r\n private handshakeRejecter!: (reason?: any) => void;\r\n private stopDuringStartError?: Error;\r\n\r\n private connectionState: HubConnectionState;\r\n // connectionStarted is tracked independently from connectionState, so we can check if the\r\n // connection ever did successfully transition from connecting to connected before disconnecting.\r\n private connectionStarted: boolean;\r\n private startPromise?: Promise;\r\n private stopPromise?: Promise;\r\n private nextKeepAlive: number = 0;\r\n\r\n // The type of these a) doesn't matter and b) varies when building in browser and node contexts\r\n // Since we're building the WebPack bundle directly from the TypeScript, this matters (previously\r\n // we built the bundle from the compiled JavaScript).\r\n private reconnectDelayHandle?: any;\r\n private timeoutHandle?: any;\r\n private pingServerHandle?: any;\r\n\r\n /** The server timeout in milliseconds.\r\n *\r\n * If this timeout elapses without receiving any messages from the server, the connection will be terminated with an error.\r\n * The default timeout value is 30,000 milliseconds (30 seconds).\r\n */\r\n public serverTimeoutInMilliseconds: number;\r\n\r\n /** Default interval at which to ping the server.\r\n *\r\n * The default value is 15,000 milliseconds (15 seconds).\r\n * Allows the server to detect hard disconnects (like when a client unplugs their computer).\r\n * The ping will happen at most as often as the server pings.\r\n * If the server pings every 5 seconds, a value lower than 5 will ping every 5 seconds.\r\n */\r\n public keepAliveIntervalInMilliseconds: number;\r\n\r\n /** @internal */\r\n // Using a public static factory method means we can have a private constructor and an _internal_\r\n // create method that can be used by HubConnectionBuilder. An \"internal\" constructor would just\r\n // be stripped away and the '.d.ts' file would have no constructor, which is interpreted as a\r\n // public parameter-less constructor.\r\n public static create(connection: IConnection, logger: ILogger, protocol: IHubProtocol, reconnectPolicy?: IRetryPolicy): HubConnection {\r\n return new HubConnection(connection, logger, protocol, reconnectPolicy);\r\n }\r\n\r\n private constructor(connection: IConnection, logger: ILogger, protocol: IHubProtocol, reconnectPolicy?: IRetryPolicy) {\r\n Arg.isRequired(connection, \"connection\");\r\n Arg.isRequired(logger, \"logger\");\r\n Arg.isRequired(protocol, \"protocol\");\r\n\r\n this.serverTimeoutInMilliseconds = DEFAULT_TIMEOUT_IN_MS;\r\n this.keepAliveIntervalInMilliseconds = DEFAULT_PING_INTERVAL_IN_MS;\r\n\r\n this.logger = logger;\r\n this.protocol = protocol;\r\n this.connection = connection;\r\n this.reconnectPolicy = reconnectPolicy;\r\n this.handshakeProtocol = new HandshakeProtocol();\r\n\r\n this.connection.onreceive = (data: any) => this.processIncomingData(data);\r\n this.connection.onclose = (error?: Error) => this.connectionClosed(error);\r\n\r\n this.callbacks = {};\r\n this.methods = {};\r\n this.closedCallbacks = [];\r\n this.reconnectingCallbacks = [];\r\n this.reconnectedCallbacks = [];\r\n this.invocationId = 0;\r\n this.receivedHandshakeResponse = false;\r\n this.connectionState = HubConnectionState.Disconnected;\r\n this.connectionStarted = false;\r\n\r\n this.cachedPingMessage = this.protocol.writeMessage({ type: MessageType.Ping });\r\n }\r\n\r\n /** Indicates the state of the {@link HubConnection} to the server. */\r\n get state(): HubConnectionState {\r\n return this.connectionState;\r\n }\r\n\r\n /** Represents the connection id of the {@link HubConnection} on the server. The connection id will be null when the connection is either\r\n * in the disconnected state or if the negotiation step was skipped.\r\n */\r\n get connectionId(): string | null {\r\n return this.connection ? (this.connection.connectionId || null) : null;\r\n }\r\n\r\n /** Indicates the url of the {@link HubConnection} to the server. */\r\n get baseUrl(): string {\r\n return this.connection.baseUrl || \"\";\r\n }\r\n\r\n /**\r\n * Sets a new url for the HubConnection. Note that the url can only be changed when the connection is in either the Disconnected or\r\n * Reconnecting states.\r\n * @param {string} url The url to connect to.\r\n */\r\n set baseUrl(url: string) {\r\n if (this.connectionState !== HubConnectionState.Disconnected && this.connectionState !== HubConnectionState.Reconnecting) {\r\n throw new Error(\"The HubConnection must be in the Disconnected or Reconnecting state to change the url.\");\r\n }\r\n\r\n if (!url) {\r\n throw new Error(\"The HubConnection url must be a valid url.\");\r\n }\r\n\r\n this.connection.baseUrl = url;\r\n }\r\n\r\n /** Starts the connection.\r\n *\r\n * @returns {Promise} A Promise that resolves when the connection has been successfully established, or rejects with an error.\r\n */\r\n public start(): Promise {\r\n this.startPromise = this.startWithStateTransitions();\r\n return this.startPromise;\r\n }\r\n\r\n private async startWithStateTransitions(): Promise {\r\n if (this.connectionState !== HubConnectionState.Disconnected) {\r\n return Promise.reject(new Error(\"Cannot start a HubConnection that is not in the 'Disconnected' state.\"));\r\n }\r\n\r\n this.connectionState = HubConnectionState.Connecting;\r\n this.logger.log(LogLevel.Debug, \"Starting HubConnection.\");\r\n\r\n try {\r\n await this.startInternal();\r\n\r\n this.connectionState = HubConnectionState.Connected;\r\n this.connectionStarted = true;\r\n this.logger.log(LogLevel.Debug, \"HubConnection connected successfully.\");\r\n } catch (e) {\r\n this.connectionState = HubConnectionState.Disconnected;\r\n this.logger.log(LogLevel.Debug, `HubConnection failed to start successfully because of error '${e}'.`);\r\n return Promise.reject(e);\r\n }\r\n }\r\n\r\n private async startInternal() {\r\n this.stopDuringStartError = undefined;\r\n this.receivedHandshakeResponse = false;\r\n // Set up the promise before any connection is (re)started otherwise it could race with received messages\r\n const handshakePromise = new Promise((resolve, reject) => {\r\n this.handshakeResolver = resolve;\r\n this.handshakeRejecter = reject;\r\n });\r\n\r\n await this.connection.start(this.protocol.transferFormat);\r\n\r\n try {\r\n const handshakeRequest: HandshakeRequestMessage = {\r\n protocol: this.protocol.name,\r\n version: this.protocol.version,\r\n };\r\n\r\n this.logger.log(LogLevel.Debug, \"Sending handshake request.\");\r\n\r\n await this.sendMessage(this.handshakeProtocol.writeHandshakeRequest(handshakeRequest));\r\n\r\n this.logger.log(LogLevel.Information, `Using HubProtocol '${this.protocol.name}'.`);\r\n\r\n // defensively cleanup timeout in case we receive a message from the server before we finish start\r\n this.cleanupTimeout();\r\n this.resetTimeoutPeriod();\r\n this.resetKeepAliveInterval();\r\n\r\n await handshakePromise;\r\n\r\n // It's important to check the stopDuringStartError instead of just relying on the handshakePromise\r\n // being rejected on close, because this continuation can run after both the handshake completed successfully\r\n // and the connection was closed.\r\n if (this.stopDuringStartError) {\r\n // It's important to throw instead of returning a rejected promise, because we don't want to allow any state\r\n // transitions to occur between now and the calling code observing the exceptions. Returning a rejected promise\r\n // will cause the calling continuation to get scheduled to run later.\r\n throw this.stopDuringStartError;\r\n }\r\n } catch (e) {\r\n this.logger.log(LogLevel.Debug, `Hub handshake failed with error '${e}' during start(). Stopping HubConnection.`);\r\n\r\n this.cleanupTimeout();\r\n this.cleanupPingTimer();\r\n\r\n // HttpConnection.stop() should not complete until after the onclose callback is invoked.\r\n // This will transition the HubConnection to the disconnected state before HttpConnection.stop() completes.\r\n await this.connection.stop(e);\r\n throw e;\r\n }\r\n }\r\n\r\n /** Stops the connection.\r\n *\r\n * @returns {Promise} A Promise that resolves when the connection has been successfully terminated, or rejects with an error.\r\n */\r\n public async stop(): Promise {\r\n // Capture the start promise before the connection might be restarted in an onclose callback.\r\n const startPromise = this.startPromise;\r\n\r\n this.stopPromise = this.stopInternal();\r\n await this.stopPromise;\r\n\r\n try {\r\n // Awaiting undefined continues immediately\r\n await startPromise;\r\n } catch (e) {\r\n // This exception is returned to the user as a rejected Promise from the start method.\r\n }\r\n }\r\n\r\n private stopInternal(error?: Error): Promise {\r\n if (this.connectionState === HubConnectionState.Disconnected) {\r\n this.logger.log(LogLevel.Debug, `Call to HubConnection.stop(${error}) ignored because it is already in the disconnected state.`);\r\n return Promise.resolve();\r\n }\r\n\r\n if (this.connectionState === HubConnectionState.Disconnecting) {\r\n this.logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnecting state.`);\r\n return this.stopPromise!;\r\n }\r\n\r\n this.connectionState = HubConnectionState.Disconnecting;\r\n\r\n this.logger.log(LogLevel.Debug, \"Stopping HubConnection.\");\r\n\r\n if (this.reconnectDelayHandle) {\r\n // We're in a reconnect delay which means the underlying connection is currently already stopped.\r\n // Just clear the handle to stop the reconnect loop (which no one is waiting on thankfully) and\r\n // fire the onclose callbacks.\r\n this.logger.log(LogLevel.Debug, \"Connection stopped during reconnect delay. Done reconnecting.\");\r\n\r\n clearTimeout(this.reconnectDelayHandle);\r\n this.reconnectDelayHandle = undefined;\r\n\r\n this.completeClose();\r\n return Promise.resolve();\r\n }\r\n\r\n this.cleanupTimeout();\r\n this.cleanupPingTimer();\r\n this.stopDuringStartError = error || new Error(\"The connection was stopped before the hub handshake could complete.\");\r\n\r\n // HttpConnection.stop() should not complete until after either HttpConnection.start() fails\r\n // or the onclose callback is invoked. The onclose callback will transition the HubConnection\r\n // to the disconnected state if need be before HttpConnection.stop() completes.\r\n return this.connection.stop(error);\r\n }\r\n\r\n /** Invokes a streaming hub method on the server using the specified name and arguments.\r\n *\r\n * @typeparam T The type of the items returned by the server.\r\n * @param {string} methodName The name of the server method to invoke.\r\n * @param {any[]} args The arguments used to invoke the server method.\r\n * @returns {IStreamResult} An object that yields results from the server as they are received.\r\n */\r\n public stream(methodName: string, ...args: any[]): IStreamResult {\r\n const [streams, streamIds] = this.replaceStreamingParams(args);\r\n const invocationDescriptor = this.createStreamInvocation(methodName, args, streamIds);\r\n\r\n let promiseQueue: Promise;\r\n const subject = new Subject();\r\n subject.cancelCallback = () => {\r\n const cancelInvocation: CancelInvocationMessage = this.createCancelInvocation(invocationDescriptor.invocationId);\r\n\r\n delete this.callbacks[invocationDescriptor.invocationId];\r\n\r\n return promiseQueue.then(() => {\r\n return this.sendWithProtocol(cancelInvocation);\r\n });\r\n };\r\n\r\n this.callbacks[invocationDescriptor.invocationId] = (invocationEvent: CompletionMessage | StreamItemMessage | null, error?: Error) => {\r\n if (error) {\r\n subject.error(error);\r\n return;\r\n } else if (invocationEvent) {\r\n // invocationEvent will not be null when an error is not passed to the callback\r\n if (invocationEvent.type === MessageType.Completion) {\r\n if (invocationEvent.error) {\r\n subject.error(new Error(invocationEvent.error));\r\n } else {\r\n subject.complete();\r\n }\r\n } else {\r\n subject.next((invocationEvent.item) as T);\r\n }\r\n }\r\n };\r\n\r\n promiseQueue = this.sendWithProtocol(invocationDescriptor)\r\n .catch((e) => {\r\n subject.error(e);\r\n delete this.callbacks[invocationDescriptor.invocationId];\r\n });\r\n\r\n this.launchStreams(streams, promiseQueue);\r\n\r\n return subject;\r\n }\r\n\r\n private sendMessage(message: any) {\r\n this.resetKeepAliveInterval();\r\n return this.connection.send(message);\r\n }\r\n\r\n /**\r\n * Sends a js object to the server.\r\n * @param message The js object to serialize and send.\r\n */\r\n private sendWithProtocol(message: any) {\r\n return this.sendMessage(this.protocol.writeMessage(message));\r\n }\r\n\r\n /** Invokes a hub method on the server using the specified name and arguments. Does not wait for a response from the receiver.\r\n *\r\n * The Promise returned by this method resolves when the client has sent the invocation to the server. The server may still\r\n * be processing the invocation.\r\n *\r\n * @param {string} methodName The name of the server method to invoke.\r\n * @param {any[]} args The arguments used to invoke the server method.\r\n * @returns {Promise} A Promise that resolves when the invocation has been successfully sent, or rejects with an error.\r\n */\r\n public send(methodName: string, ...args: any[]): Promise {\r\n const [streams, streamIds] = this.replaceStreamingParams(args);\r\n const sendPromise = this.sendWithProtocol(this.createInvocation(methodName, args, true, streamIds));\r\n\r\n this.launchStreams(streams, sendPromise);\r\n\r\n return sendPromise;\r\n }\r\n\r\n /** Invokes a hub method on the server using the specified name and arguments.\r\n *\r\n * The Promise returned by this method resolves when the server indicates it has finished invoking the method. When the promise\r\n * resolves, the server has finished invoking the method. If the server method returns a result, it is produced as the result of\r\n * resolving the Promise.\r\n *\r\n * @typeparam T The expected return type.\r\n * @param {string} methodName The name of the server method to invoke.\r\n * @param {any[]} args The arguments used to invoke the server method.\r\n * @returns {Promise} A Promise that resolves with the result of the server method (if any), or rejects with an error.\r\n */\r\n public invoke(methodName: string, ...args: any[]): Promise {\r\n const [streams, streamIds] = this.replaceStreamingParams(args);\r\n const invocationDescriptor = this.createInvocation(methodName, args, false, streamIds);\r\n\r\n const p = new Promise((resolve, reject) => {\r\n // invocationId will always have a value for a non-blocking invocation\r\n this.callbacks[invocationDescriptor.invocationId!] = (invocationEvent: StreamItemMessage | CompletionMessage | null, error?: Error) => {\r\n if (error) {\r\n reject(error);\r\n return;\r\n } else if (invocationEvent) {\r\n // invocationEvent will not be null when an error is not passed to the callback\r\n if (invocationEvent.type === MessageType.Completion) {\r\n if (invocationEvent.error) {\r\n reject(new Error(invocationEvent.error));\r\n } else {\r\n resolve(invocationEvent.result);\r\n }\r\n } else {\r\n reject(new Error(`Unexpected message type: ${invocationEvent.type}`));\r\n }\r\n }\r\n };\r\n\r\n const promiseQueue = this.sendWithProtocol(invocationDescriptor)\r\n .catch((e) => {\r\n reject(e);\r\n // invocationId will always have a value for a non-blocking invocation\r\n delete this.callbacks[invocationDescriptor.invocationId!];\r\n });\r\n\r\n this.launchStreams(streams, promiseQueue);\r\n });\r\n\r\n return p;\r\n }\r\n\r\n /** Registers a handler that will be invoked when the hub method with the specified method name is invoked.\r\n *\r\n * @param {string} methodName The name of the hub method to define.\r\n * @param {Function} newMethod The handler that will be raised when the hub method is invoked.\r\n */\r\n public on(methodName: string, newMethod: (...args: any[]) => void) {\r\n if (!methodName || !newMethod) {\r\n return;\r\n }\r\n\r\n methodName = methodName.toLowerCase();\r\n if (!this.methods[methodName]) {\r\n this.methods[methodName] = [];\r\n }\r\n\r\n // Preventing adding the same handler multiple times.\r\n if (this.methods[methodName].indexOf(newMethod) !== -1) {\r\n return;\r\n }\r\n\r\n this.methods[methodName].push(newMethod);\r\n }\r\n\r\n /** Removes all handlers for the specified hub method.\r\n *\r\n * @param {string} methodName The name of the method to remove handlers for.\r\n */\r\n public off(methodName: string): void;\r\n\r\n /** Removes the specified handler for the specified hub method.\r\n *\r\n * You must pass the exact same Function instance as was previously passed to {@link @microsoft/signalr.HubConnection.on}. Passing a different instance (even if the function\r\n * body is the same) will not remove the handler.\r\n *\r\n * @param {string} methodName The name of the method to remove handlers for.\r\n * @param {Function} method The handler to remove. This must be the same Function instance as the one passed to {@link @microsoft/signalr.HubConnection.on}.\r\n */\r\n public off(methodName: string, method: (...args: any[]) => void): void;\r\n public off(methodName: string, method?: (...args: any[]) => void): void {\r\n if (!methodName) {\r\n return;\r\n }\r\n\r\n methodName = methodName.toLowerCase();\r\n const handlers = this.methods[methodName];\r\n if (!handlers) {\r\n return;\r\n }\r\n if (method) {\r\n const removeIdx = handlers.indexOf(method);\r\n if (removeIdx !== -1) {\r\n handlers.splice(removeIdx, 1);\r\n if (handlers.length === 0) {\r\n delete this.methods[methodName];\r\n }\r\n }\r\n } else {\r\n delete this.methods[methodName];\r\n }\r\n\r\n }\r\n\r\n /** Registers a handler that will be invoked when the connection is closed.\r\n *\r\n * @param {Function} callback The handler that will be invoked when the connection is closed. Optionally receives a single argument containing the error that caused the connection to close (if any).\r\n */\r\n public onclose(callback: (error?: Error) => void) {\r\n if (callback) {\r\n this.closedCallbacks.push(callback);\r\n }\r\n }\r\n\r\n /** Registers a handler that will be invoked when the connection starts reconnecting.\r\n *\r\n * @param {Function} callback The handler that will be invoked when the connection starts reconnecting. Optionally receives a single argument containing the error that caused the connection to start reconnecting (if any).\r\n */\r\n public onreconnecting(callback: (error?: Error) => void) {\r\n if (callback) {\r\n this.reconnectingCallbacks.push(callback);\r\n }\r\n }\r\n\r\n /** Registers a handler that will be invoked when the connection successfully reconnects.\r\n *\r\n * @param {Function} callback The handler that will be invoked when the connection successfully reconnects.\r\n */\r\n public onreconnected(callback: (connectionId?: string) => void) {\r\n if (callback) {\r\n this.reconnectedCallbacks.push(callback);\r\n }\r\n }\r\n\r\n private processIncomingData(data: any) {\r\n this.cleanupTimeout();\r\n\r\n if (!this.receivedHandshakeResponse) {\r\n data = this.processHandshakeResponse(data);\r\n this.receivedHandshakeResponse = true;\r\n }\r\n\r\n // Data may have all been read when processing handshake response\r\n if (data) {\r\n // Parse the messages\r\n const messages = this.protocol.parseMessages(data, this.logger);\r\n\r\n for (const message of messages) {\r\n switch (message.type) {\r\n case MessageType.Invocation:\r\n this.invokeClientMethod(message);\r\n break;\r\n case MessageType.StreamItem:\r\n case MessageType.Completion:\r\n const callback = this.callbacks[message.invocationId];\r\n if (callback) {\r\n if (message.type === MessageType.Completion) {\r\n delete this.callbacks[message.invocationId];\r\n }\r\n callback(message);\r\n }\r\n break;\r\n case MessageType.Ping:\r\n // Don't care about pings\r\n break;\r\n case MessageType.Close:\r\n this.logger.log(LogLevel.Information, \"Close message received from server.\");\r\n\r\n const error = message.error ? new Error(\"Server returned an error on close: \" + message.error) : undefined;\r\n\r\n if (message.allowReconnect === true) {\r\n // It feels wrong not to await connection.stop() here, but processIncomingData is called as part of an onreceive callback which is not async,\r\n // this is already the behavior for serverTimeout(), and HttpConnection.Stop() should catch and log all possible exceptions.\r\n\r\n // tslint:disable-next-line:no-floating-promises\r\n this.connection.stop(error);\r\n } else {\r\n // We cannot await stopInternal() here, but subsequent calls to stop() will await this if stopInternal() is still ongoing.\r\n this.stopPromise = this.stopInternal(error);\r\n }\r\n\r\n break;\r\n default:\r\n this.logger.log(LogLevel.Warning, `Invalid message type: ${message.type}.`);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n this.resetTimeoutPeriod();\r\n }\r\n\r\n private processHandshakeResponse(data: any): any {\r\n let responseMessage: HandshakeResponseMessage;\r\n let remainingData: any;\r\n\r\n try {\r\n [remainingData, responseMessage] = this.handshakeProtocol.parseHandshakeResponse(data);\r\n } catch (e) {\r\n const message = \"Error parsing handshake response: \" + e;\r\n this.logger.log(LogLevel.Error, message);\r\n\r\n const error = new Error(message);\r\n this.handshakeRejecter(error);\r\n throw error;\r\n }\r\n if (responseMessage.error) {\r\n const message = \"Server returned handshake error: \" + responseMessage.error;\r\n this.logger.log(LogLevel.Error, message);\r\n\r\n const error = new Error(message);\r\n this.handshakeRejecter(error);\r\n throw error;\r\n } else {\r\n this.logger.log(LogLevel.Debug, \"Server handshake complete.\");\r\n }\r\n\r\n this.handshakeResolver();\r\n return remainingData;\r\n }\r\n\r\n private resetKeepAliveInterval() {\r\n if (this.connection.features.inherentKeepAlive) {\r\n return;\r\n }\r\n\r\n // Set the time we want the next keep alive to be sent\r\n // Timer will be setup on next message receive\r\n this.nextKeepAlive = new Date().getTime() + this.keepAliveIntervalInMilliseconds;\r\n\r\n this.cleanupPingTimer();\r\n }\r\n\r\n private resetTimeoutPeriod() {\r\n if (!this.connection.features || !this.connection.features.inherentKeepAlive) {\r\n // Set the timeout timer\r\n this.timeoutHandle = setTimeout(() => this.serverTimeout(), this.serverTimeoutInMilliseconds);\r\n\r\n // Set keepAlive timer if there isn't one\r\n if (this.pingServerHandle === undefined) {\r\n let nextPing = this.nextKeepAlive - new Date().getTime();\r\n if (nextPing < 0) {\r\n nextPing = 0;\r\n }\r\n\r\n // The timer needs to be set from a networking callback to avoid Chrome timer throttling from causing timers to run once a minute\r\n this.pingServerHandle = setTimeout(async () => {\r\n if (this.connectionState === HubConnectionState.Connected) {\r\n try {\r\n await this.sendMessage(this.cachedPingMessage);\r\n } catch {\r\n // We don't care about the error. It should be seen elsewhere in the client.\r\n // The connection is probably in a bad or closed state now, cleanup the timer so it stops triggering\r\n this.cleanupPingTimer();\r\n }\r\n }\r\n }, nextPing);\r\n }\r\n }\r\n }\r\n\r\n private serverTimeout() {\r\n // The server hasn't talked to us in a while. It doesn't like us anymore ... :(\r\n // Terminate the connection, but we don't need to wait on the promise. This could trigger reconnecting.\r\n // tslint:disable-next-line:no-floating-promises\r\n this.connection.stop(new Error(\"Server timeout elapsed without receiving a message from the server.\"));\r\n }\r\n\r\n private invokeClientMethod(invocationMessage: InvocationMessage) {\r\n const methods = this.methods[invocationMessage.target.toLowerCase()];\r\n if (methods) {\r\n try {\r\n methods.forEach((m) => m.apply(this, invocationMessage.arguments));\r\n } catch (e) {\r\n this.logger.log(LogLevel.Error, `A callback for the method ${invocationMessage.target.toLowerCase()} threw error '${e}'.`);\r\n }\r\n\r\n if (invocationMessage.invocationId) {\r\n // This is not supported in v1. So we return an error to avoid blocking the server waiting for the response.\r\n const message = \"Server requested a response, which is not supported in this version of the client.\";\r\n this.logger.log(LogLevel.Error, message);\r\n\r\n // We don't want to wait on the stop itself.\r\n this.stopPromise = this.stopInternal(new Error(message));\r\n }\r\n } else {\r\n this.logger.log(LogLevel.Warning, `No client method with the name '${invocationMessage.target}' found.`);\r\n }\r\n }\r\n\r\n private connectionClosed(error?: Error) {\r\n this.logger.log(LogLevel.Debug, `HubConnection.connectionClosed(${error}) called while in state ${this.connectionState}.`);\r\n\r\n // Triggering this.handshakeRejecter is insufficient because it could already be resolved without the continuation having run yet.\r\n this.stopDuringStartError = this.stopDuringStartError || error || new Error(\"The underlying connection was closed before the hub handshake could complete.\");\r\n\r\n // If the handshake is in progress, start will be waiting for the handshake promise, so we complete it.\r\n // If it has already completed, this should just noop.\r\n if (this.handshakeResolver) {\r\n this.handshakeResolver();\r\n }\r\n\r\n this.cancelCallbacksWithError(error || new Error(\"Invocation canceled due to the underlying connection being closed.\"));\r\n\r\n this.cleanupTimeout();\r\n this.cleanupPingTimer();\r\n\r\n if (this.connectionState === HubConnectionState.Disconnecting) {\r\n this.completeClose(error);\r\n } else if (this.connectionState === HubConnectionState.Connected && this.reconnectPolicy) {\r\n // tslint:disable-next-line:no-floating-promises\r\n this.reconnect(error);\r\n } else if (this.connectionState === HubConnectionState.Connected) {\r\n this.completeClose(error);\r\n }\r\n\r\n // If none of the above if conditions were true were called the HubConnection must be in either:\r\n // 1. The Connecting state in which case the handshakeResolver will complete it and stopDuringStartError will fail it.\r\n // 2. The Reconnecting state in which case the handshakeResolver will complete it and stopDuringStartError will fail the current reconnect attempt\r\n // and potentially continue the reconnect() loop.\r\n // 3. The Disconnected state in which case we're already done.\r\n }\r\n\r\n private completeClose(error?: Error) {\r\n if (this.connectionStarted) {\r\n this.connectionState = HubConnectionState.Disconnected;\r\n this.connectionStarted = false;\r\n\r\n try {\r\n this.closedCallbacks.forEach((c) => c.apply(this, [error]));\r\n } catch (e) {\r\n this.logger.log(LogLevel.Error, `An onclose callback called with error '${error}' threw error '${e}'.`);\r\n }\r\n }\r\n }\r\n\r\n private async reconnect(error?: Error) {\r\n const reconnectStartTime = Date.now();\r\n let previousReconnectAttempts = 0;\r\n let retryError = error !== undefined ? error : new Error(\"Attempting to reconnect due to a unknown error.\");\r\n\r\n let nextRetryDelay = this.getNextRetryDelay(previousReconnectAttempts++, 0, retryError);\r\n\r\n if (nextRetryDelay === null) {\r\n this.logger.log(LogLevel.Debug, \"Connection not reconnecting because the IRetryPolicy returned null on the first reconnect attempt.\");\r\n this.completeClose(error);\r\n return;\r\n }\r\n\r\n this.connectionState = HubConnectionState.Reconnecting;\r\n\r\n if (error) {\r\n this.logger.log(LogLevel.Information, `Connection reconnecting because of error '${error}'.`);\r\n } else {\r\n this.logger.log(LogLevel.Information, \"Connection reconnecting.\");\r\n }\r\n\r\n if (this.onreconnecting) {\r\n try {\r\n this.reconnectingCallbacks.forEach((c) => c.apply(this, [error]));\r\n } catch (e) {\r\n this.logger.log(LogLevel.Error, `An onreconnecting callback called with error '${error}' threw error '${e}'.`);\r\n }\r\n\r\n // Exit early if an onreconnecting callback called connection.stop().\r\n if (this.connectionState !== HubConnectionState.Reconnecting) {\r\n this.logger.log(LogLevel.Debug, \"Connection left the reconnecting state in onreconnecting callback. Done reconnecting.\");\r\n return;\r\n }\r\n }\r\n\r\n while (nextRetryDelay !== null) {\r\n this.logger.log(LogLevel.Information, `Reconnect attempt number ${previousReconnectAttempts} will start in ${nextRetryDelay} ms.`);\r\n\r\n await new Promise((resolve) => {\r\n this.reconnectDelayHandle = setTimeout(resolve, nextRetryDelay!);\r\n });\r\n this.reconnectDelayHandle = undefined;\r\n\r\n if (this.connectionState !== HubConnectionState.Reconnecting) {\r\n this.logger.log(LogLevel.Debug, \"Connection left the reconnecting state during reconnect delay. Done reconnecting.\");\r\n return;\r\n }\r\n\r\n try {\r\n await this.startInternal();\r\n\r\n this.connectionState = HubConnectionState.Connected;\r\n this.logger.log(LogLevel.Information, \"HubConnection reconnected successfully.\");\r\n\r\n if (this.onreconnected) {\r\n try {\r\n this.reconnectedCallbacks.forEach((c) => c.apply(this, [this.connection.connectionId]));\r\n } catch (e) {\r\n this.logger.log(LogLevel.Error, `An onreconnected callback called with connectionId '${this.connection.connectionId}; threw error '${e}'.`);\r\n }\r\n }\r\n\r\n return;\r\n } catch (e) {\r\n this.logger.log(LogLevel.Information, `Reconnect attempt failed because of error '${e}'.`);\r\n\r\n if (this.connectionState !== HubConnectionState.Reconnecting) {\r\n this.logger.log(LogLevel.Debug, `Connection moved to the '${this.connectionState}' from the reconnecting state during reconnect attempt. Done reconnecting.`);\r\n // The TypeScript compiler thinks that connectionState must be Connected here. The TypeScript compiler is wrong.\r\n if (this.connectionState as any === HubConnectionState.Disconnecting) {\r\n this.completeClose();\r\n }\r\n return;\r\n }\r\n\r\n retryError = e instanceof Error ? e : new Error(e.toString());\r\n nextRetryDelay = this.getNextRetryDelay(previousReconnectAttempts++, Date.now() - reconnectStartTime, retryError);\r\n }\r\n }\r\n\r\n this.logger.log(LogLevel.Information, `Reconnect retries have been exhausted after ${Date.now() - reconnectStartTime} ms and ${previousReconnectAttempts} failed attempts. Connection disconnecting.`);\r\n\r\n this.completeClose();\r\n }\r\n\r\n private getNextRetryDelay(previousRetryCount: number, elapsedMilliseconds: number, retryReason: Error) {\r\n try {\r\n return this.reconnectPolicy!.nextRetryDelayInMilliseconds({\r\n elapsedMilliseconds,\r\n previousRetryCount,\r\n retryReason,\r\n });\r\n } catch (e) {\r\n this.logger.log(LogLevel.Error, `IRetryPolicy.nextRetryDelayInMilliseconds(${previousRetryCount}, ${elapsedMilliseconds}) threw error '${e}'.`);\r\n return null;\r\n }\r\n }\r\n\r\n private cancelCallbacksWithError(error: Error) {\r\n const callbacks = this.callbacks;\r\n this.callbacks = {};\r\n\r\n Object.keys(callbacks)\r\n .forEach((key) => {\r\n const callback = callbacks[key];\r\n callback(null, error);\r\n });\r\n }\r\n\r\n private cleanupPingTimer(): void {\r\n if (this.pingServerHandle) {\r\n clearTimeout(this.pingServerHandle);\r\n this.pingServerHandle = undefined;\r\n }\r\n }\r\n\r\n private cleanupTimeout(): void {\r\n if (this.timeoutHandle) {\r\n clearTimeout(this.timeoutHandle);\r\n }\r\n }\r\n\r\n private createInvocation(methodName: string, args: any[], nonblocking: boolean, streamIds: string[]): InvocationMessage {\r\n if (nonblocking) {\r\n return {\r\n arguments: args,\r\n streamIds,\r\n target: methodName,\r\n type: MessageType.Invocation,\r\n };\r\n } else {\r\n const invocationId = this.invocationId;\r\n this.invocationId++;\r\n\r\n return {\r\n arguments: args,\r\n invocationId: invocationId.toString(),\r\n streamIds,\r\n target: methodName,\r\n type: MessageType.Invocation,\r\n };\r\n }\r\n }\r\n\r\n private launchStreams(streams: Array>, promiseQueue: Promise): void {\r\n if (streams.length === 0) {\r\n return;\r\n }\r\n\r\n // Synchronize stream data so they arrive in-order on the server\r\n if (!promiseQueue) {\r\n promiseQueue = Promise.resolve();\r\n }\r\n\r\n // We want to iterate over the keys, since the keys are the stream ids\r\n // tslint:disable-next-line:forin\r\n for (const streamId in streams) {\r\n streams[streamId].subscribe({\r\n complete: () => {\r\n promiseQueue = promiseQueue.then(() => this.sendWithProtocol(this.createCompletionMessage(streamId)));\r\n },\r\n error: (err) => {\r\n let message: string;\r\n if (err instanceof Error) {\r\n message = err.message;\r\n } else if (err && err.toString) {\r\n message = err.toString();\r\n } else {\r\n message = \"Unknown error\";\r\n }\r\n\r\n promiseQueue = promiseQueue.then(() => this.sendWithProtocol(this.createCompletionMessage(streamId, message)));\r\n },\r\n next: (item) => {\r\n promiseQueue = promiseQueue.then(() => this.sendWithProtocol(this.createStreamItemMessage(streamId, item)));\r\n },\r\n });\r\n }\r\n }\r\n\r\n private replaceStreamingParams(args: any[]): [Array>, string[]] {\r\n const streams: Array> = [];\r\n const streamIds: string[] = [];\r\n for (let i = 0; i < args.length; i++) {\r\n const argument = args[i];\r\n if (this.isObservable(argument)) {\r\n const streamId = this.invocationId;\r\n this.invocationId++;\r\n // Store the stream for later use\r\n streams[streamId] = argument;\r\n streamIds.push(streamId.toString());\r\n\r\n // remove stream from args\r\n args.splice(i, 1);\r\n }\r\n }\r\n\r\n return [streams, streamIds];\r\n }\r\n\r\n private isObservable(arg: any): arg is IStreamResult {\r\n // This allows other stream implementations to just work (like rxjs)\r\n return arg && arg.subscribe && typeof arg.subscribe === \"function\";\r\n }\r\n\r\n private createStreamInvocation(methodName: string, args: any[], streamIds: string[]): StreamInvocationMessage {\r\n const invocationId = this.invocationId;\r\n this.invocationId++;\r\n\r\n return {\r\n arguments: args,\r\n invocationId: invocationId.toString(),\r\n streamIds,\r\n target: methodName,\r\n type: MessageType.StreamInvocation,\r\n };\r\n }\r\n\r\n private createCancelInvocation(id: string): CancelInvocationMessage {\r\n return {\r\n invocationId: id,\r\n type: MessageType.CancelInvocation,\r\n };\r\n }\r\n\r\n private createStreamItemMessage(id: string, item: any): StreamItemMessage {\r\n return {\r\n invocationId: id,\r\n item,\r\n type: MessageType.StreamItem,\r\n };\r\n }\r\n\r\n private createCompletionMessage(id: string, error?: any, result?: any): CompletionMessage {\r\n if (error) {\r\n return {\r\n error,\r\n invocationId: id,\r\n type: MessageType.Completion,\r\n };\r\n }\r\n\r\n return {\r\n invocationId: id,\r\n result,\r\n type: MessageType.Completion,\r\n };\r\n }\r\n}\r\n","// 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 { IStreamResult, IStreamSubscriber, ISubscription } from \"./Stream\";\r\nimport { SubjectSubscription } from \"./Utils\";\r\n\r\n/** Stream implementation to stream items to the server. */\r\nexport class Subject implements IStreamResult {\r\n /** @internal */\r\n public observers: Array>;\r\n\r\n /** @internal */\r\n public cancelCallback?: () => Promise;\r\n\r\n constructor() {\r\n this.observers = [];\r\n }\r\n\r\n public next(item: T): void {\r\n for (const observer of this.observers) {\r\n observer.next(item);\r\n }\r\n }\r\n\r\n public error(err: any): void {\r\n for (const observer of this.observers) {\r\n if (observer.error) {\r\n observer.error(err);\r\n }\r\n }\r\n }\r\n\r\n public complete(): void {\r\n for (const observer of this.observers) {\r\n if (observer.complete) {\r\n observer.complete();\r\n }\r\n }\r\n }\r\n\r\n public subscribe(observer: IStreamSubscriber): ISubscription {\r\n this.observers.push(observer);\r\n return new SubjectSubscription(this, observer);\r\n }\r\n}\r\n","// 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\n// This will be treated as a bit flag in the future, so we keep it using power-of-two values.\r\n/** Specifies a specific HTTP transport type. */\r\nexport enum HttpTransportType {\r\n /** Specifies no transport preference. */\r\n None = 0,\r\n /** Specifies the WebSockets transport. */\r\n WebSockets = 1,\r\n /** Specifies the Server-Sent Events transport. */\r\n ServerSentEvents = 2,\r\n /** Specifies the Long Polling transport. */\r\n LongPolling = 4,\r\n}\r\n\r\n/** Specifies the transfer format for a connection. */\r\nexport enum TransferFormat {\r\n /** Specifies that only text data will be transmitted over the connection. */\r\n Text = 1,\r\n /** Specifies that binary data will be transmitted over the connection. */\r\n Binary = 2,\r\n}\r\n\r\n/** An abstraction over the behavior of transports. This is designed to support the framework and not intended for use by applications. */\r\nexport interface ITransport {\r\n connect(url: string, transferFormat: TransferFormat): Promise;\r\n send(data: any): Promise;\r\n stop(): Promise;\r\n onreceive: ((data: string | ArrayBuffer) => void) | null;\r\n onclose: ((error?: Error) => void) | null;\r\n}\r\n","// 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 { IRetryPolicy, RetryContext } from \"./IRetryPolicy\";\r\n\r\n// 0, 2, 10, 30 second delays before reconnect attempts.\r\nconst DEFAULT_RETRY_DELAYS_IN_MILLISECONDS = [0, 2000, 10000, 30000, null];\r\n\r\n/** @private */\r\nexport class DefaultReconnectPolicy implements IRetryPolicy {\r\n private readonly retryDelays: Array;\r\n\r\n constructor(retryDelays?: number[]) {\r\n this.retryDelays = retryDelays !== undefined ? [...retryDelays, null] : DEFAULT_RETRY_DELAYS_IN_MILLISECONDS;\r\n }\r\n\r\n public nextRetryDelayInMilliseconds(retryContext: RetryContext): number | null {\r\n return this.retryDelays[retryContext.previousRetryCount];\r\n }\r\n}\r\n","// 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\n// Rough polyfill of https://developer.mozilla.org/en-US/docs/Web/API/AbortController\r\n// We don't actually ever use the API being polyfilled, we always use the polyfill because\r\n// it's a very new API right now.\r\n\r\n// Not exported from index.\r\n/** @private */\r\nexport class AbortController implements AbortSignal {\r\n private isAborted: boolean = false;\r\n public onabort: (() => void) | null = null;\r\n\r\n public abort() {\r\n if (!this.isAborted) {\r\n this.isAborted = true;\r\n if (this.onabort) {\r\n this.onabort();\r\n }\r\n }\r\n }\r\n\r\n get signal(): AbortSignal {\r\n return this;\r\n }\r\n\r\n get aborted(): boolean {\r\n return this.isAborted;\r\n }\r\n}\r\n\r\n/** Represents a signal that can be monitored to determine if a request has been aborted. */\r\nexport interface AbortSignal {\r\n /** Indicates if the request has been aborted. */\r\n aborted: boolean;\r\n /** Set this to a handler that will be invoked when the request is aborted. */\r\n onabort: (() => void) | null;\r\n}\r\n","// 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 { AbortController } from \"./AbortController\";\r\nimport { HttpError, TimeoutError } from \"./Errors\";\r\nimport { HttpClient, HttpRequest } from \"./HttpClient\";\r\nimport { ILogger, LogLevel } from \"./ILogger\";\r\nimport { ITransport, TransferFormat } from \"./ITransport\";\r\nimport { Arg, getDataDetail, sendMessage } from \"./Utils\";\r\n\r\n// Not exported from 'index', this type is internal.\r\n/** @private */\r\nexport class LongPollingTransport 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 pollAbort: AbortController;\r\n\r\n private url?: string;\r\n private running: boolean;\r\n private receiving?: Promise;\r\n private closeError?: Error;\r\n\r\n public onreceive: ((data: string | ArrayBuffer) => void) | null;\r\n public onclose: ((error?: Error) => void) | null;\r\n\r\n // This is an internal type, not exported from 'index' so this is really just internal.\r\n public get pollAborted() {\r\n return this.pollAbort.aborted;\r\n }\r\n\r\n constructor(httpClient: HttpClient, accessTokenFactory: (() => string | Promise) | undefined, logger: ILogger, logMessageContent: boolean) {\r\n this.httpClient = httpClient;\r\n this.accessTokenFactory = accessTokenFactory;\r\n this.logger = logger;\r\n this.pollAbort = new AbortController();\r\n this.logMessageContent = logMessageContent;\r\n\r\n this.running = false;\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.url = url;\r\n\r\n this.logger.log(LogLevel.Trace, \"(LongPolling transport) Connecting.\");\r\n\r\n // Allow binary format on Node and Browsers that support binary content (indicated by the presence of responseType property)\r\n if (transferFormat === TransferFormat.Binary &&\r\n (typeof XMLHttpRequest !== \"undefined\" && typeof new XMLHttpRequest().responseType !== \"string\")) {\r\n throw new Error(\"Binary protocols over XmlHttpRequest not implementing advanced features are not supported.\");\r\n }\r\n\r\n const pollOptions: HttpRequest = {\r\n abortSignal: this.pollAbort.signal,\r\n headers: {},\r\n timeout: 100000,\r\n };\r\n\r\n if (transferFormat === TransferFormat.Binary) {\r\n pollOptions.responseType = \"arraybuffer\";\r\n }\r\n\r\n const token = await this.getAccessToken();\r\n this.updateHeaderToken(pollOptions, token);\r\n\r\n // Make initial long polling request\r\n // Server uses first long polling request to finish initializing connection and it returns without data\r\n const pollUrl = `${url}&_=${Date.now()}`;\r\n this.logger.log(LogLevel.Trace, `(LongPolling transport) polling: ${pollUrl}.`);\r\n const response = await this.httpClient.get(pollUrl, pollOptions);\r\n if (response.statusCode !== 200) {\r\n this.logger.log(LogLevel.Error, `(LongPolling transport) Unexpected response code: ${response.statusCode}.`);\r\n\r\n // Mark running as false so that the poll immediately ends and runs the close logic\r\n this.closeError = new HttpError(response.statusText || \"\", response.statusCode);\r\n this.running = false;\r\n } else {\r\n this.running = true;\r\n }\r\n\r\n this.receiving = this.poll(this.url, pollOptions);\r\n }\r\n\r\n private async getAccessToken(): Promise {\r\n if (this.accessTokenFactory) {\r\n return await this.accessTokenFactory();\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private updateHeaderToken(request: HttpRequest, token: string | null) {\r\n if (!request.headers) {\r\n request.headers = {};\r\n }\r\n if (token) {\r\n // tslint:disable-next-line:no-string-literal\r\n request.headers[\"Authorization\"] = `Bearer ${token}`;\r\n return;\r\n }\r\n // tslint:disable-next-line:no-string-literal\r\n if (request.headers[\"Authorization\"]) {\r\n // tslint:disable-next-line:no-string-literal\r\n delete request.headers[\"Authorization\"];\r\n }\r\n }\r\n\r\n private async poll(url: string, pollOptions: HttpRequest): Promise {\r\n try {\r\n while (this.running) {\r\n // We have to get the access token on each poll, in case it changes\r\n const token = await this.getAccessToken();\r\n this.updateHeaderToken(pollOptions, token);\r\n\r\n try {\r\n const pollUrl = `${url}&_=${Date.now()}`;\r\n this.logger.log(LogLevel.Trace, `(LongPolling transport) polling: ${pollUrl}.`);\r\n const response = await this.httpClient.get(pollUrl, pollOptions);\r\n\r\n if (response.statusCode === 204) {\r\n this.logger.log(LogLevel.Information, \"(LongPolling transport) Poll terminated by server.\");\r\n\r\n this.running = false;\r\n } else if (response.statusCode !== 200) {\r\n this.logger.log(LogLevel.Error, `(LongPolling transport) Unexpected response code: ${response.statusCode}.`);\r\n\r\n // Unexpected status code\r\n this.closeError = new HttpError(response.statusText || \"\", response.statusCode);\r\n this.running = false;\r\n } else {\r\n // Process the response\r\n if (response.content) {\r\n this.logger.log(LogLevel.Trace, `(LongPolling transport) data received. ${getDataDetail(response.content, this.logMessageContent)}.`);\r\n if (this.onreceive) {\r\n this.onreceive(response.content);\r\n }\r\n } else {\r\n // This is another way timeout manifest.\r\n this.logger.log(LogLevel.Trace, \"(LongPolling transport) Poll timed out, reissuing.\");\r\n }\r\n }\r\n } catch (e) {\r\n if (!this.running) {\r\n // Log but disregard errors that occur after stopping\r\n this.logger.log(LogLevel.Trace, `(LongPolling transport) Poll errored after shutdown: ${e.message}`);\r\n } else {\r\n if (e instanceof TimeoutError) {\r\n // Ignore timeouts and reissue the poll.\r\n this.logger.log(LogLevel.Trace, \"(LongPolling transport) Poll timed out, reissuing.\");\r\n } else {\r\n // Close the connection with the error as the result.\r\n this.closeError = e;\r\n this.running = false;\r\n }\r\n }\r\n }\r\n }\r\n } finally {\r\n this.logger.log(LogLevel.Trace, \"(LongPolling transport) Polling complete.\");\r\n\r\n // We will reach here with pollAborted==false when the server returned a response causing the transport to stop.\r\n // If pollAborted==true then client initiated the stop and the stop method will raise the close event after DELETE is sent.\r\n if (!this.pollAborted) {\r\n this.raiseOnClose();\r\n }\r\n }\r\n }\r\n\r\n public async send(data: any): Promise {\r\n if (!this.running) {\r\n return Promise.reject(new Error(\"Cannot send until the transport is connected\"));\r\n }\r\n return sendMessage(this.logger, \"LongPolling\", this.httpClient, this.url!, this.accessTokenFactory, data, this.logMessageContent);\r\n }\r\n\r\n public async stop(): Promise {\r\n this.logger.log(LogLevel.Trace, \"(LongPolling transport) Stopping polling.\");\r\n\r\n // Tell receiving loop to stop, abort any current request, and then wait for it to finish\r\n this.running = false;\r\n this.pollAbort.abort();\r\n\r\n try {\r\n await this.receiving;\r\n\r\n // Send DELETE to clean up long polling on the server\r\n this.logger.log(LogLevel.Trace, `(LongPolling transport) sending DELETE request to ${this.url}.`);\r\n\r\n const deleteOptions: HttpRequest = {\r\n headers: {},\r\n };\r\n const token = await this.getAccessToken();\r\n this.updateHeaderToken(deleteOptions, token);\r\n await this.httpClient.delete(this.url!, deleteOptions);\r\n\r\n this.logger.log(LogLevel.Trace, \"(LongPolling transport) DELETE request sent.\");\r\n } finally {\r\n this.logger.log(LogLevel.Trace, \"(LongPolling transport) Stop finished.\");\r\n\r\n // Raise close event here instead of in polling\r\n // It needs to happen after the DELETE request is sent\r\n this.raiseOnClose();\r\n }\r\n }\r\n\r\n private raiseOnClose() {\r\n if (this.onclose) {\r\n let logMessage = \"(LongPolling transport) Firing onclose event.\";\r\n if (this.closeError) {\r\n logMessage += \" Error: \" + this.closeError;\r\n }\r\n this.logger.log(LogLevel.Trace, logMessage);\r\n this.onclose(this.closeError);\r\n }\r\n }\r\n}\r\n","// 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 { ILogger, LogLevel } from \"./ILogger\";\r\nimport { ITransport, TransferFormat } from \"./ITransport\";\r\nimport { EventSourceConstructor } from \"./Polyfills\";\r\nimport { Arg, getDataDetail, 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 eventSourceConstructor: EventSourceConstructor;\r\n private eventSource?: EventSource;\r\n private url?: string;\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) {\r\n this.httpClient = httpClient;\r\n this.accessTokenFactory = accessTokenFactory;\r\n this.logger = logger;\r\n this.logMessageContent = logMessageContent;\r\n this.eventSourceConstructor = eventSourceConstructor;\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: true });\r\n } else {\r\n // Non-browser passes cookies via the dictionary\r\n const cookies = this.httpClient.getCookieString(url);\r\n eventSource = new this.eventSourceConstructor(url, { withCredentials: true, headers: { Cookie: cookies } } 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);\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","// 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 { ILogger, LogLevel } from \"./ILogger\";\r\nimport { ITransport, TransferFormat } from \"./ITransport\";\r\nimport { WebSocketConstructor } from \"./Polyfills\";\r\nimport { Arg, getDataDetail, Platform } from \"./Utils\";\r\n\r\n/** @private */\r\nexport class WebSocketTransport implements ITransport {\r\n private readonly logger: ILogger;\r\n private readonly accessTokenFactory: (() => string | Promise) | undefined;\r\n private readonly logMessageContent: boolean;\r\n private readonly webSocketConstructor: WebSocketConstructor;\r\n private readonly httpClient: HttpClient;\r\n private webSocket?: WebSocket;\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, webSocketConstructor: WebSocketConstructor) {\r\n this.logger = logger;\r\n this.accessTokenFactory = accessTokenFactory;\r\n this.logMessageContent = logMessageContent;\r\n this.webSocketConstructor = webSocketConstructor;\r\n this.httpClient = httpClient;\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 this.logger.log(LogLevel.Trace, \"(WebSockets transport) Connecting.\");\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 url = url.replace(/^http/, \"ws\");\r\n let webSocket: WebSocket | undefined;\r\n const cookies = this.httpClient.getCookieString(url);\r\n let opened = false;\r\n\r\n if (Platform.isNode && cookies) {\r\n // Only pass cookies when in non-browser environments\r\n webSocket = new this.webSocketConstructor(url, undefined, {\r\n headers: {\r\n Cookie: `${cookies}`,\r\n },\r\n });\r\n }\r\n\r\n if (!webSocket) {\r\n // Chrome is not happy with passing 'undefined' as protocol\r\n webSocket = new this.webSocketConstructor(url);\r\n }\r\n\r\n if (transferFormat === TransferFormat.Binary) {\r\n webSocket.binaryType = \"arraybuffer\";\r\n }\r\n\r\n // tslint:disable-next-line:variable-name\r\n webSocket.onopen = (_event: Event) => {\r\n this.logger.log(LogLevel.Information, `WebSocket connected to ${url}.`);\r\n this.webSocket = webSocket;\r\n opened = true;\r\n resolve();\r\n };\r\n\r\n webSocket.onerror = (event: Event) => {\r\n let error: any = null;\r\n // ErrorEvent is a browser only type we need to check if the type exists before using it\r\n if (typeof ErrorEvent !== \"undefined\" && event instanceof ErrorEvent) {\r\n error = event.error;\r\n } else {\r\n error = new Error(\"There was an error with the transport.\");\r\n }\r\n\r\n reject(error);\r\n };\r\n\r\n webSocket.onmessage = (message: MessageEvent) => {\r\n this.logger.log(LogLevel.Trace, `(WebSockets transport) data received. ${getDataDetail(message.data, this.logMessageContent)}.`);\r\n if (this.onreceive) {\r\n this.onreceive(message.data);\r\n }\r\n };\r\n\r\n webSocket.onclose = (event: CloseEvent) => {\r\n // Don't call close handler if connection was never established\r\n // We'll reject the connect call instead\r\n if (opened) {\r\n this.close(event);\r\n } else {\r\n let error: any = null;\r\n // ErrorEvent is a browser only type we need to check if the type exists before using it\r\n if (typeof ErrorEvent !== \"undefined\" && event instanceof ErrorEvent) {\r\n error = event.error;\r\n } else {\r\n error = new Error(\"There was an error with the transport.\");\r\n }\r\n\r\n reject(error);\r\n }\r\n };\r\n });\r\n }\r\n\r\n public send(data: any): Promise {\r\n if (this.webSocket && this.webSocket.readyState === this.webSocketConstructor.OPEN) {\r\n this.logger.log(LogLevel.Trace, `(WebSockets transport) sending data. ${getDataDetail(data, this.logMessageContent)}.`);\r\n this.webSocket.send(data);\r\n return Promise.resolve();\r\n }\r\n\r\n return Promise.reject(\"WebSocket is not in the OPEN state\");\r\n }\r\n\r\n public stop(): Promise {\r\n if (this.webSocket) {\r\n // Manually invoke onclose callback inline so we know the HttpConnection was closed properly before returning\r\n // This also solves an issue where websocket.onclose could take 18+ seconds to trigger during network disconnects\r\n this.close(undefined);\r\n }\r\n\r\n return Promise.resolve();\r\n }\r\n\r\n private close(event?: CloseEvent): void {\r\n // webSocket will be null if the transport did not start successfully\r\n if (this.webSocket) {\r\n // Clear websocket handlers because we are considering the socket closed now\r\n this.webSocket.onclose = () => {};\r\n this.webSocket.onmessage = () => {};\r\n this.webSocket.onerror = () => {};\r\n this.webSocket.close();\r\n this.webSocket = undefined;\r\n }\r\n\r\n this.logger.log(LogLevel.Trace, \"(WebSockets transport) socket closed.\");\r\n if (this.onclose) {\r\n if (event && (event.wasClean === false || event.code !== 1000)) {\r\n this.onclose(new Error(`WebSocket closed with status code: ${event.code} (${event.reason}).`));\r\n } else {\r\n this.onclose();\r\n }\r\n }\r\n }\r\n}\r\n","// 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 { DefaultHttpClient } from \"./DefaultHttpClient\";\r\nimport { HttpClient } from \"./HttpClient\";\r\nimport { IConnection } from \"./IConnection\";\r\nimport { IHttpConnectionOptions } from \"./IHttpConnectionOptions\";\r\nimport { ILogger, LogLevel } from \"./ILogger\";\r\nimport { HttpTransportType, ITransport, TransferFormat } from \"./ITransport\";\r\nimport { LongPollingTransport } from \"./LongPollingTransport\";\r\nimport { ServerSentEventsTransport } from \"./ServerSentEventsTransport\";\r\nimport { Arg, createLogger, Platform } from \"./Utils\";\r\nimport { WebSocketTransport } from \"./WebSocketTransport\";\r\n\r\n/** @private */\r\nconst enum ConnectionState {\r\n Connecting = \"Connecting \",\r\n Connected = \"Connected\",\r\n Disconnected = \"Disconnected\",\r\n Disconnecting = \"Disconnecting\",\r\n}\r\n\r\n/** @private */\r\nexport interface INegotiateResponse {\r\n connectionId?: string;\r\n connectionToken?: string;\r\n negotiateVersion?: number;\r\n availableTransports?: IAvailableTransport[];\r\n url?: string;\r\n accessToken?: string;\r\n error?: string;\r\n}\r\n\r\n/** @private */\r\nexport interface IAvailableTransport {\r\n transport: keyof typeof HttpTransportType;\r\n transferFormats: Array;\r\n}\r\n\r\nconst MAX_REDIRECTS = 100;\r\n\r\nlet WebSocketModule: any = null;\r\nlet EventSourceModule: any = null;\r\nif (Platform.isNode && typeof require !== \"undefined\") {\r\n // In order to ignore the dynamic require in webpack builds we need to do this magic\r\n // @ts-ignore: TS doesn't know about these names\r\n const requireFunc = typeof __webpack_require__ === \"function\" ? __non_webpack_require__ : require;\r\n WebSocketModule = requireFunc(\"ws\");\r\n EventSourceModule = requireFunc(\"eventsource\");\r\n}\r\n\r\n/** @private */\r\nexport class HttpConnection implements IConnection {\r\n private connectionState: ConnectionState;\r\n // connectionStarted is tracked independently from connectionState, so we can check if the\r\n // connection ever did successfully transition from connecting to connected before disconnecting.\r\n private connectionStarted: boolean;\r\n private readonly httpClient: HttpClient;\r\n private readonly logger: ILogger;\r\n private readonly options: IHttpConnectionOptions;\r\n private transport?: ITransport;\r\n private startInternalPromise?: Promise;\r\n private stopPromise?: Promise;\r\n private stopPromiseResolver: (value?: PromiseLike) => void = () => {};\r\n private stopError?: Error;\r\n private accessTokenFactory?: () => string | Promise;\r\n private sendQueue?: TransportSendQueue;\r\n\r\n public readonly features: any = {};\r\n public baseUrl: string;\r\n public connectionId?: string;\r\n public onreceive: ((data: string | ArrayBuffer) => void) | null;\r\n public onclose: ((e?: Error) => void) | null;\r\n\r\n private readonly negotiateVersion: number = 1;\r\n\r\n constructor(url: string, options: IHttpConnectionOptions = {}) {\r\n Arg.isRequired(url, \"url\");\r\n\r\n this.logger = createLogger(options.logger);\r\n this.baseUrl = this.resolveUrl(url);\r\n\r\n options = options || {};\r\n options.logMessageContent = options.logMessageContent || false;\r\n\r\n if (!Platform.isNode && typeof WebSocket !== \"undefined\" && !options.WebSocket) {\r\n options.WebSocket = WebSocket;\r\n } else if (Platform.isNode && !options.WebSocket) {\r\n if (WebSocketModule) {\r\n options.WebSocket = WebSocketModule;\r\n }\r\n }\r\n\r\n if (!Platform.isNode && typeof EventSource !== \"undefined\" && !options.EventSource) {\r\n options.EventSource = EventSource;\r\n } else if (Platform.isNode && !options.EventSource) {\r\n if (typeof EventSourceModule !== \"undefined\") {\r\n options.EventSource = EventSourceModule;\r\n }\r\n }\r\n\r\n this.httpClient = options.httpClient || new DefaultHttpClient(this.logger);\r\n this.connectionState = ConnectionState.Disconnected;\r\n this.connectionStarted = false;\r\n this.options = options;\r\n\r\n this.onreceive = null;\r\n this.onclose = null;\r\n }\r\n\r\n public start(): Promise;\r\n public start(transferFormat: TransferFormat): Promise;\r\n public async start(transferFormat?: TransferFormat): Promise {\r\n transferFormat = transferFormat || TransferFormat.Binary;\r\n\r\n Arg.isIn(transferFormat, TransferFormat, \"transferFormat\");\r\n\r\n this.logger.log(LogLevel.Debug, `Starting connection with transfer format '${TransferFormat[transferFormat]}'.`);\r\n\r\n if (this.connectionState !== ConnectionState.Disconnected) {\r\n return Promise.reject(new Error(\"Cannot start an HttpConnection that is not in the 'Disconnected' state.\"));\r\n }\r\n\r\n this.connectionState = ConnectionState.Connecting;\r\n\r\n this.startInternalPromise = this.startInternal(transferFormat);\r\n await this.startInternalPromise;\r\n\r\n // The TypeScript compiler thinks that connectionState must be Connecting here. The TypeScript compiler is wrong.\r\n if (this.connectionState as any === ConnectionState.Disconnecting) {\r\n // stop() was called and transitioned the client into the Disconnecting state.\r\n const message = \"Failed to start the HttpConnection before stop() was called.\";\r\n this.logger.log(LogLevel.Error, message);\r\n\r\n // We cannot await stopPromise inside startInternal since stopInternal awaits the startInternalPromise.\r\n await this.stopPromise;\r\n\r\n return Promise.reject(new Error(message));\r\n } else if (this.connectionState as any !== ConnectionState.Connected) {\r\n // stop() was called and transitioned the client into the Disconnecting state.\r\n const message = \"HttpConnection.startInternal completed gracefully but didn't enter the connection into the connected state!\";\r\n this.logger.log(LogLevel.Error, message);\r\n return Promise.reject(new Error(message));\r\n }\r\n\r\n this.connectionStarted = true;\r\n }\r\n\r\n public send(data: string | ArrayBuffer): Promise {\r\n if (this.connectionState !== ConnectionState.Connected) {\r\n return Promise.reject(new Error(\"Cannot send data if the connection is not in the 'Connected' State.\"));\r\n }\r\n\r\n if (!this.sendQueue) {\r\n this.sendQueue = new TransportSendQueue(this.transport!);\r\n }\r\n\r\n // Transport will not be null if state is connected\r\n return this.sendQueue.send(data);\r\n }\r\n\r\n public async stop(error?: Error): Promise {\r\n if (this.connectionState === ConnectionState.Disconnected) {\r\n this.logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnected state.`);\r\n return Promise.resolve();\r\n }\r\n\r\n if (this.connectionState === ConnectionState.Disconnecting) {\r\n this.logger.log(LogLevel.Debug, `Call to HttpConnection.stop(${error}) ignored because the connection is already in the disconnecting state.`);\r\n return this.stopPromise;\r\n }\r\n\r\n this.connectionState = ConnectionState.Disconnecting;\r\n\r\n this.stopPromise = new Promise((resolve) => {\r\n // Don't complete stop() until stopConnection() completes.\r\n this.stopPromiseResolver = resolve;\r\n });\r\n\r\n // stopInternal should never throw so just observe it.\r\n await this.stopInternal(error);\r\n await this.stopPromise;\r\n }\r\n\r\n private async stopInternal(error?: Error): Promise {\r\n // Set error as soon as possible otherwise there is a race between\r\n // the transport closing and providing an error and the error from a close message\r\n // We would prefer the close message error.\r\n this.stopError = error;\r\n\r\n try {\r\n await this.startInternalPromise;\r\n } catch (e) {\r\n // This exception is returned to the user as a rejected Promise from the start method.\r\n }\r\n\r\n // The transport's onclose will trigger stopConnection which will run our onclose event.\r\n // The transport should always be set if currently connected. If it wasn't set, it's likely because\r\n // stop was called during start() and start() failed.\r\n if (this.transport) {\r\n try {\r\n await this.transport.stop();\r\n } catch (e) {\r\n this.logger.log(LogLevel.Error, `HttpConnection.transport.stop() threw error '${e}'.`);\r\n this.stopConnection();\r\n }\r\n\r\n this.transport = undefined;\r\n } else {\r\n this.logger.log(LogLevel.Debug, \"HttpConnection.transport is undefined in HttpConnection.stop() because start() failed.\");\r\n }\r\n }\r\n\r\n private async startInternal(transferFormat: TransferFormat): Promise {\r\n // Store the original base url and the access token factory since they may change\r\n // as part of negotiating\r\n let url = this.baseUrl;\r\n this.accessTokenFactory = this.options.accessTokenFactory;\r\n\r\n try {\r\n if (this.options.skipNegotiation) {\r\n if (this.options.transport === HttpTransportType.WebSockets) {\r\n // No need to add a connection ID in this case\r\n this.transport = this.constructTransport(HttpTransportType.WebSockets);\r\n // We should just call connect directly in this case.\r\n // No fallback or negotiate in this case.\r\n await this.startTransport(url, transferFormat);\r\n } else {\r\n throw new Error(\"Negotiation can only be skipped when using the WebSocket transport directly.\");\r\n }\r\n } else {\r\n let negotiateResponse: INegotiateResponse | null = null;\r\n let redirects = 0;\r\n\r\n do {\r\n negotiateResponse = await this.getNegotiationResponse(url);\r\n // the user tries to stop the connection when it is being started\r\n if (this.connectionState === ConnectionState.Disconnecting || this.connectionState === ConnectionState.Disconnected) {\r\n throw new Error(\"The connection was stopped during negotiation.\");\r\n }\r\n\r\n if (negotiateResponse.error) {\r\n throw new Error(negotiateResponse.error);\r\n }\r\n\r\n if ((negotiateResponse as any).ProtocolVersion) {\r\n throw new Error(\"Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.\");\r\n }\r\n\r\n if (negotiateResponse.url) {\r\n url = negotiateResponse.url;\r\n }\r\n\r\n if (negotiateResponse.accessToken) {\r\n // Replace the current access token factory with one that uses\r\n // the returned access token\r\n const accessToken = negotiateResponse.accessToken;\r\n this.accessTokenFactory = () => accessToken;\r\n }\r\n\r\n redirects++;\r\n }\r\n while (negotiateResponse.url && redirects < MAX_REDIRECTS);\r\n\r\n if (redirects === MAX_REDIRECTS && negotiateResponse.url) {\r\n throw new Error(\"Negotiate redirection limit exceeded.\");\r\n }\r\n\r\n await this.createTransport(url, this.options.transport, negotiateResponse, transferFormat);\r\n }\r\n\r\n if (this.transport instanceof LongPollingTransport) {\r\n this.features.inherentKeepAlive = true;\r\n }\r\n\r\n if (this.connectionState === ConnectionState.Connecting) {\r\n // Ensure the connection transitions to the connected state prior to completing this.startInternalPromise.\r\n // start() will handle the case when stop was called and startInternal exits still in the disconnecting state.\r\n this.logger.log(LogLevel.Debug, \"The HttpConnection connected successfully.\");\r\n this.connectionState = ConnectionState.Connected;\r\n }\r\n\r\n // stop() is waiting on us via this.startInternalPromise so keep this.transport around so it can clean up.\r\n // This is the only case startInternal can exit in neither the connected nor disconnected state because stopConnection()\r\n // will transition to the disconnected state. start() will wait for the transition using the stopPromise.\r\n } catch (e) {\r\n this.logger.log(LogLevel.Error, \"Failed to start the connection: \" + e);\r\n this.connectionState = ConnectionState.Disconnected;\r\n this.transport = undefined;\r\n\r\n // if start fails, any active calls to stop assume that start will complete the stop promise\r\n this.stopPromiseResolver();\r\n return Promise.reject(e);\r\n }\r\n }\r\n\r\n private async getNegotiationResponse(url: string): Promise {\r\n let headers;\r\n if (this.accessTokenFactory) {\r\n const token = await this.accessTokenFactory();\r\n if (token) {\r\n headers = {\r\n [\"Authorization\"]: `Bearer ${token}`,\r\n };\r\n }\r\n }\r\n\r\n const negotiateUrl = this.resolveNegotiateUrl(url);\r\n this.logger.log(LogLevel.Debug, `Sending negotiation request: ${negotiateUrl}.`);\r\n try {\r\n const response = await this.httpClient.post(negotiateUrl, {\r\n content: \"\",\r\n headers,\r\n });\r\n\r\n if (response.statusCode !== 200) {\r\n return Promise.reject(new Error(`Unexpected status code returned from negotiate ${response.statusCode}`));\r\n }\r\n\r\n const negotiateResponse = JSON.parse(response.content as string) as INegotiateResponse;\r\n if (!negotiateResponse.negotiateVersion || negotiateResponse.negotiateVersion < 1) {\r\n // Negotiate version 0 doesn't use connectionToken\r\n // So we set it equal to connectionId so all our logic can use connectionToken without being aware of the negotiate version\r\n negotiateResponse.connectionToken = negotiateResponse.connectionId;\r\n }\r\n return negotiateResponse;\r\n } catch (e) {\r\n this.logger.log(LogLevel.Error, \"Failed to complete negotiation with the server: \" + e);\r\n return Promise.reject(e);\r\n }\r\n }\r\n\r\n private createConnectUrl(url: string, connectionToken: string | null | undefined) {\r\n if (!connectionToken) {\r\n return url;\r\n }\r\n\r\n return url + (url.indexOf(\"?\") === -1 ? \"?\" : \"&\") + `id=${connectionToken}`;\r\n }\r\n\r\n private async createTransport(url: string, requestedTransport: HttpTransportType | ITransport | undefined, negotiateResponse: INegotiateResponse, requestedTransferFormat: TransferFormat): Promise {\r\n let connectUrl = this.createConnectUrl(url, negotiateResponse.connectionToken);\r\n if (this.isITransport(requestedTransport)) {\r\n this.logger.log(LogLevel.Debug, \"Connection was provided an instance of ITransport, using that directly.\");\r\n this.transport = requestedTransport;\r\n await this.startTransport(connectUrl, requestedTransferFormat);\r\n\r\n this.connectionId = negotiateResponse.connectionId;\r\n return;\r\n }\r\n\r\n const transportExceptions: any[] = [];\r\n const transports = negotiateResponse.availableTransports || [];\r\n let negotiate: INegotiateResponse | undefined = negotiateResponse;\r\n for (const endpoint of transports) {\r\n const transportOrError = this.resolveTransportOrError(endpoint, requestedTransport, requestedTransferFormat);\r\n if (transportOrError instanceof Error) {\r\n // Store the error and continue, we don't want to cause a re-negotiate in these cases\r\n transportExceptions.push(`${endpoint.transport} failed: ${transportOrError}`);\r\n } else if (this.isITransport(transportOrError)) {\r\n this.transport = transportOrError;\r\n if (!negotiate) {\r\n try {\r\n negotiate = await this.getNegotiationResponse(url);\r\n } catch (ex) {\r\n return Promise.reject(ex);\r\n }\r\n connectUrl = this.createConnectUrl(url, negotiate.connectionToken);\r\n }\r\n try {\r\n await this.startTransport(connectUrl, requestedTransferFormat);\r\n this.connectionId = negotiate.connectionId;\r\n return;\r\n } catch (ex) {\r\n this.logger.log(LogLevel.Error, `Failed to start the transport '${endpoint.transport}': ${ex}`);\r\n negotiate = undefined;\r\n transportExceptions.push(`${endpoint.transport} failed: ${ex}`);\r\n\r\n if (this.connectionState !== ConnectionState.Connecting) {\r\n const message = \"Failed to select transport before stop() was called.\";\r\n this.logger.log(LogLevel.Debug, message);\r\n return Promise.reject(new Error(message));\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (transportExceptions.length > 0) {\r\n return Promise.reject(new Error(`Unable to connect to the server with any of the available transports. ${transportExceptions.join(\" \")}`));\r\n }\r\n return Promise.reject(new Error(\"None of the transports supported by the client are supported by the server.\"));\r\n }\r\n\r\n private constructTransport(transport: HttpTransportType): ITransport {\r\n switch (transport) {\r\n case HttpTransportType.WebSockets:\r\n if (!this.options.WebSocket) {\r\n throw new Error(\"'WebSocket' is not supported in your environment.\");\r\n }\r\n return new WebSocketTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false, this.options.WebSocket);\r\n case HttpTransportType.ServerSentEvents:\r\n if (!this.options.EventSource) {\r\n throw new Error(\"'EventSource' is not supported in your environment.\");\r\n }\r\n return new ServerSentEventsTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false, this.options.EventSource);\r\n case HttpTransportType.LongPolling:\r\n return new LongPollingTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false);\r\n default:\r\n throw new Error(`Unknown transport: ${transport}.`);\r\n }\r\n }\r\n\r\n private startTransport(url: string, transferFormat: TransferFormat): Promise {\r\n this.transport!.onreceive = this.onreceive;\r\n this.transport!.onclose = (e) => this.stopConnection(e);\r\n return this.transport!.connect(url, transferFormat);\r\n }\r\n\r\n private resolveTransportOrError(endpoint: IAvailableTransport, requestedTransport: HttpTransportType | undefined, requestedTransferFormat: TransferFormat): ITransport | Error {\r\n const transport = HttpTransportType[endpoint.transport];\r\n if (transport === null || transport === undefined) {\r\n this.logger.log(LogLevel.Debug, `Skipping transport '${endpoint.transport}' because it is not supported by this client.`);\r\n return new Error(`Skipping transport '${endpoint.transport}' because it is not supported by this client.`);\r\n } else {\r\n if (transportMatches(requestedTransport, transport)) {\r\n const transferFormats = endpoint.transferFormats.map((s) => TransferFormat[s]);\r\n if (transferFormats.indexOf(requestedTransferFormat) >= 0) {\r\n if ((transport === HttpTransportType.WebSockets && !this.options.WebSocket) ||\r\n (transport === HttpTransportType.ServerSentEvents && !this.options.EventSource)) {\r\n this.logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it is not supported in your environment.'`);\r\n return new Error(`'${HttpTransportType[transport]}' is not supported in your environment.`);\r\n } else {\r\n this.logger.log(LogLevel.Debug, `Selecting transport '${HttpTransportType[transport]}'.`);\r\n try {\r\n return this.constructTransport(transport);\r\n } catch (ex) {\r\n return ex;\r\n }\r\n }\r\n } else {\r\n this.logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it does not support the requested transfer format '${TransferFormat[requestedTransferFormat]}'.`);\r\n return new Error(`'${HttpTransportType[transport]}' does not support ${TransferFormat[requestedTransferFormat]}.`);\r\n }\r\n } else {\r\n this.logger.log(LogLevel.Debug, `Skipping transport '${HttpTransportType[transport]}' because it was disabled by the client.`);\r\n return new Error(`'${HttpTransportType[transport]}' is disabled by the client.`);\r\n }\r\n }\r\n }\r\n\r\n private isITransport(transport: any): transport is ITransport {\r\n return transport && typeof (transport) === \"object\" && \"connect\" in transport;\r\n }\r\n\r\n private stopConnection(error?: Error): void {\r\n this.logger.log(LogLevel.Debug, `HttpConnection.stopConnection(${error}) called while in state ${this.connectionState}.`);\r\n\r\n this.transport = undefined;\r\n\r\n // If we have a stopError, it takes precedence over the error from the transport\r\n error = this.stopError || error;\r\n this.stopError = undefined;\r\n\r\n if (this.connectionState === ConnectionState.Disconnected) {\r\n this.logger.log(LogLevel.Debug, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is already in the disconnected state.`);\r\n return;\r\n }\r\n\r\n if (this.connectionState === ConnectionState.Connecting) {\r\n this.logger.log(LogLevel.Warning, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection hasn't yet left the in the connecting state.`);\r\n return;\r\n }\r\n\r\n if (this.connectionState === ConnectionState.Disconnecting) {\r\n // A call to stop() induced this call to stopConnection and needs to be completed.\r\n // Any stop() awaiters will be scheduled to continue after the onclose callback fires.\r\n this.stopPromiseResolver();\r\n }\r\n\r\n if (error) {\r\n this.logger.log(LogLevel.Error, `Connection disconnected with error '${error}'.`);\r\n } else {\r\n this.logger.log(LogLevel.Information, \"Connection disconnected.\");\r\n }\r\n\r\n if (this.sendQueue) {\r\n this.sendQueue.stop().catch((e) => {\r\n this.logger.log(LogLevel.Error, `TransportSendQueue.stop() threw error '${e}'.`);\r\n });\r\n this.sendQueue = undefined;\r\n }\r\n\r\n this.connectionId = undefined;\r\n this.connectionState = ConnectionState.Disconnected;\r\n\r\n if (this.connectionStarted) {\r\n this.connectionStarted = false;\r\n try {\r\n if (this.onclose) {\r\n this.onclose(error);\r\n }\r\n } catch (e) {\r\n this.logger.log(LogLevel.Error, `HttpConnection.onclose(${error}) threw error '${e}'.`);\r\n }\r\n }\r\n }\r\n\r\n private resolveUrl(url: string): string {\r\n // startsWith is not supported in IE\r\n if (url.lastIndexOf(\"https://\", 0) === 0 || url.lastIndexOf(\"http://\", 0) === 0) {\r\n return url;\r\n }\r\n\r\n if (!Platform.isBrowser || !window.document) {\r\n throw new Error(`Cannot resolve '${url}'.`);\r\n }\r\n\r\n // Setting the url to the href propery of an anchor tag handles normalization\r\n // for us. There are 3 main cases.\r\n // 1. Relative path normalization e.g \"b\" -> \"http://localhost:5000/a/b\"\r\n // 2. Absolute path normalization e.g \"/a/b\" -> \"http://localhost:5000/a/b\"\r\n // 3. Networkpath reference normalization e.g \"//localhost:5000/a/b\" -> \"http://localhost:5000/a/b\"\r\n const aTag = window.document.createElement(\"a\");\r\n aTag.href = url;\r\n\r\n this.logger.log(LogLevel.Information, `Normalizing '${url}' to '${aTag.href}'.`);\r\n return aTag.href;\r\n }\r\n\r\n private resolveNegotiateUrl(url: string): string {\r\n const index = url.indexOf(\"?\");\r\n let negotiateUrl = url.substring(0, index === -1 ? url.length : index);\r\n if (negotiateUrl[negotiateUrl.length - 1] !== \"/\") {\r\n negotiateUrl += \"/\";\r\n }\r\n negotiateUrl += \"negotiate\";\r\n negotiateUrl += index === -1 ? \"\" : url.substring(index);\r\n\r\n if (negotiateUrl.indexOf(\"negotiateVersion\") === -1) {\r\n negotiateUrl += index === -1 ? \"?\" : \"&\";\r\n negotiateUrl += \"negotiateVersion=\" + this.negotiateVersion;\r\n }\r\n return negotiateUrl;\r\n }\r\n}\r\n\r\nfunction transportMatches(requestedTransport: HttpTransportType | undefined, actualTransport: HttpTransportType) {\r\n return !requestedTransport || ((actualTransport & requestedTransport) !== 0);\r\n}\r\n\r\n/** @private */\r\nexport class TransportSendQueue {\r\n private buffer: any[] = [];\r\n private sendBufferedData: PromiseSource;\r\n private executing: boolean = true;\r\n private transportResult?: PromiseSource;\r\n private sendLoopPromise: Promise;\r\n\r\n constructor(private readonly transport: ITransport) {\r\n this.sendBufferedData = new PromiseSource();\r\n this.transportResult = new PromiseSource();\r\n\r\n this.sendLoopPromise = this.sendLoop();\r\n }\r\n\r\n public send(data: string | ArrayBuffer): Promise {\r\n this.bufferData(data);\r\n if (!this.transportResult) {\r\n this.transportResult = new PromiseSource();\r\n }\r\n return this.transportResult.promise;\r\n }\r\n\r\n public stop(): Promise {\r\n this.executing = false;\r\n this.sendBufferedData.resolve();\r\n return this.sendLoopPromise;\r\n }\r\n\r\n private bufferData(data: string | ArrayBuffer): void {\r\n if (this.buffer.length && typeof(this.buffer[0]) !== typeof(data)) {\r\n throw new Error(`Expected data to be of type ${typeof(this.buffer)} but was of type ${typeof(data)}`);\r\n }\r\n\r\n this.buffer.push(data);\r\n this.sendBufferedData.resolve();\r\n }\r\n\r\n private async sendLoop(): Promise {\r\n while (true) {\r\n await this.sendBufferedData.promise;\r\n\r\n if (!this.executing) {\r\n if (this.transportResult) {\r\n this.transportResult.reject(\"Connection stopped.\");\r\n }\r\n\r\n break;\r\n }\r\n\r\n this.sendBufferedData = new PromiseSource();\r\n\r\n const transportResult = this.transportResult!;\r\n this.transportResult = undefined;\r\n\r\n const data = typeof(this.buffer[0]) === \"string\" ?\r\n this.buffer.join(\"\") :\r\n TransportSendQueue.concatBuffers(this.buffer);\r\n\r\n this.buffer.length = 0;\r\n\r\n try {\r\n await this.transport.send(data);\r\n transportResult.resolve();\r\n } catch (error) {\r\n transportResult.reject(error);\r\n }\r\n }\r\n }\r\n\r\n private static concatBuffers(arrayBuffers: ArrayBuffer[]): ArrayBuffer {\r\n const totalLength = arrayBuffers.map((b) => b.byteLength).reduce((a, b) => a + b);\r\n const result = new Uint8Array(totalLength);\r\n let offset = 0;\r\n for (const item of arrayBuffers) {\r\n result.set(new Uint8Array(item), offset);\r\n offset += item.byteLength;\r\n }\r\n\r\n return result;\r\n }\r\n}\r\n\r\nclass PromiseSource {\r\n private resolver?: () => void;\r\n private rejecter!: (reason?: any) => void;\r\n public promise: Promise;\r\n\r\n constructor() {\r\n this.promise = new Promise((resolve, reject) => [this.resolver, this.rejecter] = [resolve, reject]);\r\n }\r\n\r\n public resolve(): void {\r\n this.resolver!();\r\n }\r\n\r\n public reject(reason?: any): void {\r\n this.rejecter!(reason);\r\n }\r\n}\r\n","// 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 { CompletionMessage, HubMessage, IHubProtocol, InvocationMessage, MessageType, StreamItemMessage } from \"./IHubProtocol\";\r\nimport { ILogger, LogLevel } from \"./ILogger\";\r\nimport { TransferFormat } from \"./ITransport\";\r\nimport { NullLogger } from \"./Loggers\";\r\nimport { TextMessageFormat } from \"./TextMessageFormat\";\r\n\r\nconst JSON_HUB_PROTOCOL_NAME: string = \"json\";\r\n\r\n/** Implements the JSON Hub Protocol. */\r\nexport class JsonHubProtocol implements IHubProtocol {\r\n\r\n /** @inheritDoc */\r\n public readonly name: string = JSON_HUB_PROTOCOL_NAME;\r\n /** @inheritDoc */\r\n public readonly version: number = 1;\r\n\r\n /** @inheritDoc */\r\n public readonly transferFormat: TransferFormat = TransferFormat.Text;\r\n\r\n /** Creates an array of {@link @microsoft/signalr.HubMessage} objects from the specified serialized representation.\r\n *\r\n * @param {string} input A string containing the serialized representation.\r\n * @param {ILogger} logger A logger that will be used to log messages that occur during parsing.\r\n */\r\n public parseMessages(input: string, logger: ILogger): HubMessage[] {\r\n // The interface does allow \"ArrayBuffer\" to be passed in, but this implementation does not. So let's throw a useful error.\r\n if (typeof input !== \"string\") {\r\n throw new Error(\"Invalid input for JSON hub protocol. Expected a string.\");\r\n }\r\n\r\n if (!input) {\r\n return [];\r\n }\r\n\r\n if (logger === null) {\r\n logger = NullLogger.instance;\r\n }\r\n\r\n // Parse the messages\r\n const messages = TextMessageFormat.parse(input);\r\n\r\n const hubMessages = [];\r\n for (const message of messages) {\r\n const parsedMessage = JSON.parse(message) as HubMessage;\r\n if (typeof parsedMessage.type !== \"number\") {\r\n throw new Error(\"Invalid payload.\");\r\n }\r\n switch (parsedMessage.type) {\r\n case MessageType.Invocation:\r\n this.isInvocationMessage(parsedMessage);\r\n break;\r\n case MessageType.StreamItem:\r\n this.isStreamItemMessage(parsedMessage);\r\n break;\r\n case MessageType.Completion:\r\n this.isCompletionMessage(parsedMessage);\r\n break;\r\n case MessageType.Ping:\r\n // Single value, no need to validate\r\n break;\r\n case MessageType.Close:\r\n // All optional values, no need to validate\r\n break;\r\n default:\r\n // Future protocol changes can add message types, old clients can ignore them\r\n logger.log(LogLevel.Information, \"Unknown message type '\" + parsedMessage.type + \"' ignored.\");\r\n continue;\r\n }\r\n hubMessages.push(parsedMessage);\r\n }\r\n\r\n return hubMessages;\r\n }\r\n\r\n /** Writes the specified {@link @microsoft/signalr.HubMessage} to a string and returns it.\r\n *\r\n * @param {HubMessage} message The message to write.\r\n * @returns {string} A string containing the serialized representation of the message.\r\n */\r\n public writeMessage(message: HubMessage): string {\r\n return TextMessageFormat.write(JSON.stringify(message));\r\n }\r\n\r\n private isInvocationMessage(message: InvocationMessage): void {\r\n this.assertNotEmptyString(message.target, \"Invalid payload for Invocation message.\");\r\n\r\n if (message.invocationId !== undefined) {\r\n this.assertNotEmptyString(message.invocationId, \"Invalid payload for Invocation message.\");\r\n }\r\n }\r\n\r\n private isStreamItemMessage(message: StreamItemMessage): void {\r\n this.assertNotEmptyString(message.invocationId, \"Invalid payload for StreamItem message.\");\r\n\r\n if (message.item === undefined) {\r\n throw new Error(\"Invalid payload for StreamItem message.\");\r\n }\r\n }\r\n\r\n private isCompletionMessage(message: CompletionMessage): void {\r\n if (message.result && message.error) {\r\n throw new Error(\"Invalid payload for Completion message.\");\r\n }\r\n\r\n if (!message.result && message.error) {\r\n this.assertNotEmptyString(message.error, \"Invalid payload for Completion message.\");\r\n }\r\n\r\n this.assertNotEmptyString(message.invocationId, \"Invalid payload for Completion message.\");\r\n }\r\n\r\n private assertNotEmptyString(value: any, errorMessage: string): void {\r\n if (typeof value !== \"string\" || value === \"\") {\r\n throw new Error(errorMessage);\r\n }\r\n }\r\n}\r\n","// 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 { DefaultReconnectPolicy } from \"./DefaultReconnectPolicy\";\r\nimport { HttpConnection } from \"./HttpConnection\";\r\nimport { HubConnection } from \"./HubConnection\";\r\nimport { IHttpConnectionOptions } from \"./IHttpConnectionOptions\";\r\nimport { IHubProtocol } from \"./IHubProtocol\";\r\nimport { ILogger, LogLevel } from \"./ILogger\";\r\nimport { IRetryPolicy } from \"./IRetryPolicy\";\r\nimport { HttpTransportType } from \"./ITransport\";\r\nimport { JsonHubProtocol } from \"./JsonHubProtocol\";\r\nimport { NullLogger } from \"./Loggers\";\r\nimport { Arg, ConsoleLogger } from \"./Utils\";\r\n\r\n// tslint:disable:object-literal-sort-keys\r\nconst LogLevelNameMapping = {\r\n trace: LogLevel.Trace,\r\n debug: LogLevel.Debug,\r\n info: LogLevel.Information,\r\n information: LogLevel.Information,\r\n warn: LogLevel.Warning,\r\n warning: LogLevel.Warning,\r\n error: LogLevel.Error,\r\n critical: LogLevel.Critical,\r\n none: LogLevel.None,\r\n};\r\n\r\nfunction parseLogLevel(name: string): LogLevel {\r\n // Case-insensitive matching via lower-casing\r\n // Yes, I know case-folding is a complicated problem in Unicode, but we only support\r\n // the ASCII strings defined in LogLevelNameMapping anyway, so it's fine -anurse.\r\n const mapping = LogLevelNameMapping[name.toLowerCase()];\r\n if (typeof mapping !== \"undefined\") {\r\n return mapping;\r\n } else {\r\n throw new Error(`Unknown log level: ${name}`);\r\n }\r\n}\r\n\r\n/** A builder for configuring {@link @microsoft/signalr.HubConnection} instances. */\r\nexport class HubConnectionBuilder {\r\n /** @internal */\r\n public protocol?: IHubProtocol;\r\n /** @internal */\r\n public httpConnectionOptions?: IHttpConnectionOptions;\r\n /** @internal */\r\n public url?: string;\r\n /** @internal */\r\n public logger?: ILogger;\r\n\r\n /** If defined, this indicates the client should automatically attempt to reconnect if the connection is lost. */\r\n /** @internal */\r\n public reconnectPolicy?: IRetryPolicy;\r\n\r\n /** Configures console logging for the {@link @microsoft/signalr.HubConnection}.\r\n *\r\n * @param {LogLevel} logLevel The minimum level of messages to log. Anything at this level, or a more severe level, will be logged.\r\n * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.\r\n */\r\n public configureLogging(logLevel: LogLevel): HubConnectionBuilder;\r\n\r\n /** Configures custom logging for the {@link @microsoft/signalr.HubConnection}.\r\n *\r\n * @param {ILogger} logger An object implementing the {@link @microsoft/signalr.ILogger} interface, which will be used to write all log messages.\r\n * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.\r\n */\r\n public configureLogging(logger: ILogger): HubConnectionBuilder;\r\n\r\n /** Configures custom logging for the {@link @microsoft/signalr.HubConnection}.\r\n *\r\n * @param {string} logLevel A string representing a LogLevel setting a minimum level of messages to log.\r\n * See {@link https://docs.microsoft.com/en-us/aspnet/core/signalr/configuration#configure-logging|the documentation for client logging configuration} for more details.\r\n */\r\n public configureLogging(logLevel: string): HubConnectionBuilder;\r\n\r\n /** Configures custom logging for the {@link @microsoft/signalr.HubConnection}.\r\n *\r\n * @param {LogLevel | string | ILogger} logging A {@link @microsoft/signalr.LogLevel}, a string representing a LogLevel, or an object implementing the {@link @microsoft/signalr.ILogger} interface.\r\n * See {@link https://docs.microsoft.com/en-us/aspnet/core/signalr/configuration#configure-logging|the documentation for client logging configuration} for more details.\r\n * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.\r\n */\r\n public configureLogging(logging: LogLevel | string | ILogger): HubConnectionBuilder;\r\n public configureLogging(logging: LogLevel | string | ILogger): HubConnectionBuilder {\r\n Arg.isRequired(logging, \"logging\");\r\n\r\n if (isLogger(logging)) {\r\n this.logger = logging;\r\n } else if (typeof logging === \"string\") {\r\n const logLevel = parseLogLevel(logging);\r\n this.logger = new ConsoleLogger(logLevel);\r\n } else {\r\n this.logger = new ConsoleLogger(logging);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /** Configures the {@link @microsoft/signalr.HubConnection} to use HTTP-based transports to connect to the specified URL.\r\n *\r\n * The transport will be selected automatically based on what the server and client support.\r\n *\r\n * @param {string} url The URL the connection will use.\r\n * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.\r\n */\r\n public withUrl(url: string): HubConnectionBuilder;\r\n\r\n /** Configures the {@link @microsoft/signalr.HubConnection} to use the specified HTTP-based transport to connect to the specified URL.\r\n *\r\n * @param {string} url The URL the connection will use.\r\n * @param {HttpTransportType} transportType The specific transport to use.\r\n * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.\r\n */\r\n public withUrl(url: string, transportType: HttpTransportType): HubConnectionBuilder;\r\n\r\n /** Configures the {@link @microsoft/signalr.HubConnection} to use HTTP-based transports to connect to the specified URL.\r\n *\r\n * @param {string} url The URL the connection will use.\r\n * @param {IHttpConnectionOptions} options An options object used to configure the connection.\r\n * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining.\r\n */\r\n public withUrl(url: string, options: IHttpConnectionOptions): HubConnectionBuilder;\r\n public withUrl(url: string, transportTypeOrOptions?: IHttpConnectionOptions | HttpTransportType): HubConnectionBuilder {\r\n Arg.isRequired(url, \"url\");\r\n\r\n this.url = url;\r\n\r\n // Flow-typing knows where it's at. Since HttpTransportType is a number and IHttpConnectionOptions is guaranteed\r\n // to be an object, we know (as does TypeScript) this comparison is all we need to figure out which overload was called.\r\n if (typeof transportTypeOrOptions === \"object\") {\r\n this.httpConnectionOptions = { ...this.httpConnectionOptions, ...transportTypeOrOptions };\r\n } else {\r\n this.httpConnectionOptions = {\r\n ...this.httpConnectionOptions,\r\n transport: transportTypeOrOptions,\r\n };\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /** Configures the {@link @microsoft/signalr.HubConnection} to use the specified Hub Protocol.\r\n *\r\n * @param {IHubProtocol} protocol The {@link @microsoft/signalr.IHubProtocol} implementation to use.\r\n */\r\n public withHubProtocol(protocol: IHubProtocol): HubConnectionBuilder {\r\n Arg.isRequired(protocol, \"protocol\");\r\n\r\n this.protocol = protocol;\r\n return this;\r\n }\r\n\r\n /** Configures the {@link @microsoft/signalr.HubConnection} to automatically attempt to reconnect if the connection is lost.\r\n * By default, the client will wait 0, 2, 10 and 30 seconds respectively before trying up to 4 reconnect attempts.\r\n */\r\n public withAutomaticReconnect(): HubConnectionBuilder;\r\n\r\n /** Configures the {@link @microsoft/signalr.HubConnection} to automatically attempt to reconnect if the connection is lost.\r\n *\r\n * @param {number[]} retryDelays An array containing the delays in milliseconds before trying each reconnect attempt.\r\n * The length of the array represents how many failed reconnect attempts it takes before the client will stop attempting to reconnect.\r\n */\r\n public withAutomaticReconnect(retryDelays: number[]): HubConnectionBuilder;\r\n\r\n /** Configures the {@link @microsoft/signalr.HubConnection} to automatically attempt to reconnect if the connection is lost.\r\n *\r\n * @param {IRetryPolicy} reconnectPolicy An {@link @microsoft/signalR.IRetryPolicy} that controls the timing and number of reconnect attempts.\r\n */\r\n public withAutomaticReconnect(reconnectPolicy: IRetryPolicy): HubConnectionBuilder;\r\n public withAutomaticReconnect(retryDelaysOrReconnectPolicy?: number[] | IRetryPolicy): HubConnectionBuilder {\r\n if (this.reconnectPolicy) {\r\n throw new Error(\"A reconnectPolicy has already been set.\");\r\n }\r\n\r\n if (!retryDelaysOrReconnectPolicy) {\r\n this.reconnectPolicy = new DefaultReconnectPolicy();\r\n } else if (Array.isArray(retryDelaysOrReconnectPolicy)) {\r\n this.reconnectPolicy = new DefaultReconnectPolicy(retryDelaysOrReconnectPolicy);\r\n } else {\r\n this.reconnectPolicy = retryDelaysOrReconnectPolicy;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /** Creates a {@link @microsoft/signalr.HubConnection} from the configuration options specified in this builder.\r\n *\r\n * @returns {HubConnection} The configured {@link @microsoft/signalr.HubConnection}.\r\n */\r\n public build(): HubConnection {\r\n // If httpConnectionOptions has a logger, use it. Otherwise, override it with the one\r\n // provided to configureLogger\r\n const httpConnectionOptions = this.httpConnectionOptions || {};\r\n\r\n // If it's 'null', the user **explicitly** asked for null, don't mess with it.\r\n if (httpConnectionOptions.logger === undefined) {\r\n // If our logger is undefined or null, that's OK, the HttpConnection constructor will handle it.\r\n httpConnectionOptions.logger = this.logger;\r\n }\r\n\r\n // Now create the connection\r\n if (!this.url) {\r\n throw new Error(\"The 'HubConnectionBuilder.withUrl' method must be called before building the connection.\");\r\n }\r\n const connection = new HttpConnection(this.url, httpConnectionOptions);\r\n\r\n return HubConnection.create(\r\n connection,\r\n this.logger || NullLogger.instance,\r\n this.protocol || new JsonHubProtocol(),\r\n this.reconnectPolicy);\r\n }\r\n}\r\n\r\nfunction isLogger(logger: any): logger is ILogger {\r\n return logger.log !== undefined;\r\n}\r\n","// 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\n/** Error thrown when an HTTP request fails. */\r\nexport class HttpError extends Error {\r\n // @ts-ignore: Intentionally unused.\r\n // tslint:disable-next-line:variable-name\r\n private __proto__: Error;\r\n\r\n /** The HTTP status code represented by this error. */\r\n public statusCode: number;\r\n\r\n /** Constructs a new instance of {@link @microsoft/signalr.HttpError}.\r\n *\r\n * @param {string} errorMessage A descriptive error message.\r\n * @param {number} statusCode The HTTP status code represented by this error.\r\n */\r\n constructor(errorMessage: string, statusCode: number) {\r\n const trueProto = new.target.prototype;\r\n super(errorMessage);\r\n this.statusCode = statusCode;\r\n\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n\r\n/** Error thrown when a timeout elapses. */\r\nexport class TimeoutError extends Error {\r\n // @ts-ignore: Intentionally unused.\r\n // tslint:disable-next-line:variable-name\r\n private __proto__: Error;\r\n\r\n /** Constructs a new instance of {@link @microsoft/signalr.TimeoutError}.\r\n *\r\n * @param {string} errorMessage A descriptive error message.\r\n */\r\n constructor(errorMessage: string = \"A timeout occurred.\") {\r\n const trueProto = new.target.prototype;\r\n super(errorMessage);\r\n\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n\r\n/** Error thrown when an action is aborted. */\r\nexport class AbortError extends Error {\r\n // @ts-ignore: Intentionally unused.\r\n // tslint:disable-next-line:variable-name\r\n private __proto__: Error;\r\n\r\n /** Constructs a new instance of {@link AbortError}.\r\n *\r\n * @param {string} errorMessage A descriptive error message.\r\n */\r\n constructor(errorMessage: string = \"An abort occurred.\") {\r\n const trueProto = new.target.prototype;\r\n super(errorMessage);\r\n\r\n // Workaround issue in Typescript compiler\r\n // https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200\r\n this.__proto__ = trueProto;\r\n }\r\n}\r\n"],"sourceRoot":""}