Skip to content

Commit

Permalink
feat: added webSocket composable
Browse files Browse the repository at this point in the history
  • Loading branch information
Carlos Rodrigues committed Oct 25, 2019
1 parent fb7904f commit 51e92dc
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 9 deletions.
107 changes: 107 additions & 0 deletions __tests__/web/webSocket.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { useWebSocket } from "../../src";
import { WS } from "jest-websocket-mock";
import { watch } from "@vue/composition-api";
import { nextTick } from "../utils";

describe("WebSocket", () => {
const FAKE_URL = `ws://localhost:42`;
let server: WS = undefined as any;

let warnSpy: jest.SpyInstance = undefined as any;
beforeAll(() => {
warnSpy = jest.spyOn(console, "warn").mockImplementation();
});

beforeEach(() => {
server = new WS(FAKE_URL);
warnSpy.mockReset();
});

afterEach(() => {
server!.close();
});

afterAll(()=>{
warnSpy.mockReset();
})

it("should connect to server", async () => {
const { isOpen } = useWebSocket(FAKE_URL);

await server.connected;

expect(isOpen.value).toBe(true);
});

it("should received message", async () => {
const { messageEvent } = useWebSocket(FAKE_URL);
await server.connected;

expect(messageEvent.value).toBeNull();

server.send("test");
expect(messageEvent.value).not.toBeNull();

expect(messageEvent.value).toMatchObject({
data: "test"
});
});

it("should send message", async () => {
const { send } = useWebSocket(FAKE_URL);
await server.connected;

send("test");

expect(await server.nextMessage).toBe("test");
});

it("should store error", async () => {
const { errorEvent, errored } = useWebSocket(FAKE_URL);
await server.connected;

server.error();

expect(errorEvent.value).toBeTruthy();
expect(errored.value).toBe(true);
});

it("should warn if the rate of messaging is too high", async () => {
const messages = ["test", "test1", "test2"];
const received: string[] = [];

const { data } = useWebSocket(FAKE_URL);
await server.connected;

watch(data, m => received.push(m), {
lazy: true
});

for (let i = 0; i < messages.length; i++) {
server.send(messages[i]);
}

await nextTick();
expect(warnSpy).toHaveBeenCalled();
});

it("should get all messages", async () => {
const messages = ["test", "test1", "test2"];
const received: string[] = [];

const { data } = useWebSocket(FAKE_URL);
await server.connected;

watch(data, m => received.push(m), {
lazy: true
});

for (let i = 0; i < messages.length; i++) {
server.send(messages[i]);

await nextTick();
}

expect(received).toStrictEqual(messages);
});
});
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
"coveralls": "^3.0.7",
"jest": "^24.9.0",
"jest-junit": "^9.0.0",
"jest-websocket-mock": "^1.5.1",
"lodash.camelcase": "^4.3.0",
"mock-socket": "^9.0.2",
"rimraf": "^3.0.0",
"rollup": "^1.25.2",
"rollup-plugin-commonjs": "^10.1.0",
Expand Down
11 changes: 2 additions & 9 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,6 @@ export default [
createConfig("umd", false),
createConfig("umd", true),

createConfig("cjs", true, false),
createConfig("cjs", true, true),
createConfig("cjs", false, false),
createConfig("cjs", false, true),

createConfig("es", true, false),
createConfig("es", true, true),
createConfig("es", false, false),
createConfig("es", false, true)
createConfig("cjs", false),
createConfig("es", false),
];
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './pagination/pagination'
export * from './promise/promise'
export * from './promise/cancellablePromise'
export * from './web/fetch';
export * from './web/websocket';
65 changes: 65 additions & 0 deletions src/web/webSocket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { ref } from "@vue/composition-api";

export function useWebSocket(url: string, protocols?: string | string[]) {
const ws = new WebSocket(url, protocols);
const messageEvent = ref<MessageEvent>(null);
const errorEvent = ref<Event>();
const data = ref<any>(null);

const isOpen = ref(false);
const isClosed = ref(false);
const errored = ref(false);

/* istanbul ignore next */
let lastMessage = (__DEV__ && Date.now()) || undefined;

ws.addEventListener("message", x => {
messageEvent.value = x;
data.value = x.data;

// if the messages are to quick, we need to warn
/* istanbul ignore else */
if (__DEV__) {
if (Date.now() - lastMessage! < 2) {
console.warn(
'[useWebSocket] message rate is too high, if you are using "data" or "messageEvent"' +
" you might not get updated of all the messages." +
' Use "ws..addEventListener("message", handler)" instead'
);
}
lastMessage = Date.now();
}
});

ws.addEventListener("error", error => {
errorEvent.value = error;
errored.value = true;
});

ws.addEventListener("close", () => {
isOpen.value = false;
isClosed.value = true;
});

ws.addEventListener("open", () => {
isOpen.value = true;
isClosed.value = false;
});

const send = (data: string | ArrayBufferLike | Blob | ArrayBufferView) =>
ws.send(data);

return {
ws,
send,

messageEvent,
errorEvent,

data,

isOpen,
isClosed,
errored
};
}
30 changes: 30 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2107,6 +2107,11 @@ jest-watcher@^24.9.0:
jest-util "^24.9.0"
string-length "^2.0.0"

jest-websocket-mock@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/jest-websocket-mock/-/jest-websocket-mock-1.5.1.tgz#8f19c67c55a2725aed398b49bf8e86203d934fc0"
integrity sha512-hrMDNVbPK7wxOfXrstMAJ6RvnVHCwbhZuJVjYbM7fMGlFR6XqkvIWoOIi/AbIsES7MsX77Dv6hnsk0etUTNowQ==

jest-worker@^24.6.0, jest-worker@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5"
Expand Down Expand Up @@ -2465,6 +2470,13 @@ mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1:
dependencies:
minimist "0.0.8"

mock-socket@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/mock-socket/-/mock-socket-9.0.2.tgz#8197f7e830f2f9d4b3a687eb69dce160689c23e4"
integrity sha512-VIs8Hp/FCKbs2rQeI5Zm7SGZAffTYQufooWFXTLF032ru/pv6W+KqQ1cOL4QMOktV2ugqYSP04JyE4SVG6QmWw==
dependencies:
url-parse "^1.4.4"

ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
Expand Down Expand Up @@ -2914,6 +2926,11 @@ qs@~6.5.2:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==

querystringify@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e"
integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==

rc@^1.2.7:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
Expand Down Expand Up @@ -3041,6 +3058,11 @@ require-main-filename@^2.0.0:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==

requires-port@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=

resolve-cwd@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
Expand Down Expand Up @@ -3723,6 +3745,14 @@ urix@^0.1.0:
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=

url-parse@^1.4.4:
version "1.4.7"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
dependencies:
querystringify "^2.1.1"
requires-port "^1.0.0"

use@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
Expand Down

0 comments on commit 51e92dc

Please sign in to comment.