diff --git a/client-ts/signalr/src/HttpClient.ts b/client-ts/signalr/src/HttpClient.ts index 2f8e329834..d3996e7e6b 100644 --- a/client-ts/signalr/src/HttpClient.ts +++ b/client-ts/signalr/src/HttpClient.ts @@ -8,7 +8,7 @@ export interface HttpRequest { method?: string; url?: string; content?: string | ArrayBuffer; - headers?: Map; + headers?: { [key: string]: string }; responseType?: XMLHttpRequestResponseType; abortSignal?: AbortSignal; timeout?: number; @@ -58,7 +58,8 @@ export class DefaultHttpClient extends HttpClient { xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); if (request.headers) { - request.headers.forEach((value, header) => xhr.setRequestHeader(header, value)); + Object.keys(request.headers) + .forEach((header) => xhr.setRequestHeader(header, request.headers[header])); } if (request.responseType) { diff --git a/client-ts/signalr/src/HttpConnection.ts b/client-ts/signalr/src/HttpConnection.ts index 178d67ecba..974a4bdb08 100644 --- a/client-ts/signalr/src/HttpConnection.ts +++ b/client-ts/signalr/src/HttpConnection.ts @@ -83,8 +83,9 @@ export class HttpConnection implements IConnection { let headers; const token = this.options.accessTokenFactory(); if (token) { - headers = new Map(); - headers.set("Authorization", `Bearer ${token}`); + headers = { + ["Authorization"]: `Bearer ${token}`, + }; } const negotiatePayload = await this.httpClient.post(this.resolveNegotiateUrl(this.baseUrl), { diff --git a/client-ts/signalr/src/HubConnection.ts b/client-ts/signalr/src/HubConnection.ts index f6aa33f333..3335b5eade 100644 --- a/client-ts/signalr/src/HubConnection.ts +++ b/client-ts/signalr/src/HubConnection.ts @@ -25,8 +25,8 @@ export class HubConnection { private readonly connection: IConnection; private readonly logger: ILogger; private protocol: IHubProtocol; - private callbacks: Map void>; - private methods: Map void>>; + private callbacks: { [invocationId: string]: (invocationEvent: StreamItemMessage | CompletionMessage, error?: Error) => void }; + private methods: { [name: string]: Array<(...args: any[]) => void> }; private id: number; private closedCallbacks: ConnectionClosed[]; private timeoutHandle: NodeJS.Timer; @@ -53,8 +53,8 @@ export class HubConnection { this.connection.onreceive = (data: any) => this.processIncomingData(data); this.connection.onclose = (error?: Error) => this.connectionClosed(error); - this.callbacks = new Map void>(); - this.methods = new Map void>>(); + this.callbacks = {}; + this.methods = {}; this.closedCallbacks = []; this.id = 0; } @@ -79,10 +79,10 @@ export class HubConnection { break; case MessageType.StreamItem: case MessageType.Completion: - const callback = this.callbacks.get(message.invocationId); + const callback = this.callbacks[message.invocationId]; if (callback != null) { if (message.type === MessageType.Completion) { - this.callbacks.delete(message.invocationId); + delete this.callbacks[message.invocationId]; } callback(message); } @@ -174,7 +174,7 @@ export class HubConnection { } private invokeClientMethod(invocationMessage: InvocationMessage) { - const methods = this.methods.get(invocationMessage.target.toLowerCase()); + const methods = this.methods[invocationMessage.target.toLowerCase()]; if (methods) { methods.forEach((m) => m.apply(this, invocationMessage.arguments)); if (invocationMessage.invocationId) { @@ -189,10 +189,14 @@ export class HubConnection { } private connectionClosed(error?: Error) { - this.callbacks.forEach((callback) => { - callback(undefined, error ? error : new Error("Invocation canceled due to connection being closed.")); - }); - this.callbacks.clear(); + const callbacks = this.callbacks; + this.callbacks = {}; + + Object.keys(callbacks) + .forEach((key) => { + const callback = callbacks[key]; + callback(undefined, error ? error : new Error("Invocation canceled due to connection being closed.")); + }); this.cleanupTimeout(); @@ -228,12 +232,12 @@ export class HubConnection { const cancelInvocation: CancelInvocationMessage = this.createCancelInvocation(invocationDescriptor.invocationId); const cancelMessage: any = this.protocol.writeMessage(cancelInvocation); - this.callbacks.delete(invocationDescriptor.invocationId); + delete this.callbacks[invocationDescriptor.invocationId]; return this.connection.send(cancelMessage); }); - this.callbacks.set(invocationDescriptor.invocationId, (invocationEvent: CompletionMessage | StreamItemMessage, error?: Error) => { + this.callbacks[invocationDescriptor.invocationId] = (invocationEvent: CompletionMessage | StreamItemMessage, error?: Error) => { if (error) { subject.error(error); return; @@ -248,14 +252,14 @@ export class HubConnection { } else { subject.next((invocationEvent.item) as T); } - }); + }; const message = this.protocol.writeMessage(invocationDescriptor); this.connection.send(message) .catch((e) => { subject.error(e); - this.callbacks.delete(invocationDescriptor.invocationId); + delete this.callbacks[invocationDescriptor.invocationId]; }); return subject; @@ -273,7 +277,7 @@ export class HubConnection { const invocationDescriptor = this.createInvocation(methodName, args, false); const p = new Promise((resolve, reject) => { - this.callbacks.set(invocationDescriptor.invocationId, (invocationEvent: StreamItemMessage | CompletionMessage, error?: Error) => { + this.callbacks[invocationDescriptor.invocationId] = (invocationEvent: StreamItemMessage | CompletionMessage, error?: Error) => { if (error) { reject(error); return; @@ -288,14 +292,14 @@ export class HubConnection { } else { reject(new Error(`Unexpected message type: ${invocationEvent.type}`)); } - }); + }; const message = this.protocol.writeMessage(invocationDescriptor); this.connection.send(message) .catch((e) => { reject(e); - this.callbacks.delete(invocationDescriptor.invocationId); + delete this.callbacks[invocationDescriptor.invocationId]; }); }); @@ -308,11 +312,11 @@ export class HubConnection { } methodName = methodName.toLowerCase(); - if (!this.methods.has(methodName)) { - this.methods.set(methodName, []); + if (!this.methods[methodName]) { + this.methods[methodName] = []; } - this.methods.get(methodName).push(method); + this.methods[methodName].push(method); } public off(methodName: string, method: (...args: any[]) => void) { @@ -321,7 +325,7 @@ export class HubConnection { } methodName = methodName.toLowerCase(); - const handlers = this.methods.get(methodName); + const handlers = this.methods[methodName]; if (!handlers) { return; } @@ -329,7 +333,7 @@ export class HubConnection { if (removeIdx !== -1) { handlers.splice(removeIdx, 1); if (handlers.length === 0) { - this.methods.delete(methodName); + delete this.methods[methodName]; } } } diff --git a/client-ts/signalr/src/Transports.ts b/client-ts/signalr/src/Transports.ts index 480196bc81..50f23e30b9 100644 --- a/client-ts/signalr/src/Transports.ts +++ b/client-ts/signalr/src/Transports.ts @@ -238,7 +238,7 @@ export class LongPollingTransport implements ITransport { private async poll(url: string, transferFormat: TransferFormat): Promise { const pollOptions: HttpRequest = { abortSignal: this.pollAbort.signal, - headers: new Map(), + headers: {}, timeout: 90000, }; @@ -248,7 +248,8 @@ export class LongPollingTransport implements ITransport { const token = this.accessTokenFactory(); if (token) { - pollOptions.headers.set("Authorization", `Bearer ${token}`); + // tslint:disable-next-line:no-string-literal + pollOptions.headers["Authorization"] = `Bearer ${token}`; } while (!this.pollAbort.signal.aborted) { @@ -316,8 +317,9 @@ async function send(httpClient: HttpClient, url: string, accessTokenFactory: () let headers; const token = accessTokenFactory(); if (token) { - headers = new Map(); - headers.set("Authorization", `Bearer ${accessTokenFactory()}`); + headers = { + ["Authorization"]: `Bearer ${accessTokenFactory()}`, + }; } await httpClient.post(url, { diff --git a/client-ts/tsconfig-base.json b/client-ts/tsconfig-base.json index 2122a6c242..78b45efe77 100644 --- a/client-ts/tsconfig-base.json +++ b/client-ts/tsconfig-base.json @@ -13,6 +13,6 @@ "noImplicitAny": true, "suppressImplicitAnyIndexErrors": true, "noEmitOnError": true, - "lib": [ "es2016", "dom" ] + "lib": [ "es5", "es2015.promise", "es2015.iterable", "dom" ] } }