unit tests, and some cleaning up

This commit is contained in:
Josh Burman
2019-03-14 10:14:42 -04:00
parent 501a14d713
commit 21f77fa4c3
134 changed files with 16787 additions and 359 deletions

21
node_modules/mock-socket/LICENSE.txt generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017 Travis Hoover
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

232
node_modules/mock-socket/README.md generated vendored Normal file
View File

@ -0,0 +1,232 @@
<p align="center">
<img width=600 src="http://imgur.com/Xt9X83M.png">
</p>
<p align="center">
Javascript mocking library for <a href="https://developer.mozilla.org/en-US/docs/WebSockets">websockets</a> and <a href="http://socket.io/">socket.io</a>
</p>
<p align="center">
<a href="https://travis-ci.org/thoov/mock-socket">
<img src="https://img.shields.io/travis/thoov/mock-socket.svg?style=for-the-badge" alt="Build Status">
</a>
<a href="https://github.com/thoov/mock-socket/blob/master/LICENSE.txt">
<img src="https://img.shields.io/github/license/thoov/mock-socket.svg?style=for-the-badge" alt="Code Coverage">
</a>
<a href="https://www.npmjs.com/package/mock-socket">
<img src="https://img.shields.io/npm/v/mock-socket.svg?style=for-the-badge" alt="NPM Version">
</a>
</p>
## Contents
- [Installation](#installation)
- [Basic Usage](#usage)
- [Advanced Usage](#advanced-usage)
- [Typescript Support](#typescript-support)
- [Socket.IO](#socket-io)
- [Contributing](#contributing)
- [Feedback](#feedback)
## Installation
```shell
npm install mock-socket
```
```js
import { WebSocket, Server } from 'mock-socket';
```
## Usage
```js
import test from 'ava';
import { Server } from 'mock-socket';
class ChatApp {
constructor(url) {
this.messages = [];
this.connection = new WebSocket(url);
this.connection.onmessage = (event) => {
this.messages.push(event.data);
};
}
sendMessage(message) {
this.connection.send(message);
}
}
test.cb('that chat app can be mocked', t => {
const fakeURL = 'ws://localhost:8080';
const mockServer = new Server(fakeURL);
mockServer.on('connection', socket => {
socket.on('message', data => {
t.is(data, 'test message from app', 'we have intercepted the message and can assert on it');
socket.send('test message from mock server');
});
});
const app = new ChatApp(fakeURL);
app.sendMessage('test message from app'); // NOTE: this line creates a micro task
// NOTE: this timeout is for creating another micro task that will happen after the above one
setTimeout(() => {
t.is(app.messages.length, 1);
t.is(app.messages[0], 'test message from mock server', 'we have subbed our websocket backend');
mockServer.stop(t.done);
}, 100);
});
```
## Advanced Usage
### Stubbing the "global"
```js
import { WebSocket, Server } from 'mock-socket';
/*
* By default the global WebSocket object is stubbed out. However,
* if you need to stub something else out you can like so:
*/
window.WebSocket = WebSocket; // Here we stub out the window object
```
### Server Methods
```js
const mockServer = new Server('ws://localhost:8080');
mockServer.on('connection', socket => {
socket.on('message', () => {});
socket.on('close', () => {});
socket.send('message');
socket.close();
});
mockServer.clients() // array of all connected clients
mockServer.emit('room', 'message');
mockServer.stop(optionalCallback);
```
## Typescript Support
A [declaration file](https://github.com/thoov/mock-socket/blob/master/index.d.ts) is included by default. If you notice any issues with the types please create an issue or a PR!
## Socket IO
[Socket.IO](https://socket.io/) has **limited support**. Below is a similar example to the one above but modified to show off socket.io support.
```js
import test from 'ava';
import { SocketIO, Server } from 'mock-socket';
class ChatApp {
constructor(url) {
this.messages = [];
this.connection = new io(url);
this.connection.on('chat-message', data => {
this.messages.push(event.data);
};
}
sendMessage(message) {
this.connection.emit('chat-message', message);
}
}
test.cb('that socket.io works', t => {
const fakeURL = 'ws://localhost:8080';
const mockServer = new Server(fakeURL);
window.io = SocketIO;
mockServer.on('connection', socket => {
socket.on('chat-message', data => {
t.is(data, 'test message from app', 'we have intercepted the message and can assert on it');
socket.emit('chat-message', 'test message from mock server');
});
});
const app = new ChatApp(fakeURL);
app.sendMessage('test message from app');
setTimeout(() => {
t.is(app.messages.length, 1);
t.is(app.messages[0], 'test message from mock server', 'we have subbed our websocket backend');
mockServer.stop(t.done);
}, 100);
});
```
## Contributing
The easiest way to work on the project is to clone the repo down via:
```shell
git clone git@github.com:thoov/mock-socket.git
cd mock-socket
yarn install
```
Then to create a local build via:
```shell
yarn build
```
Then create a local npm link via:
```shell
yarn link
```
At this point you can create other projects / apps locally and reference this local build via:
```shell
yarn link mock-socket
```
from within your other projects folder. Make sure that after any changes you run `yarn build`!
### Tests
This project uses [ava.js](https://github.com/avajs/ava) as its test framework. Tests are located in /tests. To run tests:
```shell
yarn test
```
### Linting
This project uses eslint and a rules set from [airbnb's javascript style guides](https://github.com/airbnb/javascript). To run linting:
```shell
yarn lint
```
### Formatting
This project uses [prettier](https://github.com/prettier/prettier). To run the formatting:
```shell
yarn format
```
### Code Coverage
Code coverage reports are created in /coverage after all of the tests have successfully passed. To run the coverage:
```shell
yarn test:coverage
```
## Feedback
If you have any feedback, encounter any bugs, or just have a question, please feel free to create a [github issue](https://github.com/thoov/mock-socket/issues/new) or send me a tweet at [@thoov](https://twitter.com/thoov).

1928
node_modules/mock-socket/dist/mock-socket.amd.js generated vendored Normal file

File diff suppressed because one or more lines are too long

1926
node_modules/mock-socket/dist/mock-socket.cjs.js generated vendored Normal file

File diff suppressed because one or more lines are too long

1920
node_modules/mock-socket/dist/mock-socket.es.js generated vendored Normal file

File diff suppressed because one or more lines are too long

1932
node_modules/mock-socket/dist/mock-socket.js generated vendored Normal file

File diff suppressed because one or more lines are too long

84
node_modules/mock-socket/index.d.ts generated vendored Normal file
View File

@ -0,0 +1,84 @@
// Type definitions for Mock Socket 8.X+
// Project: Mock Socket
// Definitions by: Travis Hoover <https://github.com/thoov/mock-socket>
declare module 'mock-socket' {
class EventTarget {
listeners: any;
addEventListener(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void;
dispatchEvent(evt: Event): boolean;
removeEventListener(type: string, listener?: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;
}
//
// https://html.spec.whatwg.org/multipage/web-sockets.html#websocket
//
class WebSocket extends EventTarget {
constructor(url?: string, protocols?: string|string[]);
static readonly CONNECTING: 0;
static readonly OPEN: 1;
static readonly CLOSING: 2;
static readonly CLOSED: 3;
readonly url: string;
readonly CONNECTING: 0;
readonly OPEN: 1;
readonly CLOSING: 2;
readonly CLOSED: 3;
readonly readyState: number;
readonly bufferedAmount: number;
onopen: EventHandlerNonNull;
onerror: EventHandlerNonNull;
onclose: EventHandlerNonNull;
readonly extensions: string;
readonly protocol: string;
close(code?: number, reason?: string): void;
onmessage: EventHandlerNonNull;
binaryType: BinaryType;
send(data: string | Blob | ArrayBuffer | ArrayBufferView): void;
}
class Server extends EventTarget {
constructor(url: string, options?: ServerOptions);
readonly options?: ServerOptions;
start(): void;
stop(callback?: () => void): void;
on(type: string, callback: (socket: WebSocket) => void): void;
close(options?: CloseOptions): void;
emit(event: string, data: any, options?: EmitOptions): void;
clients(): WebSocket[];
to(room: any, broadcaster: any, broadcastList?: object): ToReturnObject;
in(any: any): ToReturnObject;
simulate(event: Event): void;
public of(url: string): Server;
}
interface CloseOptions {
code: number;
reason: string;
wasClean: boolean;
}
interface EmitOptions {
websockets: WebSocket[];
}
interface ToReturnObject {
to: (chainedRoom: any, chainedBroadcaster: any) => ToReturnObject;
emit(event: Event, data: any): void;
}
interface ServerOptions {
verifyClient: () => any;
selectProtocol: () => any;
}
}

108
node_modules/mock-socket/package.json generated vendored Normal file
View File

@ -0,0 +1,108 @@
{
"_from": "mock-socket",
"_id": "mock-socket@8.0.5",
"_inBundle": false,
"_integrity": "sha512-dE2EbcxJKQCeYLZSsI7BAiMZCe/bHbJ2LHb5aGwUuDmfoOINEJ8QI6qYJ85NHsSNkNa90F3s6onZcmt/+MppFA==",
"_location": "/mock-socket",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "mock-socket",
"name": "mock-socket",
"escapedName": "mock-socket",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#DEV:/",
"#USER"
],
"_resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-8.0.5.tgz",
"_shasum": "4ce8909601b2bcdf5f7680f35c2f7b34beb2afc4",
"_spec": "mock-socket",
"_where": "/Users/josh.burman/Projects/braid",
"author": {
"name": "Travis Hoover"
},
"ava": {
"files": [
"tests/**/*.test.js"
],
"require": [
"babel-register",
"babel-polyfill"
],
"babel": "inherit"
},
"bugs": {
"url": "https://github.com/thoov/mock-socket/issues"
},
"bundleDependencies": false,
"dependencies": {
"url-parse": "^1.2.0"
},
"deprecated": false,
"description": "Javascript mocking library for websockets and socket.io",
"devDependencies": {
"ava": "^0.19.1",
"babel-core": "^6.24.1",
"babel-loader": "^7.0.0",
"babel-polyfill": "^6.23.0",
"babel-preset-latest": "^6.24.1",
"cross-env": "^5.0.0",
"eslint": "^3.19.0",
"eslint-config-airbnb-base": "^11.2.0",
"eslint-plugin-import": "^2.0.1",
"husky": "^0.13.3",
"jsdom": "^11.5.1",
"lint-staged": "^3.4.1",
"nyc": "^10.3.2",
"prettier": "^1.3.1",
"rollup": "^0.41.6",
"rollup-plugin-buble": "^0.15.0",
"rollup-plugin-commonjs": "^8.2.6",
"rollup-plugin-node-resolve": "^3.0.0",
"systemjs": "^0.20.12",
"typescript": "^2.9.2",
"typescript-eslint-parser": "^16.0.1"
},
"directories": {
"test": "tests"
},
"engines": {
"node": ">= 6"
},
"homepage": "https://github.com/thoov/mock-socket",
"keywords": [
"websockets",
"mock",
"mocksocket",
"sockets"
],
"license": "MIT",
"lint-staged": {
"*.js": [
"format",
"lint",
"git add"
]
},
"main": "./dist/mock-socket",
"name": "mock-socket",
"repository": {
"type": "git",
"url": "git+https://github.com/thoov/mock-socket.git"
},
"scripts": {
"build": "rm -rf dist && rollup -c rollup.config.js",
"format": "prettier --print-width 120 --single-quote --write '{src,tests}/**/*.js'",
"lint": "eslint src tests",
"precommit": "lint-staged",
"prepublishOnly": "yarn build",
"test": "cross-env NODE_ENV=test ava --serial --verbose",
"test:coverage": "cross-env NODE_ENV=test nyc ava --serial"
},
"version": "8.0.5"
}

57
node_modules/mock-socket/src/algorithms/close.js generated vendored Normal file
View File

@ -0,0 +1,57 @@
import WebSocket from '../websocket';
import delay from '../helpers/delay';
import networkBridge from '../network-bridge';
import { createCloseEvent, createEvent } from '../event/factory';
export function closeWebSocketConnection(context, code, reason) {
context.readyState = WebSocket.CLOSING;
const server = networkBridge.serverLookup(context.url);
const closeEvent = createCloseEvent({
type: 'close',
target: context,
code,
reason
});
delay(() => {
networkBridge.removeWebSocket(context, context.url);
context.readyState = WebSocket.CLOSED;
context.dispatchEvent(closeEvent);
if (server) {
server.dispatchEvent(closeEvent, server);
}
}, context);
}
export function failWebSocketConnection(context, code, reason) {
context.readyState = WebSocket.CLOSING;
const server = networkBridge.serverLookup(context.url);
const closeEvent = createCloseEvent({
type: 'close',
target: context,
code,
reason,
wasClean: false
});
const errorEvent = createEvent({
type: 'error',
target: context
});
delay(() => {
networkBridge.removeWebSocket(context, context.url);
context.readyState = WebSocket.CLOSED;
context.dispatchEvent(errorEvent);
context.dispatchEvent(closeEvent);
if (server) {
server.dispatchEvent(closeEvent, server);
}
}, context);
}

29
node_modules/mock-socket/src/constants.js generated vendored Normal file
View File

@ -0,0 +1,29 @@
/*
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
*/
export const CLOSE_CODES = {
CLOSE_NORMAL: 1000,
CLOSE_GOING_AWAY: 1001,
CLOSE_PROTOCOL_ERROR: 1002,
CLOSE_UNSUPPORTED: 1003,
CLOSE_NO_STATUS: 1005,
CLOSE_ABNORMAL: 1006,
UNSUPPORTED_DATA: 1007,
POLICY_VIOLATION: 1008,
CLOSE_TOO_LARGE: 1009,
MISSING_EXTENSION: 1010,
INTERNAL_ERROR: 1011,
SERVICE_RESTART: 1012,
TRY_AGAIN_LATER: 1013,
TLS_HANDSHAKE: 1015
};
export const ERROR_PREFIX = {
CONSTRUCTOR_ERROR: "Failed to construct 'WebSocket':",
CLOSE_ERROR: "Failed to execute 'close' on 'WebSocket':",
EVENT: {
CONSTRUCT: "Failed to construct 'Event':",
MESSAGE: "Failed to construct 'MessageEvent':",
CLOSE: "Failed to construct 'CloseEvent':"
}
};

34
node_modules/mock-socket/src/event/close.js generated vendored Normal file
View File

@ -0,0 +1,34 @@
import EventPrototype from './prototype';
import { ERROR_PREFIX } from '../constants';
export default class CloseEvent extends EventPrototype {
constructor(type, eventInitConfig = {}) {
super();
if (!type) {
throw new TypeError(`${ERROR_PREFIX.EVENT.CLOSE} 1 argument required, but only 0 present.`);
}
if (typeof eventInitConfig !== 'object') {
throw new TypeError(`${ERROR_PREFIX.EVENT.CLOSE} parameter 2 ('eventInitDict') is not an object`);
}
const { bubbles, cancelable, code, reason, wasClean } = eventInitConfig;
this.type = `${type}`;
this.timeStamp = Date.now();
this.target = null;
this.srcElement = null;
this.returnValue = true;
this.isTrusted = false;
this.eventPhase = 0;
this.defaultPrevented = false;
this.currentTarget = null;
this.cancelable = cancelable ? Boolean(cancelable) : false;
this.cancelBubble = false;
this.bubbles = bubbles ? Boolean(bubbles) : false;
this.code = typeof code === 'number' ? parseInt(code, 10) : 0;
this.reason = `${reason || ''}`;
this.wasClean = wasClean ? Boolean(wasClean) : false;
}
}

31
node_modules/mock-socket/src/event/event.js generated vendored Normal file
View File

@ -0,0 +1,31 @@
import EventPrototype from './prototype';
import { ERROR_PREFIX } from '../constants';
export default class Event extends EventPrototype {
constructor(type, eventInitConfig = {}) {
super();
if (!type) {
throw new TypeError(`${ERROR_PREFIX.EVENT_ERROR} 1 argument required, but only 0 present.`);
}
if (typeof eventInitConfig !== 'object') {
throw new TypeError(`${ERROR_PREFIX.EVENT_ERROR} parameter 2 ('eventInitDict') is not an object.`);
}
const { bubbles, cancelable } = eventInitConfig;
this.type = `${type}`;
this.timeStamp = Date.now();
this.target = null;
this.srcElement = null;
this.returnValue = true;
this.isTrusted = false;
this.eventPhase = 0;
this.defaultPrevented = false;
this.currentTarget = null;
this.cancelable = cancelable ? Boolean(cancelable) : false;
this.canncelBubble = false;
this.bubbles = bubbles ? Boolean(bubbles) : false;
}
}

75
node_modules/mock-socket/src/event/factory.js generated vendored Normal file
View File

@ -0,0 +1,75 @@
import Event from './event';
import MessageEvent from './message';
import CloseEvent from './close';
/*
* Creates an Event object and extends it to allow full modification of
* its properties.
*
* @param {object} config - within config you will need to pass type and optionally target
*/
function createEvent(config) {
const { type, target } = config;
const eventObject = new Event(type);
if (target) {
eventObject.target = target;
eventObject.srcElement = target;
eventObject.currentTarget = target;
}
return eventObject;
}
/*
* Creates a MessageEvent object and extends it to allow full modification of
* its properties.
*
* @param {object} config - within config: type, origin, data and optionally target
*/
function createMessageEvent(config) {
const { type, origin, data, target } = config;
const messageEvent = new MessageEvent(type, {
data,
origin
});
if (target) {
messageEvent.target = target;
messageEvent.srcElement = target;
messageEvent.currentTarget = target;
}
return messageEvent;
}
/*
* Creates a CloseEvent object and extends it to allow full modification of
* its properties.
*
* @param {object} config - within config: type and optionally target, code, and reason
*/
function createCloseEvent(config) {
const { code, reason, type, target } = config;
let { wasClean } = config;
if (!wasClean) {
wasClean = code === 1000;
}
const closeEvent = new CloseEvent(type, {
code,
reason,
wasClean
});
if (target) {
closeEvent.target = target;
closeEvent.srcElement = target;
closeEvent.currentTarget = target;
}
return closeEvent;
}
export { createEvent, createMessageEvent, createCloseEvent };

35
node_modules/mock-socket/src/event/message.js generated vendored Normal file
View File

@ -0,0 +1,35 @@
import EventPrototype from './prototype';
import { ERROR_PREFIX } from '../constants';
export default class MessageEvent extends EventPrototype {
constructor(type, eventInitConfig = {}) {
super();
if (!type) {
throw new TypeError(`${ERROR_PREFIX.EVENT.MESSAGE} 1 argument required, but only 0 present.`);
}
if (typeof eventInitConfig !== 'object') {
throw new TypeError(`${ERROR_PREFIX.EVENT.MESSAGE} parameter 2 ('eventInitDict') is not an object`);
}
const { bubbles, cancelable, data, origin, lastEventId, ports } = eventInitConfig;
this.type = `${type}`;
this.timeStamp = Date.now();
this.target = null;
this.srcElement = null;
this.returnValue = true;
this.isTrusted = false;
this.eventPhase = 0;
this.defaultPrevented = false;
this.currentTarget = null;
this.cancelable = cancelable ? Boolean(cancelable) : false;
this.canncelBubble = false;
this.bubbles = bubbles ? Boolean(bubbles) : false;
this.origin = `${origin}`;
this.ports = typeof ports === 'undefined' ? null : ports;
this.data = typeof data === 'undefined' ? null : data;
this.lastEventId = `${lastEventId || ''}`;
}
}

13
node_modules/mock-socket/src/event/prototype.js generated vendored Normal file
View File

@ -0,0 +1,13 @@
export default class EventPrototype {
// Noops
stopPropagation() {}
stopImmediatePropagation() {}
// if no arguments are passed then the type is set to "undefined" on
// chrome and safari.
initEvent(type = 'undefined', bubbles = false, cancelable = false) {
this.type = `${type}`;
this.bubbles = Boolean(bubbles);
this.cancelable = Boolean(cancelable);
}
}

73
node_modules/mock-socket/src/event/target.js generated vendored Normal file
View File

@ -0,0 +1,73 @@
import { reject, filter } from '../helpers/array-helpers';
/*
* EventTarget is an interface implemented by objects that can
* receive events and may have listeners for them.
*
* https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
*/
class EventTarget {
constructor() {
this.listeners = {};
}
/*
* Ties a listener function to an event type which can later be invoked via the
* dispatchEvent method.
*
* @param {string} type - the type of event (ie: 'open', 'message', etc.)
* @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type
* @param {boolean} useCapture - N/A TODO: implement useCapture functionality
*/
addEventListener(type, listener /* , useCapture */) {
if (typeof listener === 'function') {
if (!Array.isArray(this.listeners[type])) {
this.listeners[type] = [];
}
// Only add the same function once
if (filter(this.listeners[type], item => item === listener).length === 0) {
this.listeners[type].push(listener);
}
}
}
/*
* Removes the listener so it will no longer be invoked via the dispatchEvent method.
*
* @param {string} type - the type of event (ie: 'open', 'message', etc.)
* @param {function} listener - the callback function to invoke whenever an event is dispatched matching the given type
* @param {boolean} useCapture - N/A TODO: implement useCapture functionality
*/
removeEventListener(type, removingListener /* , useCapture */) {
const arrayOfListeners = this.listeners[type];
this.listeners[type] = reject(arrayOfListeners, listener => listener === removingListener);
}
/*
* Invokes all listener functions that are listening to the given event.type property. Each
* listener will be passed the event as the first argument.
*
* @param {object} event - event object which will be passed to all listeners of the event.type property
*/
dispatchEvent(event, ...customArguments) {
const eventName = event.type;
const listeners = this.listeners[eventName];
if (!Array.isArray(listeners)) {
return false;
}
listeners.forEach(listener => {
if (customArguments.length > 0) {
listener.apply(this, customArguments);
} else {
listener.call(this, event);
}
});
return true;
}
}
export default EventTarget;

21
node_modules/mock-socket/src/helpers/array-helpers.js generated vendored Normal file
View File

@ -0,0 +1,21 @@
export function reject(array, callback) {
const results = [];
array.forEach(itemInArray => {
if (!callback(itemInArray)) {
results.push(itemInArray);
}
});
return results;
}
export function filter(array, callback) {
const results = [];
array.forEach(itemInArray => {
if (callback(itemInArray)) {
results.push(itemInArray);
}
});
return results;
}

5
node_modules/mock-socket/src/helpers/byte-length.js generated vendored Normal file
View File

@ -0,0 +1,5 @@
export default function lengthInUtf8Bytes(str) {
// Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence.
const m = encodeURIComponent(str).match(/%[89ABab]/g);
return str.length + (m ? m.length : 0);
}

5
node_modules/mock-socket/src/helpers/dedupe.js generated vendored Normal file
View File

@ -0,0 +1,5 @@
export default arr =>
arr.reduce((deduped, b) => {
if (deduped.indexOf(b) > -1) return deduped;
return deduped.concat(b);
}, []);

11
node_modules/mock-socket/src/helpers/delay.js generated vendored Normal file
View File

@ -0,0 +1,11 @@
/*
* This delay allows the thread to finish assigning its on* methods
* before invoking the delay callback. This is purely a timing hack.
* http://geekabyte.blogspot.com/2014/01/javascript-effect-of-setting-settimeout.html
*
* @param {callback: function} the callback which will be invoked after the timeout
* @parma {context: object} the context in which to invoke the function
*/
export default function delay(callback, context) {
setTimeout(timeoutContext => callback.call(timeoutContext), 4, context);
}

View File

@ -0,0 +1,7 @@
export default function retrieveGlobalObject() {
if (typeof window !== 'undefined') {
return window;
}
return typeof process === 'object' && typeof require === 'function' && typeof global === 'object' ? global : this;
}

7
node_modules/mock-socket/src/helpers/logger.js generated vendored Normal file
View File

@ -0,0 +1,7 @@
export default function log(method, message) {
/* eslint-disable no-console */
if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'test') {
console[method].call(null, message);
}
/* eslint-enable no-console */
}

View File

@ -0,0 +1,7 @@
export default function normalizeSendData(data) {
if (Object.prototype.toString.call(data) !== '[object Blob]' && !(data instanceof ArrayBuffer)) {
data = String(data);
}
return data;
}

View File

@ -0,0 +1,24 @@
import { ERROR_PREFIX } from '../constants';
export default function protocolVerification(protocols = []) {
if (!Array.isArray(protocols) && typeof protocols !== 'string') {
throw new SyntaxError(`${ERROR_PREFIX.CONSTRUCTOR_ERROR} The subprotocol '${protocols.toString()}' is invalid.`);
}
if (typeof protocols === 'string') {
protocols = [protocols];
}
const uniq = protocols.map(p => ({ count: 1, protocol: p })).reduce((a, b) => {
a[b.protocol] = (a[b.protocol] || 0) + b.count;
return a;
}, {});
const duplicates = Object.keys(uniq).filter(a => uniq[a] > 1);
if (duplicates.length > 0) {
throw new SyntaxError(`${ERROR_PREFIX.CONSTRUCTOR_ERROR} The subprotocol '${duplicates[0]}' is duplicated.`);
}
return protocols;
}

45
node_modules/mock-socket/src/helpers/proxy-factory.js generated vendored Normal file
View File

@ -0,0 +1,45 @@
import { CLOSE_CODES } from '../constants';
import { closeWebSocketConnection } from '../algorithms/close';
import normalizeSendData from './normalize-send';
import { createMessageEvent } from '../event/factory';
export default function proxyFactory(target) {
const handler = {
get(obj, prop) {
if (prop === 'close') {
return function close(options = {}) {
const code = options.code || CLOSE_CODES.CLOSE_NORMAL;
const reason = options.reason || '';
closeWebSocketConnection(target, code, reason);
};
}
if (prop === 'send') {
return function send(data) {
data = normalizeSendData(data);
target.dispatchEvent(
createMessageEvent({
type: 'message',
data,
origin: this.url,
target
})
);
};
}
if (prop === 'on') {
return function onWrapper(type, cb) {
target.addEventListener(`server::${type}`, cb);
};
}
return obj[prop];
}
};
const proxy = new Proxy(target, handler);
return proxy;
}

View File

@ -0,0 +1,37 @@
import URL from 'url-parse';
import { ERROR_PREFIX } from '../constants';
export default function urlVerification(url) {
const urlRecord = new URL(url);
const { pathname, protocol, hash } = urlRecord;
if (!url) {
throw new TypeError(`${ERROR_PREFIX.CONSTRUCTOR_ERROR} 1 argument required, but only 0 present.`);
}
if (!pathname) {
urlRecord.pathname = '/';
}
if (protocol === '') {
throw new SyntaxError(`${ERROR_PREFIX.CONSTRUCTOR_ERROR} The URL '${urlRecord.toString()}' is invalid.`);
}
if (protocol !== 'ws:' && protocol !== 'wss:') {
throw new SyntaxError(
`${ERROR_PREFIX.CONSTRUCTOR_ERROR} The URL's scheme must be either 'ws' or 'wss'. '${protocol}' is not allowed.`
);
}
if (hash !== '') {
/* eslint-disable max-len */
throw new SyntaxError(
`${
ERROR_PREFIX.CONSTRUCTOR_ERROR
} The URL contains a fragment identifier ('${hash}'). Fragment identifiers are not allowed in WebSocket URLs.`
);
/* eslint-enable max-len */
}
return urlRecord.toString();
}

7
node_modules/mock-socket/src/index.js generated vendored Normal file
View File

@ -0,0 +1,7 @@
import MockServer from './server';
import MockSocketIO from './socket-io';
import MockWebSocket from './websocket';
export const Server = MockServer;
export const WebSocket = MockWebSocket;
export const SocketIO = MockSocketIO;

135
node_modules/mock-socket/src/network-bridge.js generated vendored Normal file
View File

@ -0,0 +1,135 @@
import { reject } from './helpers/array-helpers';
/*
* The network bridge is a way for the mock websocket object to 'communicate' with
* all available servers. This is a singleton object so it is important that you
* clean up urlMap whenever you are finished.
*/
class NetworkBridge {
constructor() {
this.urlMap = {};
}
/*
* Attaches a websocket object to the urlMap hash so that it can find the server
* it is connected to and the server in turn can find it.
*
* @param {object} websocket - websocket object to add to the urlMap hash
* @param {string} url
*/
attachWebSocket(websocket, url) {
const connectionLookup = this.urlMap[url];
if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) === -1) {
connectionLookup.websockets.push(websocket);
return connectionLookup.server;
}
}
/*
* Attaches a websocket to a room
*/
addMembershipToRoom(websocket, room) {
const connectionLookup = this.urlMap[websocket.url];
if (connectionLookup && connectionLookup.server && connectionLookup.websockets.indexOf(websocket) !== -1) {
if (!connectionLookup.roomMemberships[room]) {
connectionLookup.roomMemberships[room] = [];
}
connectionLookup.roomMemberships[room].push(websocket);
}
}
/*
* Attaches a server object to the urlMap hash so that it can find a websockets
* which are connected to it and so that websockets can in turn can find it.
*
* @param {object} server - server object to add to the urlMap hash
* @param {string} url
*/
attachServer(server, url) {
const connectionLookup = this.urlMap[url];
if (!connectionLookup) {
this.urlMap[url] = {
server,
websockets: [],
roomMemberships: {}
};
return server;
}
}
/*
* Finds the server which is 'running' on the given url.
*
* @param {string} url - the url to use to find which server is running on it
*/
serverLookup(url) {
const connectionLookup = this.urlMap[url];
if (connectionLookup) {
return connectionLookup.server;
}
}
/*
* Finds all websockets which is 'listening' on the given url.
*
* @param {string} url - the url to use to find all websockets which are associated with it
* @param {string} room - if a room is provided, will only return sockets in this room
* @param {class} broadcaster - socket that is broadcasting and is to be excluded from the lookup
*/
websocketsLookup(url, room, broadcaster) {
let websockets;
const connectionLookup = this.urlMap[url];
websockets = connectionLookup ? connectionLookup.websockets : [];
if (room) {
const members = connectionLookup.roomMemberships[room];
websockets = members || [];
}
return broadcaster ? websockets.filter(websocket => websocket !== broadcaster) : websockets;
}
/*
* Removes the entry associated with the url.
*
* @param {string} url
*/
removeServer(url) {
delete this.urlMap[url];
}
/*
* Removes the individual websocket from the map of associated websockets.
*
* @param {object} websocket - websocket object to remove from the url map
* @param {string} url
*/
removeWebSocket(websocket, url) {
const connectionLookup = this.urlMap[url];
if (connectionLookup) {
connectionLookup.websockets = reject(connectionLookup.websockets, socket => socket === websocket);
}
}
/*
* Removes a websocket from a room
*/
removeMembershipFromRoom(websocket, room) {
const connectionLookup = this.urlMap[websocket.url];
const memberships = connectionLookup.roomMemberships[room];
if (connectionLookup && memberships !== null) {
connectionLookup.roomMemberships[room] = reject(memberships, socket => socket === websocket);
}
}
}
export default new NetworkBridge(); // Note: this is a singleton

217
node_modules/mock-socket/src/server.js generated vendored Normal file
View File

@ -0,0 +1,217 @@
import URL from 'url-parse';
import WebSocket from './websocket';
import dedupe from './helpers/dedupe';
import EventTarget from './event/target';
import { CLOSE_CODES } from './constants';
import networkBridge from './network-bridge';
import globalObject from './helpers/global-object';
import normalizeSendData from './helpers/normalize-send';
import { createEvent, createMessageEvent, createCloseEvent } from './event/factory';
class Server extends EventTarget {
constructor(url, options = {}) {
super();
const urlRecord = new URL(url);
if (!urlRecord.pathname) {
urlRecord.pathname = '/';
}
this.url = urlRecord.toString();
this.originalWebSocket = null;
const server = networkBridge.attachServer(this, this.url);
if (!server) {
this.dispatchEvent(createEvent({ type: 'error' }));
throw new Error('A mock server is already listening on this url');
}
if (typeof options.verifyClient === 'undefined') {
options.verifyClient = null;
}
if (typeof options.selectProtocol === 'undefined') {
options.selectProtocol = null;
}
this.options = options;
this.start();
}
/*
* Attaches the mock websocket object to the global object
*/
start() {
const globalObj = globalObject();
if (globalObj.WebSocket) {
this.originalWebSocket = globalObj.WebSocket;
}
globalObj.WebSocket = WebSocket;
}
/*
* Removes the mock websocket object from the global object
*/
stop(callback = () => {}) {
const globalObj = globalObject();
if (this.originalWebSocket) {
globalObj.WebSocket = this.originalWebSocket;
} else {
delete globalObj.WebSocket;
}
this.originalWebSocket = null;
networkBridge.removeServer(this.url);
if (typeof callback === 'function') {
callback();
}
}
/*
* This is the main function for the mock server to subscribe to the on events.
*
* ie: mockServer.on('connection', function() { console.log('a mock client connected'); });
*
* @param {string} type - The event key to subscribe to. Valid keys are: connection, message, and close.
* @param {function} callback - The callback which should be called when a certain event is fired.
*/
on(type, callback) {
this.addEventListener(type, callback);
}
/*
* Closes the connection and triggers the onclose method of all listening
* websockets. After that it removes itself from the urlMap so another server
* could add itself to the url.
*
* @param {object} options
*/
close(options = {}) {
const { code, reason, wasClean } = options;
const listeners = networkBridge.websocketsLookup(this.url);
// Remove server before notifications to prevent immediate reconnects from
// socket onclose handlers
networkBridge.removeServer(this.url);
listeners.forEach(socket => {
socket.readyState = WebSocket.CLOSE;
socket.dispatchEvent(
createCloseEvent({
type: 'close',
target: socket,
code: code || CLOSE_CODES.CLOSE_NORMAL,
reason: reason || '',
wasClean
})
);
});
this.dispatchEvent(createCloseEvent({ type: 'close' }), this);
}
/*
* Sends a generic message event to all mock clients.
*/
emit(event, data, options = {}) {
let { websockets } = options;
if (!websockets) {
websockets = networkBridge.websocketsLookup(this.url);
}
if (typeof options !== 'object' || arguments.length > 3) {
data = Array.prototype.slice.call(arguments, 1, arguments.length);
data = data.map(item => normalizeSendData(item));
} else {
data = normalizeSendData(data);
}
websockets.forEach(socket => {
if (Array.isArray(data)) {
socket.dispatchEvent(
createMessageEvent({
type: event,
data,
origin: this.url,
target: socket
}),
...data
);
} else {
socket.dispatchEvent(
createMessageEvent({
type: event,
data,
origin: this.url,
target: socket
})
);
}
});
}
/*
* Returns an array of websockets which are listening to this server
* TOOD: this should return a set and not be a method
*/
clients() {
return networkBridge.websocketsLookup(this.url);
}
/*
* Prepares a method to submit an event to members of the room
*
* e.g. server.to('my-room').emit('hi!');
*/
to(room, broadcaster, broadcastList = []) {
const self = this;
const websockets = dedupe(broadcastList.concat(networkBridge.websocketsLookup(this.url, room, broadcaster)));
return {
to: (chainedRoom, chainedBroadcaster) => this.to.call(this, chainedRoom, chainedBroadcaster, websockets),
emit(event, data) {
self.emit(event, data, { websockets });
}
};
}
/*
* Alias for Server.to
*/
in(...args) {
return this.to.apply(null, args);
}
/*
* Simulate an event from the server to the clients. Useful for
* simulating errors.
*/
simulate(event) {
const listeners = networkBridge.websocketsLookup(this.url);
if (event === 'error') {
listeners.forEach(socket => {
socket.readyState = WebSocket.CLOSE;
socket.dispatchEvent(createEvent({ type: 'error' }));
});
}
}
}
/*
* Alternative constructor to support namespaces in socket.io
*
* http://socket.io/docs/rooms-and-namespaces/#custom-namespaces
*/
Server.of = function of(url) {
return new Server(url);
};
export default Server;

279
node_modules/mock-socket/src/socket-io.js generated vendored Normal file
View File

@ -0,0 +1,279 @@
import URL from 'url-parse';
import delay from './helpers/delay';
import EventTarget from './event/target';
import networkBridge from './network-bridge';
import { CLOSE_CODES } from './constants';
import logger from './helpers/logger';
import { createEvent, createMessageEvent, createCloseEvent } from './event/factory';
/*
* The socket-io class is designed to mimick the real API as closely as possible.
*
* http://socket.io/docs/
*/
class SocketIO extends EventTarget {
/*
* @param {string} url
*/
constructor(url = 'socket.io', protocol = '') {
super();
this.binaryType = 'blob';
const urlRecord = new URL(url);
if (!urlRecord.pathname) {
urlRecord.pathname = '/';
}
this.url = urlRecord.toString();
this.readyState = SocketIO.CONNECTING;
this.protocol = '';
if (typeof protocol === 'string' || (typeof protocol === 'object' && protocol !== null)) {
this.protocol = protocol;
} else if (Array.isArray(protocol) && protocol.length > 0) {
this.protocol = protocol[0];
}
const server = networkBridge.attachWebSocket(this, this.url);
/*
* Delay triggering the connection events so they can be defined in time.
*/
delay(function delayCallback() {
if (server) {
this.readyState = SocketIO.OPEN;
server.dispatchEvent(createEvent({ type: 'connection' }), server, this);
server.dispatchEvent(createEvent({ type: 'connect' }), server, this); // alias
this.dispatchEvent(createEvent({ type: 'connect', target: this }));
} else {
this.readyState = SocketIO.CLOSED;
this.dispatchEvent(createEvent({ type: 'error', target: this }));
this.dispatchEvent(
createCloseEvent({
type: 'close',
target: this,
code: CLOSE_CODES.CLOSE_NORMAL
})
);
logger('error', `Socket.io connection to '${this.url}' failed`);
}
}, this);
/**
Add an aliased event listener for close / disconnect
*/
this.addEventListener('close', event => {
this.dispatchEvent(
createCloseEvent({
type: 'disconnect',
target: event.target,
code: event.code
})
);
});
}
/*
* Closes the SocketIO connection or connection attempt, if any.
* If the connection is already CLOSED, this method does nothing.
*/
close() {
if (this.readyState !== SocketIO.OPEN) {
return undefined;
}
const server = networkBridge.serverLookup(this.url);
networkBridge.removeWebSocket(this, this.url);
this.readyState = SocketIO.CLOSED;
this.dispatchEvent(
createCloseEvent({
type: 'close',
target: this,
code: CLOSE_CODES.CLOSE_NORMAL
})
);
if (server) {
server.dispatchEvent(
createCloseEvent({
type: 'disconnect',
target: this,
code: CLOSE_CODES.CLOSE_NORMAL
}),
server
);
}
return this;
}
/*
* Alias for Socket#close
*
* https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L383
*/
disconnect() {
return this.close();
}
/*
* Submits an event to the server with a payload
*/
emit(event, ...data) {
if (this.readyState !== SocketIO.OPEN) {
throw new Error('SocketIO is already in CLOSING or CLOSED state');
}
const messageEvent = createMessageEvent({
type: event,
origin: this.url,
data
});
const server = networkBridge.serverLookup(this.url);
if (server) {
server.dispatchEvent(messageEvent, ...data);
}
return this;
}
/*
* Submits a 'message' event to the server.
*
* Should behave exactly like WebSocket#send
*
* https://github.com/socketio/socket.io-client/blob/master/lib/socket.js#L113
*/
send(data) {
this.emit('message', data);
return this;
}
/*
* For broadcasting events to other connected sockets.
*
* e.g. socket.broadcast.emit('hi!');
* e.g. socket.broadcast.to('my-room').emit('hi!');
*/
get broadcast() {
if (this.readyState !== SocketIO.OPEN) {
throw new Error('SocketIO is already in CLOSING or CLOSED state');
}
const self = this;
const server = networkBridge.serverLookup(this.url);
if (!server) {
throw new Error(`SocketIO can not find a server at the specified URL (${this.url})`);
}
return {
emit(event, data) {
server.emit(event, data, { websockets: networkBridge.websocketsLookup(self.url, null, self) });
return self;
},
to(room) {
return server.to(room, self);
},
in(room) {
return server.in(room, self);
}
};
}
/*
* For registering events to be received from the server
*/
on(type, callback) {
this.addEventListener(type, callback);
return this;
}
/*
* Remove event listener
*
* https://socket.io/docs/client-api/#socket-on-eventname-callback
*/
off(type) {
this.removeEventListener(type);
}
/*
* Join a room on a server
*
* http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving
*/
join(room) {
networkBridge.addMembershipToRoom(this, room);
}
/*
* Get the websocket to leave the room
*
* http://socket.io/docs/rooms-and-namespaces/#joining-and-leaving
*/
leave(room) {
networkBridge.removeMembershipFromRoom(this, room);
}
to(room) {
return this.broadcast.to(room);
}
in() {
return this.to.apply(null, arguments);
}
/*
* Invokes all listener functions that are listening to the given event.type property. Each
* listener will be passed the event as the first argument.
*
* @param {object} event - event object which will be passed to all listeners of the event.type property
*/
dispatchEvent(event, ...customArguments) {
const eventName = event.type;
const listeners = this.listeners[eventName];
if (!Array.isArray(listeners)) {
return false;
}
listeners.forEach(listener => {
if (customArguments.length > 0) {
listener.apply(this, customArguments);
} else {
// Regular WebSockets expect a MessageEvent but Socketio.io just wants raw data
// payload instanceof MessageEvent works, but you can't isntance of NodeEvent
// for now we detect if the output has data defined on it
listener.call(this, event.data ? event.data : event);
}
});
}
}
SocketIO.CONNECTING = 0;
SocketIO.OPEN = 1;
SocketIO.CLOSING = 2;
SocketIO.CLOSED = 3;
/*
* Static constructor methods for the IO Socket
*/
const IO = function ioConstructor(url, protocol) {
return new SocketIO(url, protocol);
};
/*
* Alias the raw IO() constructor
*/
IO.connect = function ioConnect(url, protocol) {
/* eslint-disable new-cap */
return IO(url, protocol);
/* eslint-enable new-cap */
};
export default IO;

191
node_modules/mock-socket/src/websocket.js generated vendored Normal file
View File

@ -0,0 +1,191 @@
import delay from './helpers/delay';
import logger from './helpers/logger';
import EventTarget from './event/target';
import networkBridge from './network-bridge';
import proxyFactory from './helpers/proxy-factory';
import lengthInUtf8Bytes from './helpers/byte-length';
import { CLOSE_CODES, ERROR_PREFIX } from './constants';
import urlVerification from './helpers/url-verification';
import normalizeSendData from './helpers/normalize-send';
import protocolVerification from './helpers/protocol-verification';
import { createEvent, createMessageEvent, createCloseEvent } from './event/factory';
import { closeWebSocketConnection, failWebSocketConnection } from './algorithms/close';
/*
* The main websocket class which is designed to mimick the native WebSocket class as close
* as possible.
*
* https://html.spec.whatwg.org/multipage/web-sockets.html
*/
class WebSocket extends EventTarget {
constructor(url, protocols) {
super();
this.url = urlVerification(url);
protocols = protocolVerification(protocols);
this.protocol = protocols[0] || '';
this.binaryType = 'blob';
this.readyState = WebSocket.CONNECTING;
const server = networkBridge.attachWebSocket(this, this.url);
/*
* This delay is needed so that we dont trigger an event before the callbacks have been
* setup. For example:
*
* var socket = new WebSocket('ws://localhost');
*
* If we dont have the delay then the event would be triggered right here and this is
* before the onopen had a chance to register itself.
*
* socket.onopen = () => { // this would never be called };
*
* and with the delay the event gets triggered here after all of the callbacks have been
* registered :-)
*/
delay(function delayCallback() {
if (server) {
if (
server.options.verifyClient &&
typeof server.options.verifyClient === 'function' &&
!server.options.verifyClient()
) {
this.readyState = WebSocket.CLOSED;
logger(
'error',
`WebSocket connection to '${this.url}' failed: HTTP Authentication failed; no valid credentials available`
);
networkBridge.removeWebSocket(this, this.url);
this.dispatchEvent(createEvent({ type: 'error', target: this }));
this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL }));
} else {
if (server.options.selectProtocol && typeof server.options.selectProtocol === 'function') {
const selectedProtocol = server.options.selectProtocol(protocols);
const isFilled = selectedProtocol !== '';
const isRequested = protocols.indexOf(selectedProtocol) !== -1;
if (isFilled && !isRequested) {
this.readyState = WebSocket.CLOSED;
logger('error', `WebSocket connection to '${this.url}' failed: Invalid Sub-Protocol`);
networkBridge.removeWebSocket(this, this.url);
this.dispatchEvent(createEvent({ type: 'error', target: this }));
this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL }));
return;
}
this.protocol = selectedProtocol;
}
this.readyState = WebSocket.OPEN;
this.dispatchEvent(createEvent({ type: 'open', target: this }));
server.dispatchEvent(createEvent({ type: 'connection' }), proxyFactory(this));
}
} else {
this.readyState = WebSocket.CLOSED;
this.dispatchEvent(createEvent({ type: 'error', target: this }));
this.dispatchEvent(createCloseEvent({ type: 'close', target: this, code: CLOSE_CODES.CLOSE_NORMAL }));
logger('error', `WebSocket connection to '${this.url}' failed`);
}
}, this);
}
get onopen() {
return this.listeners.open;
}
get onmessage() {
return this.listeners.message;
}
get onclose() {
return this.listeners.close;
}
get onerror() {
return this.listeners.error;
}
set onopen(listener) {
delete this.listeners.open;
this.addEventListener('open', listener);
}
set onmessage(listener) {
delete this.listeners.message;
this.addEventListener('message', listener);
}
set onclose(listener) {
delete this.listeners.close;
this.addEventListener('close', listener);
}
set onerror(listener) {
delete this.listeners.error;
this.addEventListener('error', listener);
}
send(data) {
if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) {
throw new Error('WebSocket is already in CLOSING or CLOSED state');
}
// TODO: handle bufferedAmount
const messageEvent = createMessageEvent({
type: 'server::message',
origin: this.url,
data: normalizeSendData(data)
});
const server = networkBridge.serverLookup(this.url);
if (server) {
delay(() => {
this.dispatchEvent(messageEvent, data);
}, server);
}
}
close(code, reason) {
if (code !== undefined) {
if (typeof code !== 'number' || (code !== 1000 && (code < 3000 || code > 4999))) {
throw new TypeError(
`${ERROR_PREFIX.CLOSE_ERROR} The code must be either 1000, or between 3000 and 4999. ${code} is neither.`
);
}
}
if (reason !== undefined) {
const length = lengthInUtf8Bytes(reason);
if (length > 123) {
throw new SyntaxError(`${ERROR_PREFIX.CLOSE_ERROR} The message must not be greater than 123 bytes.`);
}
}
if (this.readyState === WebSocket.CLOSING || this.readyState === WebSocket.CLOSED) {
return;
}
if (this.readyState === WebSocket.CONNECTING) {
failWebSocketConnection(this, code, reason);
} else {
closeWebSocketConnection(this, code, reason);
}
}
}
WebSocket.CONNECTING = 0;
WebSocket.prototype.CONNECTING = WebSocket.CONNECTING;
WebSocket.OPEN = 1;
WebSocket.prototype.OPEN = WebSocket.OPEN;
WebSocket.CLOSING = 2;
WebSocket.prototype.CLOSING = WebSocket.CLOSING;
WebSocket.CLOSED = 3;
WebSocket.prototype.CLOSED = WebSocket.CLOSED;
export default WebSocket;

4687
node_modules/mock-socket/yarn.lock generated vendored Normal file

File diff suppressed because it is too large Load Diff