Skip to content

Commit a771b18

Browse files
authored
remove "dom" from bf-streaming tsconfig and refactor code (#1575) (#1579)
* remove "dom" from bf-streaming tsconfig and refactor code * remove isBrowser, look for global members instead
1 parent b6216db commit a771b18

File tree

10 files changed

+137
-8
lines changed

10 files changed

+137
-8
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @module botframework-streaming
3+
*/
4+
/**
5+
* Copyright (c) Microsoft Corporation. All rights reserved.
6+
* Licensed under the MIT License.
7+
*/
8+
9+
/**
10+
* Partially represents a FileReader from the W3C FileAPI Working Draft.
11+
* For more information, see https://w3c.github.io/FileAPI/#APIASynch.
12+
*
13+
* This interface supports the framework and is not intended to be called directly for your code.
14+
*/
15+
export interface IBrowserFileReader {
16+
result: any;
17+
onload: (event: any) => void;
18+
readAsArrayBuffer: (blobOrFile: any) => void;
19+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @module botframework-streaming
3+
*/
4+
/**
5+
* Copyright (c) Microsoft Corporation. All rights reserved.
6+
* Licensed under the MIT License.
7+
*/
8+
9+
/**
10+
* Partially represents a WebSocket from the HTML Living Standard.
11+
* For more information, see https://html.spec.whatwg.org/multipage/web-sockets.html.
12+
*
13+
* This interface supports the framework and is not intended to be called directly for your code.
14+
*/
15+
export interface IBrowserWebSocket {
16+
onclose: (event: any) => void;
17+
onerror: (event: any) => void;
18+
onmessage: (event: any) => void;
19+
onopen: (event: any) => void;
20+
readyState: number;
21+
22+
close(): void;
23+
send(buffer: any): void;
24+
}

libraries/botframework-streaming/src/interfaces/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Licensed under the MIT License.
77
*/
88

9+
export * from './IBrowserFileReader';
10+
export * from './IBrowserWebSocket';
911
export * from './INodeBuffer';
1012
export * from './INodeIncomingMessage';
1113
export * from './INodeSocket';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @module botframework-streaming
3+
*/
4+
/**
5+
* Copyright (c) Microsoft Corporation. All rights reserved.
6+
* Licensed under the MIT License.
7+
*/
8+
9+
export const doesGlobalFileReaderExist = new Function('try {return typeof FileReader !== "undefined" && FileReader !== null;}catch(e){ return false;}');
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @module botframework-streaming
3+
*/
4+
/**
5+
* Copyright (c) Microsoft Corporation. All rights reserved.
6+
* Licensed under the MIT License.
7+
*/
8+
9+
export const doesGlobalWebSocketExist = new Function('try {return typeof WebSocket !== "undefined" && WebSocket !== null;}catch(e){ return false;}');

libraries/botframework-streaming/src/utilities/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66
* Licensed under the MIT License.
77
*/
88

9+
export * from './doesGlobalFileReaderExist';
10+
export * from './doesGlobalWebSocketExist';
911
export * from './protocol-base';

libraries/botframework-streaming/src/webSocket/browserWebSocket.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,35 @@
55
* Copyright (c) Microsoft Corporation. All rights reserved.
66
* Licensed under the MIT License.
77
*/
8-
import { ISocket } from '../interfaces/ISocket';
8+
import { IBrowserFileReader, IBrowserWebSocket, ISocket } from '../interfaces';
9+
import { doesGlobalFileReaderExist, doesGlobalWebSocketExist } from '../utilities';
10+
11+
const createWebSocket = function(url: string): IBrowserWebSocket {
12+
if (!url) {
13+
throw new TypeError('Unable to create WebSocket without url.');
14+
}
15+
if (doesGlobalWebSocketExist()) {
16+
return new Function(`return new WebSocket('${ url }');`)();
17+
}
18+
throw new ReferenceError('Unable to find global.WebSocket which is required for constructing a BrowserWebSocket.');
19+
};
20+
21+
const createFileReader = function(): IBrowserFileReader {
22+
if (doesGlobalFileReaderExist()) {
23+
return new Function(`return new FileReader();`)();
24+
}
25+
throw new ReferenceError('Unable to find global.FileReader. Unable to create FileReader for BrowserWebSocket.');
26+
};
927

1028
export class BrowserWebSocket implements ISocket {
11-
private webSocket: WebSocket;
29+
private webSocket: IBrowserWebSocket;
1230

1331
/**
1432
* Creates a new instance of the [BrowserWebSocket](xref:botframework-streaming.BrowserWebSocket) class.
1533
*
1634
* @param socket The socket object to build this connection on.
1735
*/
18-
public constructor(socket?: WebSocket) {
36+
public constructor(socket?: IBrowserWebSocket) {
1937
if (socket) {
2038
this.webSocket = socket;
2139
}
@@ -31,7 +49,7 @@ export class BrowserWebSocket implements ISocket {
3149
let rejector;
3250

3351
if (!this.webSocket) {
34-
this.webSocket = new WebSocket(serverAddress);
52+
this.webSocket = createWebSocket(serverAddress);
3553
}
3654

3755
this.webSocket.onerror = (e): void => {
@@ -79,11 +97,11 @@ export class BrowserWebSocket implements ISocket {
7997
const bufferKey: string = 'buffer';
8098
let packets = [];
8199
this.webSocket.onmessage = (evt): void => {
82-
let fileReader = new FileReader();
100+
let fileReader = createFileReader();
83101
let queueEntry = {buffer: null};
84102
packets.push(queueEntry);
85103
fileReader.onload = (e): void => {
86-
let t: FileReader = e.target as FileReader;
104+
let t = e.target as IBrowserFileReader;
87105
queueEntry[bufferKey] = t.result;
88106
if (packets[0] === queueEntry) {
89107
while(0 < packets.length && packets[0][bufferKey]) {

libraries/botframework-streaming/src/webSocket/webSocketClient.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from '../payloadTransport';
1717
import { BrowserWebSocket } from './browserWebSocket';
1818
import { NodeWebSocket } from './nodeWebSocket';
19+
import { doesGlobalWebSocketExist } from '../utilities';
1920
import { WebSocketTransport } from './webSocketTransport';
2021
import { IStreamingTransportClient, IReceiveResponse } from '../interfaces';
2122

@@ -59,7 +60,7 @@ export class WebSocketClient implements IStreamingTransportClient {
5960
* @returns A promise that will not resolve until the client stops listening for incoming messages.
6061
*/
6162
public async connect(): Promise<void> {
62-
if (typeof WebSocket !== 'undefined') {
63+
if (doesGlobalWebSocketExist()) {
6364
const ws = new BrowserWebSocket();
6465
await ws.connect(this._url);
6566
const transport = new WebSocketTransport(ws);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const { doesGlobalFileReaderExist, doesGlobalWebSocketExist } = require('../lib/utilities');
2+
const chai = require('chai');
3+
const expect = chai.expect;
4+
5+
describe('Internal Utilities', () => {
6+
it('doesGlobalWebSocketExist() should return true if global.WebSocket is truthy', () => {
7+
global.WebSocket = {};
8+
try {
9+
expect(doesGlobalWebSocketExist()).to.be.true;
10+
} finally {
11+
global.WebSocket = undefined;
12+
}
13+
});
14+
15+
it('doesGlobalWebSocketExist() should return false if global.WebSocket is null or undefined', () => {
16+
expect(doesGlobalWebSocketExist()).to.be.false;
17+
18+
global.WebSocket = null;
19+
try {
20+
expect(doesGlobalWebSocketExist()).to.be.false;
21+
} finally {
22+
global.WebSocket = undefined;
23+
}
24+
});
25+
26+
it('doesGlobalFileReaderExist() should return true if global.FileReader is truthy', () => {
27+
global.FileReader = {};
28+
try {
29+
expect(doesGlobalFileReaderExist()).to.be.true;
30+
} finally {
31+
global.FileReader = undefined;
32+
}
33+
});
34+
35+
it('doesGlobalFileReaderExist() should return false if global.FileReader is null or undefined', () => {
36+
expect(doesGlobalFileReaderExist()).to.be.false;
37+
38+
global.FileReader = null;
39+
try {
40+
expect(doesGlobalFileReaderExist()).to.be.false;
41+
} finally {
42+
global.FileReader = undefined;
43+
}
44+
});
45+
});

libraries/botframework-streaming/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"compilerOptions": {
33
"target": "es6",
4-
"lib": ["es2015", "dom"],
4+
"lib": ["es2015"],
55
"module": "commonjs",
66
"declaration": true,
77
"sourceMap": true,

0 commit comments

Comments
 (0)