From 9294fa8a907fcfdf9a1cf6d9d89b52706b4c57ef Mon Sep 17 00:00:00 2001 From: frederic charette Date: Wed, 9 Oct 2019 10:11:27 -0400 Subject: [PATCH 1/9] typescript cleanup, bundle standardization --- .eslintrc | 2 +- .travis.yml | 4 +- examples/{chat => chat_websocket}/client.js | 4 +- examples/{chat => chat_websocket}/server.js | 4 +- examples/compression/client.js | 23 ++++++++ examples/compression/server.js | 27 +++++++++ examples/distributed_pub_sub/client.js | 4 +- examples/distributed_pub_sub/server.js | 16 +++--- examples/typescript/client.ts | 19 +++++++ examples/typescript/server.ts | 28 ++++++++++ package.json | 25 ++++----- packages/ipc/package.json | 7 ++- packages/ipc/src/ipc.ts | 6 +- packages/ipc/tsconfig.json | 21 ------- packages/kalm/README.md | 39 ++++++++++--- packages/kalm/package.json | 9 +-- packages/kalm/src/components/client.ts | 12 ---- packages/kalm/src/components/provider.ts | 1 - packages/kalm/src/kalm.ts | 2 - packages/kalm/src/routines/dynamic.ts | 3 +- packages/kalm/src/routines/realtime.ts | 3 +- packages/kalm/src/routines/tick.ts | 3 +- packages/kalm/src/utils/parser.ts | 4 -- packages/kalm/tsconfig.json | 21 ------- packages/tcp/package.json | 7 ++- packages/tcp/src/tcp.ts | 6 +- packages/udp/package.json | 7 ++- packages/udp/src/udp.ts | 25 ++------- packages/udp/tsconfig.json | 21 ------- packages/ws/package.json | 9 +-- packages/ws/src/ws.ts | 9 +-- packages/ws/tsconfig.json | 21 ------- scripts/benchmarks/index.js | 4 +- scripts/benchmarks/transports/kalm.js | 2 +- scripts/build.sh | 13 +++-- packages/tcp/tsconfig.json => tsconfig.json | 10 ++-- types.ts => types.d.ts | 62 ++++++++++----------- 37 files changed, 236 insertions(+), 247 deletions(-) rename examples/{chat => chat_websocket}/client.js (71%) rename examples/{chat => chat_websocket}/server.js (82%) create mode 100644 examples/compression/client.js create mode 100644 examples/compression/server.js create mode 100644 examples/typescript/client.ts create mode 100644 examples/typescript/server.ts delete mode 100644 packages/ipc/tsconfig.json delete mode 100644 packages/kalm/tsconfig.json delete mode 100644 packages/udp/tsconfig.json delete mode 100644 packages/ws/tsconfig.json rename packages/tcp/tsconfig.json => tsconfig.json (72%) rename types.ts => types.d.ts (60%) diff --git a/.eslintrc b/.eslintrc index 8c050de..6f08b92 100644 --- a/.eslintrc +++ b/.eslintrc @@ -6,7 +6,7 @@ "import/resolver": { "node": { "paths": ["packages"], - "extensions": [".js", ".json", ".ts"] + "extensions": [".ts", ".spec.js"] } } }, diff --git a/.travis.yml b/.travis.yml index d3ca34a..9586e22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ language: node_js cache: yarn node_js: + - "12" - "10" - - "8" script: - yarn run lint - yarn run test @@ -11,5 +11,5 @@ sudo: false install: - yarn before_install: - - npm install yarn@^1.13.0 + - npm install yarn@^1.19.0 - yarn --version diff --git a/examples/chat/client.js b/examples/chat_websocket/client.js similarity index 71% rename from examples/chat/client.js rename to examples/chat_websocket/client.js index 129816e..5bd8393 100644 --- a/examples/chat/client.js +++ b/examples/chat_websocket/client.js @@ -10,8 +10,8 @@ const Client = kalm.connect({ routine: kalm.routines.realtime(), }); -Client.subscribe('r.evt', (evt, frame) => console.log(`${evt.name}: ${evt.msg}`, frame)); -Client.subscribe('r.sys', (evt, frame) => console.log(`[System]: ${evt.msg}`, frame)); +Client.subscribe('r.evt', (body, frame) => console.log(`${body.name}: ${body.msg}`, frame)); +Client.subscribe('r.sys', (body, frame) => console.log(`[System]: ${body.msg}`, frame)); Client.on('connect', () => { Client.write('c.evt', { name: Client.label, msg: 'Hey everyone!' }); diff --git a/examples/chat/server.js b/examples/chat_websocket/server.js similarity index 82% rename from examples/chat/server.js rename to examples/chat_websocket/server.js index 544623d..6a8b821 100644 --- a/examples/chat/server.js +++ b/examples/chat_websocket/server.js @@ -10,8 +10,8 @@ const Server = kalm.listen({ }); Server.on('connection', (client) => { - client.subscribe('c.evt', (msg, evt) => { - Server.broadcast('r.evt', msg); + client.subscribe('c.evt', (body, frame) => { + Server.broadcast('r.evt', body); }); Server.broadcast('r.sys', { msg: 'user joined' }); diff --git a/examples/compression/client.js b/examples/compression/client.js new file mode 100644 index 0000000..fd9a2f5 --- /dev/null +++ b/examples/compression/client.js @@ -0,0 +1,23 @@ +const kalm = require('kalm'); +const ws = require('@kalm/ws'); +const snappy = require('snappy'); + +const Client = kalm.connect({ + transport: ws(), + port: 3938, + json: false, + routine: kalm.routines.realtime(), +}); + +Client.subscribe('foo', (body, frame) => { + snappy.uncompress(body, (decompressedMessage) => { + console.log('Server event', decompressedMessage, frame); + }); +}); + +const payload = { + foo: 'bar', + message: 'hello from the client!', +}; + +Client.write('foo', snappy.compressSync(Buffer.from(JSON.stringify(payload)))); diff --git a/examples/compression/server.js b/examples/compression/server.js new file mode 100644 index 0000000..3a4b09c --- /dev/null +++ b/examples/compression/server.js @@ -0,0 +1,27 @@ +const kalm = require('kalm'); +const ws = require('@kalm/ws'); +const snappy = require('snappy'); + +const provider = kalm.listen({ + label: 'internal', + transport: ws(), + port: 3000, + json: false, + routine: kalm.routines.realtime(), + host: '0.0.0.0', // Apply local ip +}); + +provider.on('connection', (client) => { + client.subscribe('foo', (body, frame) => { + snappy.uncompress(body, (decompressedMessage) => { + console.log('Client event', decompressedMessage, frame); + }); + }); + + const payload = { + foo: 'bar', + message: 'hello from the server!', + }; + + client.write('foo', snappy.compressSync(Buffer.from(JSON.stringify(payload)))); +}); diff --git a/examples/distributed_pub_sub/client.js b/examples/distributed_pub_sub/client.js index 5ad4103..4d68988 100644 --- a/examples/distributed_pub_sub/client.js +++ b/examples/distributed_pub_sub/client.js @@ -11,8 +11,8 @@ const Client = kalm.connect({ routine: kalm.routines.realtime(), }); -Client.subscribe('r.evt', (evt, frame) => { - console.log('Relayed event', evt, frame); +Client.subscribe('r.evt', (body, frame) => { + console.log('Relayed event', body, frame); }); // now send some events diff --git a/examples/distributed_pub_sub/server.js b/examples/distributed_pub_sub/server.js index 59a0aeb..0261de3 100644 --- a/examples/distributed_pub_sub/server.js +++ b/examples/distributed_pub_sub/server.js @@ -34,25 +34,25 @@ providers.forEach((provider) => { provider.on('connection', (client) => { if (isIntern) { - client.subscribe('n.add', (msg, evt) => { + client.subscribe('n.add', (body, frame) => { if (isSeed) { - provider.broadcast('n.add', msg); - } else provider.connect(evt.remote); + provider.broadcast('n.add', body); + } else provider.connect(frame.remote); }); - client.subscribe('n.evt', (msg, evt) => { + client.subscribe('n.evt', (body, frame) => { providers.forEach((_provider) => { if (_provider.label === 'external') { - _provider.broadcast('r.evt', msg); + _provider.broadcast('r.evt', body); } }); }); } else { - client.subscribe('c.evt', (msg, evt) => { + client.subscribe('c.evt', (body, frame) => { providers.forEach((_provider) => { if (_provider.label === 'internal') { - _provider.broadcast('n.evt', msg); + _provider.broadcast('n.evt', body); } else { - _provider.broadcast('r.evt', msg); + _provider.broadcast('r.evt', body); } }); }); diff --git a/examples/typescript/client.ts b/examples/typescript/client.ts new file mode 100644 index 0000000..4aab8e8 --- /dev/null +++ b/examples/typescript/client.ts @@ -0,0 +1,19 @@ +import { connect, routines, Client, Frame } from 'kalm'; +import ws from '@kalm/ws'; + +const client: Client = connect({ + transport: ws(), + port: 3938, + routine: routines.realtime(), +}); + +type MyCustomPayload = { + foo: string + message: string +}; + +client.subscribe('r.evt', (body: MyCustomPayload, frame: Frame) => { + console.log('Server event', body, frame); +}); + +client.write('c.evt', 'hello world!'); diff --git a/examples/typescript/server.ts b/examples/typescript/server.ts new file mode 100644 index 0000000..10191d8 --- /dev/null +++ b/examples/typescript/server.ts @@ -0,0 +1,28 @@ +import { listen, routines, Provider, Client, Frame } from 'kalm'; +import ws from '@kalm/ws'; + +const provider: Provider = listen({ + transport: ws(), + port: 3938, + routine: routines.tick(5), + host: '0.0.0.0', +}); + +type MyCustomPayload = { + foo: string + message: string +}; + +provider.on('connection', (client: Client) => { + client.subscribe('foo', (body: MyCustomPayload, frame: Frame) => { + console.log('Client event', body, frame); + }); + + const payload: MyCustomPayload = { + foo: 'bar', + message: 'hello from the server!', + }; + + client.write('foo', payload); +}); + \ No newline at end of file diff --git a/package.json b/package.json index 65e528e..daa5c38 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "kalm-lerna", "private": true, - "version": "3.1.2", + "version": "3.2.0", "description": "The socket optimizer", "main": "packages/kalm/bin/kalm.js", "scripts": { @@ -24,20 +24,19 @@ "contributors": [ "frederic charette " ], - "typings": "./types.ts", + "typings": "./types.d.ts", "workspaces": [ "packages/*" ], "devDependencies": { - "@types/node": "^12.0.0", - "@typescript-eslint/eslint-plugin": "^1.10.2", - "@typescript-eslint/parser": "^1.10.0", + "@types/node": "^12.7.0", + "@typescript-eslint/eslint-plugin": "^2.3.0", + "@typescript-eslint/parser": "^2.3.0", "chai": "^4.2.0", - "eslint": "^5.16.0", - "eslint-config-airbnb-base": "^13.1.0", - "eslint-plugin-import": "^2.8.0", - "mocha": "^6.1.0", - "rollup": "^1.15.0", - "socket.io": "^2.2.0", - "socket.io-client": "^2.2.0", - "typescript": "^3.5.0" + "eslint": "^6.5.0", + "eslint-config-airbnb-base": "^14.0.0", + "eslint-plugin-import": "^2.18.0", + "mocha": "^6.2.0", + "socket.io": "^2.3.0", + "socket.io-client": "^2.3.0", + "typescript": "^3.6.0" } } diff --git a/packages/ipc/package.json b/packages/ipc/package.json index 2639f14..6928e82 100644 --- a/packages/ipc/package.json +++ b/packages/ipc/package.json @@ -1,6 +1,6 @@ { "name": "@kalm/ipc", - "version": "3.1.2", + "version": "3.2.0", "description": "IPC transport for Kalm", "main": "bin/ipc.min.js", "scripts": { @@ -33,7 +33,8 @@ ], "author": "frederic charette ", "license": "Apache-2.0", - "files":["bin/ipc.min.js"], + "typings": "./bin/types.d.ts", + "files": ["bin/ipc.min.js"], "bugs": { "url": "https://github.com/kalm/kalm-js/issues" }, @@ -47,6 +48,6 @@ }, "devDependencies": { "chai": "^4.2.0", - "mocha": "^6.1.0" + "mocha": "^6.2.0" } } diff --git a/packages/ipc/src/ipc.ts b/packages/ipc/src/ipc.ts index 821a29a..c01c986 100644 --- a/packages/ipc/src/ipc.ts +++ b/packages/ipc/src/ipc.ts @@ -1,13 +1,11 @@ /* Requires ------------------------------------------------------------------*/ import net from 'net'; -import { Socket, Transport, ClientConfig, Remote, IPCConfig } from '../../../types'; -import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ -function ipc({ socketTimeout = 30000, path = '/tmp/app.socket-' }: IPCConfig = {}): Transport { - return function socket(params: ClientConfig, emitter: EventEmitter): Socket { +function ipc({ socketTimeout = 30000, path = '/tmp/app.socket-' }: IPCConfig = {}): KalmTransport { + return function socket(params: ClientConfig, emitter: NodeJS.EventEmitter): Socket { let listener: net.Server; function bind(): void { diff --git a/packages/ipc/tsconfig.json b/packages/ipc/tsconfig.json deleted file mode 100644 index 80b22ac..0000000 --- a/packages/ipc/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "module": "esnext", - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "noImplicitAny": false, - "removeComments": true, - "preserveConstEnums": true, - "lib": [ "es2018", "dom", "es2018.promise" ], - "sourceMap": false, - "allowJs": true, - "target": "es2018", - "outDir": "dist" - }, - "include": [ - "./src" - ], - "exclude": [ - "node_modules" - ] -} \ No newline at end of file diff --git a/packages/kalm/README.md b/packages/kalm/README.md index c41bfa3..82bf765 100644 --- a/packages/kalm/README.md +++ b/packages/kalm/README.md @@ -27,7 +27,7 @@ perf -The performance gain comes from buffering packets before sending them- eventually sending batches instead of individual packages. The more traffic getting processed, the better the improvement. You can read more about the algorithm [here](https://en.wikipedia.org/wiki/Nagle%27s_algorithm) +The performance gain comes from buffering packets before sending them- eventually sending batches instead of individual packages. The more traffic getting processed, the better the improvement. Many strategies are offered as routines. You can read more about the packet buffering algorithm [here](https://en.wikipedia.org/wiki/Nagle%27s_algorithm) ## Install @@ -39,9 +39,34 @@ Install the transport layer ('tcp' for example) `npm install @kalm/tcp` -## Build +## Usage + +**Server** + +```javascript +const Server = kalm.listen({ + port: 8800, + transport: ws(), + routine: kalm.routines.tick(5), // Hz + host: '0.0.0.0', +}); +``` + +**Client** + +```javascript +const kalm = require('kalm'); +const ws = require('@kalm/ws'); -`npm run build` +const Client = kalm.connect({ + host: '0.0.0.0', + port: 8800, + transport: ws(), + routine: kalm.routines.realtime(), +}); +``` + +See the [examples](https://github.com/kalm/kalm.js/tree/master/examples) folder for great real-world examples! ## Documentation @@ -50,13 +75,13 @@ Install the transport layer ('tcp' for example) - Transports [[wiki]](https://github.com/kalm/kalm.js/wiki/Transports) - Routines [[wiki]](https://github.com/kalm/kalm.js/wiki/Routines) -## Usage +## Logging -See the [examples](https://github.com/kalm/kalm.js/tree/master/examples) folder. +Kalm uses the `NODE_DEBUG` environment variable. Just include `kalm` in your value. -## Logging +Example: -Kalm uses the standard `NODE_DEBUG` environment variable. Just include `kalm` in your value. +`NODE_DEBUG=net,kalm node myApp.js` ## Testing diff --git a/packages/kalm/package.json b/packages/kalm/package.json index 37a75f4..9f87b9e 100644 --- a/packages/kalm/package.json +++ b/packages/kalm/package.json @@ -1,6 +1,6 @@ { "name": "kalm", - "version": "3.1.2", + "version": "3.2.0", "description": "The socket optimizer", "main": "bin/kalm.min.js", "scripts": { @@ -35,7 +35,8 @@ "ws", "core" ], - "files":["bin/kalm.min.js"], + "typings": "./bin/types.d.ts", + "files": ["bin/kalm.min.js"], "author": "frederic charette ", "license": "Apache-2.0", "bugs": { @@ -47,7 +48,7 @@ ], "devDependencies": { "chai": "^4.2.0", - "mocha": "^6.1.0", - "sinon": "^7.3.2" + "mocha": "^6.2.0", + "sinon": "^7.5.0" } } diff --git a/packages/kalm/src/components/client.ts b/packages/kalm/src/components/client.ts index 61997da..94ba43c 100644 --- a/packages/kalm/src/components/client.ts +++ b/packages/kalm/src/components/client.ts @@ -3,18 +3,6 @@ import logger from '../utils/logger'; import parser from '../utils/parser'; import { EventEmitter } from 'events'; -import { - Channel, - ClientConfig, - RawFrame, - Serializable, - Socket, - Client, - Remote, - Frame, - SocketHandle, - ChannelList, -} from '../../../../types'; /* Methods -------------------------------------------------------------------*/ diff --git a/packages/kalm/src/components/provider.ts b/packages/kalm/src/components/provider.ts index 7abf266..7ae949f 100644 --- a/packages/kalm/src/components/provider.ts +++ b/packages/kalm/src/components/provider.ts @@ -3,7 +3,6 @@ import logger from '../utils/logger'; import Client from './client'; import { EventEmitter } from 'events'; -import { Serializable, ClientConfig, Socket, Remote, Provider } from '../../../../types'; /* Methods -------------------------------------------------------------------*/ diff --git a/packages/kalm/src/kalm.ts b/packages/kalm/src/kalm.ts index f882e6c..6a799f4 100644 --- a/packages/kalm/src/kalm.ts +++ b/packages/kalm/src/kalm.ts @@ -8,8 +8,6 @@ import realtime from './routines/realtime'; import tick from './routines/tick'; import { EventEmitter } from 'events'; -import { ProviderConfig, Provider, ClientConfig, Client } from '../../../types'; - /* Local variables -----------------------------------------------------------*/ const defaults = { diff --git a/packages/kalm/src/routines/dynamic.ts b/packages/kalm/src/routines/dynamic.ts index dc06e28..2c81618 100644 --- a/packages/kalm/src/routines/dynamic.ts +++ b/packages/kalm/src/routines/dynamic.ts @@ -1,11 +1,10 @@ /* Requires ------------------------------------------------------------------*/ import { EventEmitter } from 'events'; -import { Queue, Routine } from '../../../../types'; /* Methods -------------------------------------------------------------------*/ -function dynamic(hz: number): Routine { +function dynamic(hz: number): KalmRoutine { if (hz <= 0 || hz > 1000) { throw new Error(`Unable to set Hertz value of ${hz}. Must be between 0.1e13 and 1000`); } diff --git a/packages/kalm/src/routines/realtime.ts b/packages/kalm/src/routines/realtime.ts index 437f598..570b119 100644 --- a/packages/kalm/src/routines/realtime.ts +++ b/packages/kalm/src/routines/realtime.ts @@ -1,11 +1,10 @@ /* Requires ------------------------------------------------------------------*/ import { EventEmitter } from 'events'; -import { Queue, Routine } from '../../../../types'; /* Methods -------------------------------------------------------------------*/ -function realtime(): Routine { +function realtime(): KalmRoutine { return function queue(channel: string, params: object, emitter: EventEmitter): Queue { let i: number = 0; diff --git a/packages/kalm/src/routines/tick.ts b/packages/kalm/src/routines/tick.ts index 3554d49..36a6779 100644 --- a/packages/kalm/src/routines/tick.ts +++ b/packages/kalm/src/routines/tick.ts @@ -1,11 +1,10 @@ /* Requires ------------------------------------------------------------------*/ import { EventEmitter } from 'events'; -import { Queue, Routine } from '../../../../types'; /* Methods -------------------------------------------------------------------*/ -function tick(hz: number, seed: number = Date.now()): Routine { +function tick(hz: number, seed: number = Date.now()): KalmRoutine { if (hz <= 0 || hz > 1000) { throw new Error(`Unable to set Hertz value of ${hz}. Must be between 0.1e13 and 1000`); } diff --git a/packages/kalm/src/utils/parser.ts b/packages/kalm/src/utils/parser.ts index 80ac8f4..b79d2a0 100644 --- a/packages/kalm/src/utils/parser.ts +++ b/packages/kalm/src/utils/parser.ts @@ -1,7 +1,3 @@ -/* Requires ------------------------------------------------------------------*/ - -import { RawFrame } from '../../../../types'; - /* Methods -------------------------------------------------------------------*/ function serialize(frameId: number, channel: string, packets: Buffer[]): number[] { diff --git a/packages/kalm/tsconfig.json b/packages/kalm/tsconfig.json deleted file mode 100644 index 80b22ac..0000000 --- a/packages/kalm/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "module": "esnext", - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "noImplicitAny": false, - "removeComments": true, - "preserveConstEnums": true, - "lib": [ "es2018", "dom", "es2018.promise" ], - "sourceMap": false, - "allowJs": true, - "target": "es2018", - "outDir": "dist" - }, - "include": [ - "./src" - ], - "exclude": [ - "node_modules" - ] -} \ No newline at end of file diff --git a/packages/tcp/package.json b/packages/tcp/package.json index 99c9012..cf9a417 100644 --- a/packages/tcp/package.json +++ b/packages/tcp/package.json @@ -1,6 +1,6 @@ { "name": "@kalm/tcp", - "version": "3.1.2", + "version": "3.2.0", "description": "TCP transport for Kalm", "main": "bin/tcp.min.js", "scripts": { @@ -31,7 +31,8 @@ "web", "tcp" ], - "files":["bin/tcp.min.js"], + "typings": "./bin/types.d.ts", + "files": ["bin/tcp.min.js"], "author": "frederic charette ", "license": "Apache-2.0", "bugs": { @@ -46,6 +47,6 @@ }, "devDependencies": { "chai": "^4.2.0", - "mocha": "^6.1.0" + "mocha": "^6.2.0" } } \ No newline at end of file diff --git a/packages/tcp/src/tcp.ts b/packages/tcp/src/tcp.ts index 4c439f2..9998cad 100644 --- a/packages/tcp/src/tcp.ts +++ b/packages/tcp/src/tcp.ts @@ -1,13 +1,11 @@ /* Requires ------------------------------------------------------------------*/ import net from 'net'; -import { Socket, Transport, ClientConfig, Remote, TCPConfig } from '../../../types'; -import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ -function tcp({ socketTimeout = 30000 }: TCPConfig = {}): Transport { - return function socket(params: ClientConfig, emitter: EventEmitter): Socket { +function tcp({ socketTimeout = 30000 }: TCPConfig = {}): KalmTransport { + return function socket(params: ClientConfig, emitter: NodeJS.EventEmitter): Socket { let listener: net.Server; function bind(): void { diff --git a/packages/udp/package.json b/packages/udp/package.json index da86ea1..bf97a7b 100644 --- a/packages/udp/package.json +++ b/packages/udp/package.json @@ -1,6 +1,6 @@ { "name": "@kalm/udp", - "version": "3.1.2", + "version": "3.2.0", "description": "UDP transport for Kalm", "main": "bin/udp.min.js", "scripts": { @@ -31,7 +31,8 @@ "web", "udp" ], - "files":["bin/udp.min.js"], + "typings": "./bin/types.d.ts", + "files": ["bin/udp.min.js"], "author": "frederic charette ", "license": "Apache-2.0", "bugs": { @@ -46,6 +47,6 @@ }, "devDependencies": { "chai": "^4.2.0", - "mocha": "^6.1.0" + "mocha": "^6.2.0" } } \ No newline at end of file diff --git a/packages/udp/src/udp.ts b/packages/udp/src/udp.ts index f131b44..d4ed2a2 100644 --- a/packages/udp/src/udp.ts +++ b/packages/udp/src/udp.ts @@ -1,33 +1,16 @@ /* Requires ------------------------------------------------------------------*/ import dgram from 'dgram'; -import { - Socket, - Transport, - ClientConfig, - Remote, - SocketHandle, - UDPSocketHandle, - UDPConfig, - UDPClientList, - UDPClient, -} from '../../../types'; -import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ -function udp({ - type = 'udp4', - localAddr = '0.0.0.0', - reuseAddr = true, - socketTimeout = 30000, - connectTimeout = 1000, -}: UDPConfig = {}): Transport { - return function socket(params: ClientConfig, emitter: EventEmitter): Socket { +function udp({ type = 'udp4', localAddr = '0.0.0.0', reuseAddr = true, socketTimeout = 30000, connectTimeout = 1000, +}: UDPConfig = {}): KalmTransport { + return function socket(params: ClientConfig, emitter: NodeJS.EventEmitter): Socket { let listener: dgram.Socket; const clientCache: UDPClientList = {}; - function addClient(client) { + function addClient(client: Client): void { const local: Remote = client.local(); const key: string = `${local.host}.${local.port}`; diff --git a/packages/udp/tsconfig.json b/packages/udp/tsconfig.json deleted file mode 100644 index 80b22ac..0000000 --- a/packages/udp/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "module": "esnext", - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "noImplicitAny": false, - "removeComments": true, - "preserveConstEnums": true, - "lib": [ "es2018", "dom", "es2018.promise" ], - "sourceMap": false, - "allowJs": true, - "target": "es2018", - "outDir": "dist" - }, - "include": [ - "./src" - ], - "exclude": [ - "node_modules" - ] -} \ No newline at end of file diff --git a/packages/ws/package.json b/packages/ws/package.json index 572f2a1..2c5585a 100644 --- a/packages/ws/package.json +++ b/packages/ws/package.json @@ -1,6 +1,6 @@ { "name": "@kalm/ws", - "version": "3.1.2", + "version": "3.2.0", "description": "WebSocket transport for Kalm", "main": "bin/ws.min.js", "scripts": { @@ -31,7 +31,8 @@ "web", "ws" ], - "files":["bin/ws.min.js"], + "typings": "./bin/types.d.ts", + "files": ["bin/ws.min.js"], "author": "frederic charette ", "license": "Apache-2.0", "bugs": { @@ -42,7 +43,7 @@ "frederic charette " ], "dependencies": { - "ws": "^7.0.0" + "ws": "^7.1.0" }, "browser": { "http": false, @@ -50,6 +51,6 @@ }, "devDependencies": { "chai": "^4.2.0", - "mocha": "^6.1.0" + "mocha": "^6.2.0" } } diff --git a/packages/ws/src/ws.ts b/packages/ws/src/ws.ts index aa80cbc..2150cc9 100644 --- a/packages/ws/src/ws.ts +++ b/packages/ws/src/ws.ts @@ -1,12 +1,5 @@ /* Requires ------------------------------------------------------------------*/ -import { - Socket, - Transport, - ClientConfig, - Remote, - WSConfig, -} from '../../../types'; import { EventEmitter } from 'events'; const isBrowser = (typeof WebSocket !== 'undefined'); @@ -14,7 +7,7 @@ const WS = isBrowser ? WebSocket : require('ws'); /* Methods -------------------------------------------------------------------*/ -function ws({ cert, key, secure }: WSConfig = {}): Transport { +function ws({ cert, key, secure }: WSConfig = {}): KalmTransport { return function socket(params: ClientConfig, emitter: EventEmitter): Socket { let listener; diff --git a/packages/ws/tsconfig.json b/packages/ws/tsconfig.json deleted file mode 100644 index 80b22ac..0000000 --- a/packages/ws/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "module": "esnext", - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "noImplicitAny": false, - "removeComments": true, - "preserveConstEnums": true, - "lib": [ "es2018", "dom", "es2018.promise" ], - "sourceMap": false, - "allowJs": true, - "target": "es2018", - "outDir": "dist" - }, - "include": [ - "./src" - ], - "exclude": [ - "node_modules" - ] -} \ No newline at end of file diff --git a/scripts/benchmarks/index.js b/scripts/benchmarks/index.js index 9f43bdf..033bdca 100644 --- a/scripts/benchmarks/index.js +++ b/scripts/benchmarks/index.js @@ -66,7 +66,7 @@ function _postResults() { // Roll port number settings.port = 3000 + Math.round(Math.random() * 1000); -const adpts = Object.keys(Suite).map(k => ({ +const adpts = Object.keys(Suite).map((k) => ({ transport: k, settings: { transport: k.toLowerCase() }, raw: Suite[k], @@ -99,6 +99,6 @@ adpts.forEach((i) => { tests.push(_postResults); tests.reduce( - (c, n) => c.then(resolve => new Promise(n).then(resolve, _errorHandler), _errorHandler), + (c, n) => c.then((resolve) => new Promise(n).then(resolve, _errorHandler), _errorHandler), Promise.resolve(), ); diff --git a/scripts/benchmarks/transports/kalm.js b/scripts/benchmarks/transports/kalm.js index 93547a1..f89e69c 100644 --- a/scripts/benchmarks/transports/kalm.js +++ b/scripts/benchmarks/transports/kalm.js @@ -34,7 +34,7 @@ function setup(resolve) { }); server.on('connection', (c) => { - c.subscribe(settings.testChannel, msg => c.write(settings.testChannel, msg)); + c.subscribe(settings.testChannel, (msg) => c.write(settings.testChannel, msg)); }); handbreak = false; diff --git a/scripts/build.sh b/scripts/build.sh index f2c97ad..824707c 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,8 +1,9 @@ echo "Building" $1 -mkdir -p ./tmp -rm -rf ./tmp/* -../../node_modules/typescript/bin/tsc --outDir ./tmp -echo "Compiled Typescript, rolling up" -../../node_modules/rollup/bin/rollup ./tmp/packages/$1/src/$1.js --format umd --name $1 --file ./bin/$1.min.js +mkdir -p ./bin +rm -rf ./bin/* +cp ../../tsconfig.json ./tsconfig.json +../../node_modules/typescript/bin/tsc --outDir ./bin +echo "Copying .d.ts file to bin" +cp ../../types.d.ts ./bin/types.d.ts echo "Build completed, cleaning up" -rm -rf ./tmp \ No newline at end of file +rm -rf ./tsconfig.json \ No newline at end of file diff --git a/packages/tcp/tsconfig.json b/tsconfig.json similarity index 72% rename from packages/tcp/tsconfig.json rename to tsconfig.json index 80b22ac..9610ad3 100644 --- a/packages/tcp/tsconfig.json +++ b/tsconfig.json @@ -6,16 +6,18 @@ "noImplicitAny": false, "removeComments": true, "preserveConstEnums": true, - "lib": [ "es2018", "dom", "es2018.promise" ], "sourceMap": false, "allowJs": true, - "target": "es2018", + "target": "esnext", "outDir": "dist" }, "include": [ - "./src" + "./packages", + "./src", + "./types.d.ts" ], "exclude": [ - "node_modules" + "node_modules", + "**/*.min.js" ] } \ No newline at end of file diff --git a/types.ts b/types.d.ts similarity index 60% rename from types.ts rename to types.d.ts index e23e35c..5764950 100644 --- a/types.ts +++ b/types.d.ts @@ -1,44 +1,38 @@ -/* Requires ------------------------------------------------------------------*/ - -import { EventEmitter } from 'events'; -import net from 'net'; -import dgram from 'dgram'; - /* Types ---------------------------------------------------------------------*/ -export type ClientConfig = { +interface ClientConfig { label?: string - routine?: Routine + routine?: KalmRoutine json?: Boolean - transport?: Transport + transport?: KalmTransport port?: number host?: string isServer?: boolean provider?: any } -export type ProviderConfig = { +interface ProviderConfig { label?: string - routine?: Routine + routine?: KalmRoutine json?: Boolean - transport?: Transport + transport?: KalmTransport port?: number host?: string } -export type Remote = { +type Remote = { host: string port: number } -export interface Provider extends EventEmitter { +interface Provider extends NodeJS.EventEmitter { broadcast: (channel: string, message: Serializable) => void label: string stop: () => void connections: Client[] } -export interface Client extends EventEmitter { +interface Client extends NodeJS.EventEmitter { write: (channel: string, message: Serializable) => void destroy: () => void subscribe: (channel: string, handler: () => void) => void @@ -47,42 +41,42 @@ export interface Client extends EventEmitter { remote: () => Remote } -export type Channel = { +type Channel = { queue: Queue - emitter: EventEmitter + emitter: NodeJS.EventEmitter } -export type ChannelList = { +type ChannelList = { [key: string]: Channel } -export type Serializable = Buffer | object | string | null +type Serializable = Buffer | object | string | null -export type UDPSocketHandle = { - socket: dgram.Socket +type UDPSocketHandle = { + socket: any port: number host: string } -export type UDPClient = { +type UDPClient = { client: Client timeout: NodeJS.Timeout data: Buffer[] } -export type UDPClientList = { +type UDPClientList = { [key: string]: UDPClient } -export type SocketHandle = net.Socket | UDPSocketHandle | WebSocket +type SocketHandle = NodeJS.Socket | UDPSocketHandle | WebSocket -export type Routine = (channel: string, params: object, emitter: EventEmitter) => Queue -export interface Queue { +type KalmRoutine = (channel: string, params: any, emitter: NodeJS.EventEmitter) => Queue +interface Queue { add: (packet: Buffer) => void size: () => number flush: () => void } -export type Transport = (params: object, emitter: EventEmitter) => Socket -export interface Socket { +type KalmTransport = (params: any, emitter: NodeJS.EventEmitter) => Socket +interface Socket { bind: () => void remote: (handle: SocketHandle) => Remote connect: (handle?: SocketHandle) => SocketHandle @@ -91,16 +85,16 @@ export interface Socket { disconnect: (handle: SocketHandle) => void } -export type IPCConfig = { +interface IPCConfig { socketTimeout?: number path?: string } -export type TCPConfig = { +interface TCPConfig { socketTimeout?: number } -export type UDPConfig = { +interface UDPConfig { type?: string localAddr?: string reuseAddr?: boolean @@ -108,20 +102,20 @@ export type UDPConfig = { connectTimeout?: number } -export type WSConfig = { +interface WSConfig { cert?: string key?: string secure?: boolean } -export type RawFrame = { +type RawFrame = { frameId: number channel: string packets: Buffer[] payloadBytes: number } -export type Frame = { +type Frame = { client: Client channel: string frame: { From 5220b31f929b626485aab9f8fea480c20020721a Mon Sep 17 00:00:00 2001 From: frederic charette Date: Wed, 9 Oct 2019 11:13:12 -0400 Subject: [PATCH 2/9] centralized test tooling, migrated to ts+jest --- .eslintignore | 3 ++- .eslintrc | 2 +- .npmignore | 3 ++- jest.config.js | 9 +++++++++ package.json | 7 ++++--- packages/ipc/package.json | 10 ++-------- packages/ipc/tests/unit/ipc.spec.js | 0 packages/ipc/tests/unit/ipc.spec.ts | 5 +++++ packages/kalm/package.json | 13 +++--------- .../kalm/tests/unit/components/client.spec.js | 0 .../kalm/tests/unit/components/client.spec.ts | 5 +++++ .../tests/unit/components/provider.spec.js | 0 .../tests/unit/components/provider.spec.ts | 5 +++++ .../tests/unit/{kalm.spec.js => kalm.spec.ts} | 20 +++++++++---------- .../kalm/tests/unit/routines/dynamic.spec.js | 0 .../kalm/tests/unit/routines/dynamic.spec.ts | 5 +++++ .../kalm/tests/unit/routines/realtime.spec.js | 0 .../kalm/tests/unit/routines/realtime.spec.ts | 5 +++++ .../kalm/tests/unit/routines/tick.spec.js | 0 .../kalm/tests/unit/routines/tick.spec.ts | 5 +++++ packages/kalm/tests/unit/utils/logger.spec.js | 0 packages/kalm/tests/unit/utils/logger.spec.ts | 5 +++++ packages/kalm/tests/unit/utils/parser.spec.js | 0 packages/kalm/tests/unit/utils/parser.spec.ts | 5 +++++ packages/tcp/package.json | 10 ++-------- packages/tcp/tests/unit/tcp.spec.js | 0 packages/tcp/tests/unit/tcp.spec.ts | 5 +++++ packages/udp/package.json | 10 ++-------- packages/udp/tests/unit/udp.spec.js | 0 packages/udp/tests/unit/udp.spec.ts | 5 +++++ packages/ws/package.json | 10 ++-------- packages/ws/src/ws.ts | 2 +- packages/ws/tests/unit/ws.spec.js | 0 packages/ws/tests/unit/ws.spec.ts | 5 +++++ scripts/benchmarks/transports/kalm.js | 10 +++++----- .../{index.spec.js => index.spec.ts} | 11 +++++----- tsconfig.json | 2 +- 37 files changed, 105 insertions(+), 72 deletions(-) create mode 100644 jest.config.js delete mode 100644 packages/ipc/tests/unit/ipc.spec.js create mode 100644 packages/ipc/tests/unit/ipc.spec.ts delete mode 100644 packages/kalm/tests/unit/components/client.spec.js create mode 100644 packages/kalm/tests/unit/components/client.spec.ts delete mode 100644 packages/kalm/tests/unit/components/provider.spec.js create mode 100644 packages/kalm/tests/unit/components/provider.spec.ts rename packages/kalm/tests/unit/{kalm.spec.js => kalm.spec.ts} (65%) delete mode 100644 packages/kalm/tests/unit/routines/dynamic.spec.js create mode 100644 packages/kalm/tests/unit/routines/dynamic.spec.ts delete mode 100644 packages/kalm/tests/unit/routines/realtime.spec.js create mode 100644 packages/kalm/tests/unit/routines/realtime.spec.ts delete mode 100644 packages/kalm/tests/unit/routines/tick.spec.js create mode 100644 packages/kalm/tests/unit/routines/tick.spec.ts delete mode 100644 packages/kalm/tests/unit/utils/logger.spec.js create mode 100644 packages/kalm/tests/unit/utils/logger.spec.ts delete mode 100644 packages/kalm/tests/unit/utils/parser.spec.js create mode 100644 packages/kalm/tests/unit/utils/parser.spec.ts delete mode 100644 packages/tcp/tests/unit/tcp.spec.js create mode 100644 packages/tcp/tests/unit/tcp.spec.ts delete mode 100644 packages/udp/tests/unit/udp.spec.js create mode 100644 packages/udp/tests/unit/udp.spec.ts delete mode 100644 packages/ws/tests/unit/ws.spec.js create mode 100644 packages/ws/tests/unit/ws.spec.ts rename tests/integration/{index.spec.js => index.spec.ts} (85%) diff --git a/.eslintignore b/.eslintignore index c2aa2f3..8324a63 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ **/*.min.js examples -node_modules \ No newline at end of file +node_modules +scripts \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 6f08b92..8dee611 100644 --- a/.eslintrc +++ b/.eslintrc @@ -6,7 +6,7 @@ "import/resolver": { "node": { "paths": ["packages"], - "extensions": [".ts", ".spec.js"] + "extensions": [".ts", ".spec.ts"] } } }, diff --git a/.npmignore b/.npmignore index 83bc8b3..91c62db 100644 --- a/.npmignore +++ b/.npmignore @@ -9,4 +9,5 @@ tslint.json package-lock.json yarn.lock .vscode -.github \ No newline at end of file +.github +jest.config.js \ No newline at end of file diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..ebe914b --- /dev/null +++ b/jest.config.js @@ -0,0 +1,9 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + globals: { + 'ts-jest': { + diagnostics: false, + }, + }, +}; diff --git a/package.json b/package.json index daa5c38..cb0c735 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "lint": "eslint .", "lint:fix": "yarn lint --fix", - "test": "yarn workspaces run test --ci && mocha ./tests/integration --exit", + "test": "jest ./packages && jest ./tests/integration --forceExit", "build": "yarn workspaces run build --ci", "bench": "node ./scripts/benchmarks" }, @@ -27,16 +27,17 @@ "typings": "./types.d.ts", "workspaces": [ "packages/*" ], "devDependencies": { + "@types/jest": "^24.0.17", "@types/node": "^12.7.0", "@typescript-eslint/eslint-plugin": "^2.3.0", "@typescript-eslint/parser": "^2.3.0", - "chai": "^4.2.0", "eslint": "^6.5.0", "eslint-config-airbnb-base": "^14.0.0", "eslint-plugin-import": "^2.18.0", - "mocha": "^6.2.0", + "jest": "^24.9.0", "socket.io": "^2.3.0", "socket.io-client": "^2.3.0", + "ts-jest": "^24.1.0", "typescript": "^3.6.0" } } diff --git a/packages/ipc/package.json b/packages/ipc/package.json index 6928e82..3c01ac4 100644 --- a/packages/ipc/package.json +++ b/packages/ipc/package.json @@ -2,10 +2,9 @@ "name": "@kalm/ipc", "version": "3.2.0", "description": "IPC transport for Kalm", - "main": "bin/ipc.min.js", + "main": "bin/ipc.js", "scripts": { - "build": "../../scripts/build.sh ipc", - "test": "mocha ./tests/unit --exit" + "build": "../../scripts/build.sh ipc" }, "repository": { "type": "git", @@ -34,7 +33,6 @@ "author": "frederic charette ", "license": "Apache-2.0", "typings": "./bin/types.d.ts", - "files": ["bin/ipc.min.js"], "bugs": { "url": "https://github.com/kalm/kalm-js/issues" }, @@ -45,9 +43,5 @@ "browser": { "net": false, "fs": false - }, - "devDependencies": { - "chai": "^4.2.0", - "mocha": "^6.2.0" } } diff --git a/packages/ipc/tests/unit/ipc.spec.js b/packages/ipc/tests/unit/ipc.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/ipc/tests/unit/ipc.spec.ts b/packages/ipc/tests/unit/ipc.spec.ts new file mode 100644 index 0000000..948a7e6 --- /dev/null +++ b/packages/ipc/tests/unit/ipc.spec.ts @@ -0,0 +1,5 @@ +import ipc from '../../src/ipc'; + +describe('IPC transport', () => { + it('TODO', () => { expect(ipc).not.toBeUndefined(); }); +}); diff --git a/packages/kalm/package.json b/packages/kalm/package.json index 9f87b9e..3bb07ef 100644 --- a/packages/kalm/package.json +++ b/packages/kalm/package.json @@ -2,10 +2,9 @@ "name": "kalm", "version": "3.2.0", "description": "The socket optimizer", - "main": "bin/kalm.min.js", + "main": "bin/kalm.js", "scripts": { - "build": "../../scripts/build.sh kalm", - "test": "mocha ./tests/unit --exit" + "build": "../../scripts/build.sh kalm" }, "repository": { "type": "git", @@ -36,7 +35,6 @@ "core" ], "typings": "./bin/types.d.ts", - "files": ["bin/kalm.min.js"], "author": "frederic charette ", "license": "Apache-2.0", "bugs": { @@ -45,10 +43,5 @@ "homepage": "https://kalm.js.org", "contributors": [ "frederic charette " - ], - "devDependencies": { - "chai": "^4.2.0", - "mocha": "^6.2.0", - "sinon": "^7.5.0" - } + ] } diff --git a/packages/kalm/tests/unit/components/client.spec.js b/packages/kalm/tests/unit/components/client.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kalm/tests/unit/components/client.spec.ts b/packages/kalm/tests/unit/components/client.spec.ts new file mode 100644 index 0000000..f895aab --- /dev/null +++ b/packages/kalm/tests/unit/components/client.spec.ts @@ -0,0 +1,5 @@ +import client from '../../../src/components/client'; + +describe('Client', () => { + it('TODO', () => { expect(client).not.toBeUndefined(); }); +}); diff --git a/packages/kalm/tests/unit/components/provider.spec.js b/packages/kalm/tests/unit/components/provider.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kalm/tests/unit/components/provider.spec.ts b/packages/kalm/tests/unit/components/provider.spec.ts new file mode 100644 index 0000000..00d93c4 --- /dev/null +++ b/packages/kalm/tests/unit/components/provider.spec.ts @@ -0,0 +1,5 @@ +import provider from '../../../src/components/provider'; + +describe('Provider', () => { + it('TODO', () => { expect(provider).not.toBeUndefined(); }); +}); diff --git a/packages/kalm/tests/unit/kalm.spec.js b/packages/kalm/tests/unit/kalm.spec.ts similarity index 65% rename from packages/kalm/tests/unit/kalm.spec.js rename to packages/kalm/tests/unit/kalm.spec.ts index 38d2b1d..703e9d8 100644 --- a/packages/kalm/tests/unit/kalm.spec.js +++ b/packages/kalm/tests/unit/kalm.spec.ts @@ -1,9 +1,7 @@ -const { expect } = require('chai'); -const sinon = require('sinon'); -const kalm = require('../../bin/kalm.min'); +import kalm from '../../src/kalm'; -const bindSpy = sinon.spy(); -const connectSpy = sinon.spy(); +const bindSpy = jest.fn(); +const connectSpy = jest.fn(); const mockTransport = () => () => ({ bind: bindSpy, connect: connectSpy }); describe('Kalm constructors', () => { @@ -11,16 +9,16 @@ describe('Kalm constructors', () => { let server; it('should throw an error if no transports are provided', () => { - expect(kalm.listen).to.throw(); + expect(kalm.listen).toThrow(); }); it('listen should bind to a transport if one is provided', () => { server = kalm.listen({ transport: mockTransport() }); - expect(bindSpy.called).to.be.true; + expect(bindSpy).toHaveBeenCalled(); }); it('should return an object with all the required fields', () => { - expect(server).to.have.property('label'); + expect(server).toHaveProperty('label'); }); }); @@ -28,16 +26,16 @@ describe('Kalm constructors', () => { let client; it('should throw an error if no transports are provided', () => { - expect(kalm.connect).to.throw(); + expect(kalm.connect).toThrow(); }); it('listen should connect via a transport if one is provided', () => { client = kalm.connect({ transport: mockTransport() }); - expect(connectSpy.called).to.be.true; + expect(connectSpy).toHaveBeenCalled(); }); it('should return an object with all the required fields', () => { - expect(client).to.have.property('label'); + expect(client).toHaveProperty('label'); }); }); }); diff --git a/packages/kalm/tests/unit/routines/dynamic.spec.js b/packages/kalm/tests/unit/routines/dynamic.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kalm/tests/unit/routines/dynamic.spec.ts b/packages/kalm/tests/unit/routines/dynamic.spec.ts new file mode 100644 index 0000000..c700667 --- /dev/null +++ b/packages/kalm/tests/unit/routines/dynamic.spec.ts @@ -0,0 +1,5 @@ +import dynamic from '../../../src/routines/dynamic'; + +describe('Dynamic routine', () => { + it('TODO', () => { expect(dynamic).not.toBeUndefined(); }); +}); diff --git a/packages/kalm/tests/unit/routines/realtime.spec.js b/packages/kalm/tests/unit/routines/realtime.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kalm/tests/unit/routines/realtime.spec.ts b/packages/kalm/tests/unit/routines/realtime.spec.ts new file mode 100644 index 0000000..5a563f0 --- /dev/null +++ b/packages/kalm/tests/unit/routines/realtime.spec.ts @@ -0,0 +1,5 @@ +import realtime from '../../../src/routines/realtime'; + +describe('Realtime routine', () => { + it('TODO', () => { expect(realtime).not.toBeUndefined(); }); +}); diff --git a/packages/kalm/tests/unit/routines/tick.spec.js b/packages/kalm/tests/unit/routines/tick.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kalm/tests/unit/routines/tick.spec.ts b/packages/kalm/tests/unit/routines/tick.spec.ts new file mode 100644 index 0000000..5da6305 --- /dev/null +++ b/packages/kalm/tests/unit/routines/tick.spec.ts @@ -0,0 +1,5 @@ +import tick from '../../../src/routines/tick'; + +describe('Tick routine', () => { + it('TODO', () => { expect(tick).not.toBeUndefined(); }); +}); diff --git a/packages/kalm/tests/unit/utils/logger.spec.js b/packages/kalm/tests/unit/utils/logger.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kalm/tests/unit/utils/logger.spec.ts b/packages/kalm/tests/unit/utils/logger.spec.ts new file mode 100644 index 0000000..ccc2c4c --- /dev/null +++ b/packages/kalm/tests/unit/utils/logger.spec.ts @@ -0,0 +1,5 @@ +import logger from '../../../src/utils/logger'; + +describe('Logger util', () => { + it('TODO', () => { expect(logger).not.toBeUndefined(); }); +}); diff --git a/packages/kalm/tests/unit/utils/parser.spec.js b/packages/kalm/tests/unit/utils/parser.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/kalm/tests/unit/utils/parser.spec.ts b/packages/kalm/tests/unit/utils/parser.spec.ts new file mode 100644 index 0000000..19284c4 --- /dev/null +++ b/packages/kalm/tests/unit/utils/parser.spec.ts @@ -0,0 +1,5 @@ +import parser from '../../../src/utils/parser'; + +describe('Parser util', () => { + it('TODO', () => { expect(parser).not.toBeUndefined(); }); +}); diff --git a/packages/tcp/package.json b/packages/tcp/package.json index cf9a417..3eb9a86 100644 --- a/packages/tcp/package.json +++ b/packages/tcp/package.json @@ -2,10 +2,9 @@ "name": "@kalm/tcp", "version": "3.2.0", "description": "TCP transport for Kalm", - "main": "bin/tcp.min.js", + "main": "bin/tcp.js", "scripts": { - "build": "../../scripts/build.sh tcp", - "test": "mocha ./tests/unit --exit" + "build": "../../scripts/build.sh tcp" }, "repository": { "type": "git", @@ -32,7 +31,6 @@ "tcp" ], "typings": "./bin/types.d.ts", - "files": ["bin/tcp.min.js"], "author": "frederic charette ", "license": "Apache-2.0", "bugs": { @@ -44,9 +42,5 @@ ], "browser": { "net": false - }, - "devDependencies": { - "chai": "^4.2.0", - "mocha": "^6.2.0" } } \ No newline at end of file diff --git a/packages/tcp/tests/unit/tcp.spec.js b/packages/tcp/tests/unit/tcp.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/tcp/tests/unit/tcp.spec.ts b/packages/tcp/tests/unit/tcp.spec.ts new file mode 100644 index 0000000..e00cd5d --- /dev/null +++ b/packages/tcp/tests/unit/tcp.spec.ts @@ -0,0 +1,5 @@ +import tcp from '../../src/tcp'; + +describe('TCP transport', () => { + it('TODO', () => { expect(tcp).not.toBeUndefined(); }); +}); diff --git a/packages/udp/package.json b/packages/udp/package.json index bf97a7b..96f365f 100644 --- a/packages/udp/package.json +++ b/packages/udp/package.json @@ -2,10 +2,9 @@ "name": "@kalm/udp", "version": "3.2.0", "description": "UDP transport for Kalm", - "main": "bin/udp.min.js", + "main": "bin/udp.js", "scripts": { - "build": "../../scripts/build.sh udp", - "test": "mocha ./tests/unit --exit" + "build": "../../scripts/build.sh udp" }, "repository": { "type": "git", @@ -32,7 +31,6 @@ "udp" ], "typings": "./bin/types.d.ts", - "files": ["bin/udp.min.js"], "author": "frederic charette ", "license": "Apache-2.0", "bugs": { @@ -44,9 +42,5 @@ ], "browser": { "dgram": false - }, - "devDependencies": { - "chai": "^4.2.0", - "mocha": "^6.2.0" } } \ No newline at end of file diff --git a/packages/udp/tests/unit/udp.spec.js b/packages/udp/tests/unit/udp.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/udp/tests/unit/udp.spec.ts b/packages/udp/tests/unit/udp.spec.ts new file mode 100644 index 0000000..466e5ad --- /dev/null +++ b/packages/udp/tests/unit/udp.spec.ts @@ -0,0 +1,5 @@ +import udp from '../../src/udp'; + +describe('UDP transport', () => { + it('TODO', () => { expect(udp).not.toBeUndefined(); }); +}); diff --git a/packages/ws/package.json b/packages/ws/package.json index 2c5585a..8e3229f 100644 --- a/packages/ws/package.json +++ b/packages/ws/package.json @@ -2,10 +2,9 @@ "name": "@kalm/ws", "version": "3.2.0", "description": "WebSocket transport for Kalm", - "main": "bin/ws.min.js", + "main": "bin/ws.js", "scripts": { - "build": "../../scripts/build.sh ws", - "test": "mocha ./tests/unit --exit" + "build": "../../scripts/build.sh ws" }, "repository": { "type": "git", @@ -32,7 +31,6 @@ "ws" ], "typings": "./bin/types.d.ts", - "files": ["bin/ws.min.js"], "author": "frederic charette ", "license": "Apache-2.0", "bugs": { @@ -48,9 +46,5 @@ "browser": { "http": false, "https": false - }, - "devDependencies": { - "chai": "^4.2.0", - "mocha": "^6.2.0" } } diff --git a/packages/ws/src/ws.ts b/packages/ws/src/ws.ts index 2150cc9..ca3d3de 100644 --- a/packages/ws/src/ws.ts +++ b/packages/ws/src/ws.ts @@ -83,4 +83,4 @@ function ws({ cert, key, secure }: WSConfig = {}): KalmTransport { /* Exports -------------------------------------------------------------------*/ -module.exports = ws; +export default ws; diff --git a/packages/ws/tests/unit/ws.spec.js b/packages/ws/tests/unit/ws.spec.js deleted file mode 100644 index e69de29..0000000 diff --git a/packages/ws/tests/unit/ws.spec.ts b/packages/ws/tests/unit/ws.spec.ts new file mode 100644 index 0000000..319bad5 --- /dev/null +++ b/packages/ws/tests/unit/ws.spec.ts @@ -0,0 +1,5 @@ +import ws from '../../src/ws'; + +describe('WS transport', () => { + it('TODO', () => { expect(ws).not.toBeUndefined(); }); +}); diff --git a/scripts/benchmarks/transports/kalm.js b/scripts/benchmarks/transports/kalm.js index f89e69c..6b31008 100644 --- a/scripts/benchmarks/transports/kalm.js +++ b/scripts/benchmarks/transports/kalm.js @@ -6,13 +6,13 @@ /* Requires ------------------------------------------------------------------*/ const settings = require('../settings'); -const Kalm = require('../../../packages/kalm/bin/kalm.min'); +const Kalm = require('../../../packages/kalm/bin/kalm'); const transports = { - ipc: require('../../../packages/ipc/bin/ipc.min'), - tcp: require('../../../packages/tcp/bin/tcp.min'), - udp: require('../../../packages/udp/bin/udp.min'), - ws: require('../../../packages/ws/bin/ws.min'), + ipc: require('../../../packages/ipc/bin/ipc'), + tcp: require('../../../packages/tcp/bin/tcp'), + udp: require('../../../packages/udp/bin/udp'), + ws: require('../../../packages/ws/bin/ws'), }; /* Local variables -----------------------------------------------------------*/ diff --git a/tests/integration/index.spec.js b/tests/integration/index.spec.ts similarity index 85% rename from tests/integration/index.spec.js rename to tests/integration/index.spec.ts index 8024e2c..b1b5c59 100644 --- a/tests/integration/index.spec.js +++ b/tests/integration/index.spec.ts @@ -5,8 +5,7 @@ /* Requires ------------------------------------------------------------------*/ -const { expect } = require('chai'); -const Kalm = require('../../packages/kalm/bin/kalm.min'); +import Kalm from '../../packages/kalm/src/kalm'; /* Suite --------------------------------------------------------------------*/ @@ -14,7 +13,7 @@ describe('Integration tests', () => { ['ipc', 'tcp', 'udp', 'ws'].forEach((transport) => { describe(`Testing ${transport} transport`, () => { let server; - const soc = require(`../../packages/${transport}/bin/${transport}.min`)(); /* eslint-disable-line */ + const soc = require(`../../packages/${transport}/src/${transport}`).default(); /* eslint-disable-line */ /* --- Setup ---*/ @@ -38,7 +37,7 @@ describe('Integration tests', () => { const payload = { foo: 'bar' }; server.on('connection', (c) => { c.subscribe('test', (data) => { - expect(data).to.eql(payload); + expect(data).toEqual(payload); done(); }); }); @@ -55,7 +54,7 @@ describe('Integration tests', () => { server.on('connection', (c) => { c.subscribe('test.large', (data) => { - expect(data).to.eql(largePayload); + expect(data).toEqual(largePayload); done(); }); }); @@ -69,7 +68,7 @@ describe('Integration tests', () => { server.on('connection', (c) => { c.subscribe('test', () => { // Throw on purpose - expect(false).to.be.true; + expect(false).toBe(true); done(); }); diff --git a/tsconfig.json b/tsconfig.json index 9610ad3..d5c4c6a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,6 @@ ], "exclude": [ "node_modules", - "**/*.min.js" + "**/*.js" ] } \ No newline at end of file From 83fc1d254c55689205a86674ee3569a66e956bde Mon Sep 17 00:00:00 2001 From: frederic charette Date: Wed, 9 Oct 2019 11:59:45 -0400 Subject: [PATCH 3/9] cleaned up ts definition location, output bundle format --- .gitignore | 16 +- examples/typescript/client.ts | 8 +- examples/typescript/server.ts | 10 +- package.json | 1 + packages/ipc/bin/ipc.min.js | 59 ------- packages/ipc/package.json | 5 +- packages/kalm/bin/kalm.min.js | 317 ---------------------------------- packages/kalm/package.json | 5 +- packages/tcp/bin/tcp.min.js | 59 ------- packages/tcp/package.json | 5 +- packages/udp/bin/udp.min.js | 111 ------------ packages/udp/package.json | 5 +- packages/ws/bin/ws.min.js | 76 -------- packages/ws/package.json | 5 +- scripts/build.sh | 8 +- scripts/cleanup.sh | 6 + tsconfig.json | 4 +- types.d.ts | 8 +- 18 files changed, 56 insertions(+), 652 deletions(-) delete mode 100644 packages/ipc/bin/ipc.min.js delete mode 100644 packages/kalm/bin/kalm.min.js delete mode 100644 packages/tcp/bin/tcp.min.js delete mode 100644 packages/udp/bin/udp.min.js delete mode 100644 packages/ws/bin/ws.min.js create mode 100755 scripts/cleanup.sh diff --git a/.gitignore b/.gitignore index f25145c..ff39d9f 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,18 @@ NTH docs yarn.lock package-lock.json -.vscode \ No newline at end of file +.vscode + +# built code +packages/kalm/bin +packages/ipc/bin +packages/tcp/bin +packages/udp/bin +packages/ws/bin + +# built types reference +packages/kalm/types.d.ts +packages/ipc/types.d.ts +packages/tcp/types.d.ts +packages/udp/types.d.ts +packages/ws/types.d.ts \ No newline at end of file diff --git a/examples/typescript/client.ts b/examples/typescript/client.ts index 4aab8e8..8516b4f 100644 --- a/examples/typescript/client.ts +++ b/examples/typescript/client.ts @@ -1,10 +1,10 @@ -import { connect, routines, Client, Frame } from 'kalm'; +import kalm from 'kalm'; import ws from '@kalm/ws'; -const client: Client = connect({ +const client = kalm.connect({ transport: ws(), port: 3938, - routine: routines.realtime(), + routine: kalm.routines.realtime(), }); type MyCustomPayload = { @@ -12,7 +12,7 @@ type MyCustomPayload = { message: string }; -client.subscribe('r.evt', (body: MyCustomPayload, frame: Frame) => { +client.subscribe('r.evt', (body: MyCustomPayload, frame) => { console.log('Server event', body, frame); }); diff --git a/examples/typescript/server.ts b/examples/typescript/server.ts index 10191d8..9859ef1 100644 --- a/examples/typescript/server.ts +++ b/examples/typescript/server.ts @@ -1,10 +1,10 @@ -import { listen, routines, Provider, Client, Frame } from 'kalm'; +import kalm from 'kalm'; import ws from '@kalm/ws'; -const provider: Provider = listen({ +const provider = kalm.listen({ transport: ws(), port: 3938, - routine: routines.tick(5), + routine: kalm.routines.tick(5), host: '0.0.0.0', }); @@ -13,8 +13,8 @@ type MyCustomPayload = { message: string }; -provider.on('connection', (client: Client) => { - client.subscribe('foo', (body: MyCustomPayload, frame: Frame) => { +provider.on('connection', (client) => { + client.subscribe('foo', (body: MyCustomPayload, frame) => { console.log('Client event', body, frame); }); diff --git a/package.json b/package.json index cb0c735..f5b4051 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint:fix": "yarn lint --fix", "test": "jest ./packages && jest ./tests/integration --forceExit", "build": "yarn workspaces run build --ci", + "clean": "yarn workspaces run clean --ci", "bench": "node ./scripts/benchmarks" }, "repository": { diff --git a/packages/ipc/bin/ipc.min.js b/packages/ipc/bin/ipc.min.js deleted file mode 100644 index 41cb3f8..0000000 --- a/packages/ipc/bin/ipc.min.js +++ /dev/null @@ -1,59 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('net')) : - typeof define === 'function' && define.amd ? define(['net'], factory) : - (global = global || self, global.ipc = factory(global.net)); -}(this, function (net) { 'use strict'; - - net = net && net.hasOwnProperty('default') ? net['default'] : net; - - function ipc({ socketTimeout = 30000, path = '/tmp/app.socket-' } = {}) { - return function socket(params, emitter) { - let listener; - function bind() { - listener = net.createServer(soc => emitter.emit('socket', soc)); - listener.on('error', err => emitter.emit('error', err)); - listener.listen(path + params.port, () => emitter.emit('ready')); - } - function remote(handle) { - return { - host: handle['_server']._pipeName, - port: handle['_handle'].fd, - }; - } - function connect(handle) { - const connection = handle || net.connect(`${path}${params.port}`); - connection.on('data', req => emitter.emit('frame', req)); - connection.on('error', err => emitter.emit('error', err)); - connection.on('connect', () => emitter.emit('connect', connection)); - connection.on('close', () => emitter.emit('disconnect')); - connection.setTimeout(socketTimeout, () => emitter.emit('disconnect')); - return connection; - } - function stop() { - if (listener) - listener.close(); - } - function send(handle, payload) { - if (handle) - handle.write(Buffer.from(payload)); - } - function disconnect(handle) { - if (handle) { - handle.end(); - handle.destroy(); - } - } - return { - bind, - connect, - disconnect, - remote, - send, - stop, - }; - }; - } - - return ipc; - -})); diff --git a/packages/ipc/package.json b/packages/ipc/package.json index 3c01ac4..907a4ee 100644 --- a/packages/ipc/package.json +++ b/packages/ipc/package.json @@ -4,7 +4,8 @@ "description": "IPC transport for Kalm", "main": "bin/ipc.js", "scripts": { - "build": "../../scripts/build.sh ipc" + "build": "../../scripts/build.sh ipc", + "clean": "../../scripts/cleanup.sh" }, "repository": { "type": "git", @@ -32,7 +33,7 @@ ], "author": "frederic charette ", "license": "Apache-2.0", - "typings": "./bin/types.d.ts", + "typings": "./types.d.ts", "bugs": { "url": "https://github.com/kalm/kalm-js/issues" }, diff --git a/packages/kalm/bin/kalm.min.js b/packages/kalm/bin/kalm.min.js deleted file mode 100644 index 0965398..0000000 --- a/packages/kalm/bin/kalm.min.js +++ /dev/null @@ -1,317 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('events')) : - typeof define === 'function' && define.amd ? define(['events'], factory) : - (global = global || self, global.kalm = factory(global.events)); -}(this, function (events) { 'use strict'; - - const enabled = ((typeof process === 'object' && process.env.NODE_DEBUG) || - (typeof window === 'object' && window.DEBUG) || - '').indexOf('kalm') > -1; - function log(msg) { - if (enabled) - console.log(msg); - } - var logger = { log }; - - function serialize(frameId, channel, packets) { - const channelLen = channel.length; - const result = [frameId % 255, channelLen]; - for (let letter = 0; letter < channelLen; letter++) { - result.push(channel.charCodeAt(letter)); - } - result.push.apply(result, _uint16Size(packets.length)); - packets.forEach((packet) => { - if (!(packet instanceof Buffer)) - throw new Error(`Cannot send packet ${packet}. Must be of type Buffer`); - result.push.apply(result, _uint16Size(packet.length)); - result.push.apply(result, packet); - }); - return result; - } - function _uint16Size(value) { - return [value >>> 8, value & 0xff]; - } - function _numericSize(bytes, index) { - return (bytes[index] << 8) | bytes[index + 1]; - } - function deserialize(payload) { - const channelLength = payload[1]; - let caret = 4 + channelLength; - const totalPackets = _numericSize(payload, 2 + channelLength); - const result = { - channel: String.fromCharCode.apply(null, payload.slice(2, 2 + channelLength)), - frameId: payload[0], - packets: _parseFramePacket(), - payloadBytes: payload.length, - }; - function _parseFramePacket() { - const packets = []; - for (let p = 0; p < totalPackets; p++) { - if (caret >= payload.length) - continue; - const packetLength = _numericSize(payload, caret); - packets.push(payload.slice(2 + caret, 2 + packetLength + caret)); - caret = 2 + caret + packetLength; - } - return packets; - } - return result; - } - var parser = { serialize, deserialize }; - - function Client(params, emitter, handle) { - let connected = 1; - const channels = {}; - const socket = params.transport(params, emitter); - emitter.setMaxListeners(50); - function write(channel, message) { - emitter.emit('stats.packetWrite'); - return _resolveChannel(channel) - .queue.add(params.json === true ? Buffer.from(JSON.stringify(message)) : message); - } - function destroy() { - for (const channel in channels) - channels[channel].queue.flush(); - if (connected > 1) - setTimeout(() => socket.disconnect(handle), 0); - } - function subscribe(channel, handler) { - _resolveChannel(channel).emitter.on('message', handler); - } - function unsubscribe(channel, handler) { - if (!(channel in channels)) - return; - if (handler) - channels[channel].emitter.off('message', handler); - else - channels[channel].emitter.removeAllListeners('message'); - if (channels[channel].emitter.listenerCount('message') === 0) { - channels[channel].queue.flush(); - delete channels[channel]; - } - } - function remote() { - if (params.isServer) - return socket.remote(handle); - return { - host: params.host, - port: params.port, - }; - } - function local() { - if (params.isServer) { - return { - host: params.host, - port: params.port, - }; - } - return null; - } - function _createChannel(channel) { - const channelEmitter = new events.EventEmitter(); - return { - emitter: channelEmitter, - queue: params.routine(channel, params, channelEmitter), - }; - } - function _wrap(event) { - const payload = parser.serialize(event.frameId, event.channel, event.packets); - emitter.emit('stats.packetReady'); - socket.send(handle, payload); - } - function _resolveChannel(channel) { - if (!(channel in channels)) { - channels[channel] = _createChannel(channel); - channels[channel].emitter.on('runQueue', _wrap); - } - return channels[channel]; - } - function _handleConnect() { - connected = 2; - logger.log(`log: connected to ${params.host}:${params.port}`); - } - function _handleError(err) { - logger.log(`error: ${err.message}`); - } - function _handleRequest(payload) { - emitter.emit('stats.packetReceived'); - const frame = parser.deserialize(payload); - frame.packets.forEach((packet, i) => _handlePackets(frame, packet, i)); - } - function _handlePackets(frame, packet, index) { - if (packet.length === 0) - return; - const decodedPacket = (params.json === true) ? JSON.parse(packet.toString()) : packet; - emitter.emit('stats.packetDecoded'); - if (channels[frame.channel]) { - channels[frame.channel].emitter.emit('message', decodedPacket, { - client: params, - frame: { - channel: frame.channel, - id: frame.frameId, - messageIndex: index, - payloadBytes: frame.payloadBytes, - payloadMessages: frame.packets.length, - }, - }); - } - } - function _handleDisconnect() { - connected = 0; - logger.log(`log: lost connection to ${params.host}:${params.port}`); - } - emitter.on('connect', _handleConnect); - emitter.on('disconnect', _handleDisconnect); - emitter.on('error', _handleError); - emitter.on('frame', _handleRequest); - if (!handle) - logger.log(`log: connecting to ${params.host}:${params.port}`); - handle = socket.connect(handle); - return Object.assign(emitter, { write, destroy, subscribe, unsubscribe, remote, local, label: params.label }); - } - - function Provider(params, emitter) { - const connections = []; - const socket = params.transport(params, emitter); - function broadcast(channel, payload) { - connections.forEach(c => c.write(channel, payload)); - } - function stop() { - logger.log('warn: stopping server'); - connections.forEach(connection => connection.destroy()); - connections.length = 0; - socket.stop(); - } - function _handleError(err) { - logger.log(`error: ${err}`); - } - function handleConnection(handle) { - const origin = socket.remote(handle); - const client = Client({ - ...params, - host: origin.host, - isServer: true, - port: origin.port, - provider: { - broadcast, - connections, - label: params.label, - stop, - }, - }, new events.EventEmitter(), handle); - connections.push(client); - emitter.emit('connection', client); - logger.log(`log: connection from ${origin.host}:${origin.port}`); - } - emitter.on('socket', handleConnection); - emitter.on('error', _handleError); - logger.log(`log: listening on ${params.host}:${params.port}`); - socket.bind(); - return Object.assign(emitter, { label: params.label, port: params.port, broadcast, stop, connections }); - } - - function dynamic(hz) { - if (hz <= 0 || hz > 1000) { - throw new Error(`Unable to set Hertz value of ${hz}. Must be between 0.1e13 and 1000`); - } - return function queue(channel, params, emitter) { - let timer = null; - const packets = []; - let i = 0; - function add(packet) { - emitter.emit('stats.queueAdd', { frameId: i, packet: packets.length }); - if (timer === null) { - timer = setTimeout(_step, Math.round(1000 / hz)); - } - packets.push(packet); - } - function _step() { - emitter.emit('stats.queueRun', { frameId: i, packets: packets.length }); - clearTimeout(timer); - timer = null; - emitter.emit('runQueue', { frameId: i++, channel, packets }); - if (i > 255) - i = 0; - packets.length = 0; - } - function size() { return packets.length; } - return { add, size, flush: _step }; - }; - } - - function realtime() { - return function queue(channel, params, emitter) { - let i = 0; - function add(packet) { - emitter.emit('stats.queueAdd', { frameId: i, packet: 0 }); - emitter.emit('stats.queueRun', { frameId: i, packets: 1 }); - emitter.emit('runQueue', { frameId: i++, channel, packets: [packet] }); - if (i > 255) - i = 0; - } - function size() { return 0; } - function flush() { } - return { add, size, flush }; - }; - } - - function tick(hz, seed = Date.now()) { - if (hz <= 0 || hz > 1000) { - throw new Error(`Unable to set Hertz value of ${hz}. Must be between 0.1e13 and 1000`); - } - let i = 0; - function _delta() { - const now = Date.now() - seed; - i = (now / (1000 / hz)) % 255; - return Math.round(now % (1000 / hz)); - } - return function queue(channel, params, emitter) { - let timer = null; - const packets = []; - function add(packet) { - emitter.emit('stats.queueAdd', { frameId: i, packet: packets.length }); - if (timer === null) { - timer = setTimeout(_step, _delta()); - } - packets.push(packet); - } - function _step() { - emitter.emit('stats.queueRun', { frameId: i, packets: packets.length }); - clearTimeout(timer); - timer = null; - emitter.emit('runQueue', { frameId: i, channel, packets }); - packets.length = 0; - } - function size() { return packets.length; } - return { add, size, flush: _step }; - }; - } - - const defaults = { - host: '0.0.0.0', - json: true, - port: 3000, - routine: realtime(), - transport: null, - }; - function listen(options) { - options.label = options.label || Math.random().toString(36).substring(7); - return Provider({ ...defaults, ...options }, new events.EventEmitter()); - } - function connect(options) { - options.label = options.label || Math.random().toString(36).substring(7); - return Client({ ...defaults, ...options }, new events.EventEmitter()); - } - var kalm = { - connect, - listen, - routines: { - dynamic, - realtime, - tick, - }, - }; - - return kalm; - -})); diff --git a/packages/kalm/package.json b/packages/kalm/package.json index 3bb07ef..a649ed8 100644 --- a/packages/kalm/package.json +++ b/packages/kalm/package.json @@ -4,7 +4,8 @@ "description": "The socket optimizer", "main": "bin/kalm.js", "scripts": { - "build": "../../scripts/build.sh kalm" + "build": "../../scripts/build.sh kalm", + "clean": "../../scripts/cleanup.sh" }, "repository": { "type": "git", @@ -34,7 +35,7 @@ "ws", "core" ], - "typings": "./bin/types.d.ts", + "typings": "./types.d.ts", "author": "frederic charette ", "license": "Apache-2.0", "bugs": { diff --git a/packages/tcp/bin/tcp.min.js b/packages/tcp/bin/tcp.min.js deleted file mode 100644 index a60b7cc..0000000 --- a/packages/tcp/bin/tcp.min.js +++ /dev/null @@ -1,59 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('net')) : - typeof define === 'function' && define.amd ? define(['net'], factory) : - (global = global || self, global.tcp = factory(global.net)); -}(this, function (net) { 'use strict'; - - net = net && net.hasOwnProperty('default') ? net['default'] : net; - - function tcp({ socketTimeout = 30000 } = {}) { - return function socket(params, emitter) { - let listener; - function bind() { - listener = net.createServer(soc => emitter.emit('socket', soc)); - listener.on('error', err => emitter.emit('error', err)); - listener.listen(params.port, () => emitter.emit('ready')); - } - function remote(handle) { - return { - host: handle.remoteAddress, - port: handle.remotePort, - }; - } - function connect(handle) { - const connection = handle || net.connect(params.port, params.host); - connection.on('data', req => emitter.emit('frame', req)); - connection.on('error', err => emitter.emit('error', err)); - connection.on('connect', () => emitter.emit('connect', connection)); - connection.on('close', () => emitter.emit('disconnect')); - connection.setTimeout(socketTimeout, () => emitter.emit('disconnect')); - return connection; - } - function stop() { - if (listener) - listener.close(); - } - function send(handle, payload) { - if (handle) - handle.write(Buffer.from(payload)); - } - function disconnect(handle) { - if (handle) { - handle.end(); - handle.destroy(); - } - } - return { - bind, - connect, - disconnect, - remote, - send, - stop, - }; - }; - } - - return tcp; - -})); diff --git a/packages/tcp/package.json b/packages/tcp/package.json index 3eb9a86..98d286a 100644 --- a/packages/tcp/package.json +++ b/packages/tcp/package.json @@ -4,7 +4,8 @@ "description": "TCP transport for Kalm", "main": "bin/tcp.js", "scripts": { - "build": "../../scripts/build.sh tcp" + "build": "../../scripts/build.sh tcp", + "clean": "../../scripts/cleanup.sh" }, "repository": { "type": "git", @@ -30,7 +31,7 @@ "web", "tcp" ], - "typings": "./bin/types.d.ts", + "typings": "./types.d.ts", "author": "frederic charette ", "license": "Apache-2.0", "bugs": { diff --git a/packages/udp/bin/udp.min.js b/packages/udp/bin/udp.min.js deleted file mode 100644 index a8b051e..0000000 --- a/packages/udp/bin/udp.min.js +++ /dev/null @@ -1,111 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('dgram')) : - typeof define === 'function' && define.amd ? define(['dgram'], factory) : - (global = global || self, global.udp = factory(global.dgram)); -}(this, function (dgram) { 'use strict'; - - dgram = dgram && dgram.hasOwnProperty('default') ? dgram['default'] : dgram; - - function udp({ type = 'udp4', localAddr = '0.0.0.0', reuseAddr = true, socketTimeout = 30000, connectTimeout = 1000, } = {}) { - return function socket(params, emitter) { - let listener; - const clientCache = {}; - function addClient(client) { - const local = client.local(); - const key = `${local.host}.${local.port}`; - if (local.host === params.host && local.port === params.port) - return; - clientCache[key].client = client; - clientCache[key].timeout = setTimeout(client.destroy, socketTimeout); - for (let i = 0; i < clientCache[key].data.length; i++) { - clientCache[key].client.emit('frame', clientCache[key].data[i]); - } - clientCache[key].data.length = 0; - } - function resolveClient(origin, data) { - const handle = { - host: origin.address, - port: origin.port, - socket: listener, - }; - if (data[0] === 83 && data[1] === 89 && data[2] === 78) { - send(handle, Buffer.from('ACK')); - data = null; - } - const key = `${origin.address}.${origin.port}`; - clearTimeout(clientCache[key] && clientCache[key].timeout); - if (!clientCache[key]) { - clientCache[key] = { - client: null, - data: [], - timeout: null, - }; - emitter.emit('socket', handle); - } - if (data) { - if (clientCache[key].client) - clientCache[key].client.emit('frame', data); - else - clientCache[key].data.push(data); - } - } - function bind() { - listener = dgram.createSocket({ type: type, reuseAddr }); - listener.on('message', (data, origin) => resolveClient(origin, data)); - listener.on('error', err => emitter.emit('error', err)); - listener.bind(params.port, localAddr); - emitter.emit('ready'); - } - function remote(handle) { - return handle; - } - function send(handle, payload) { - if (handle) { - handle.socket.send(Buffer.from(payload), handle.port, handle.host); - } - } - function stop() { - listener.close(); - } - function connect(handle) { - if (handle) - return handle; - const connection = dgram.createSocket(type); - let timeout; - connection.on('error', err => emitter.emit('error', err)); - connection.on('message', req => { - if (req[0] === 65 && req[1] === 67 && req[2] === 75) { - clearTimeout(timeout); - emitter.emit('connect', connection); - } - else - emitter.emit('frame', req); - }); - connection.bind(null, localAddr); - const res = { - host: params.host, - port: params.port, - socket: connection, - }; - send(res, Buffer.from('SYN')); - timeout = setTimeout(() => disconnect(), connectTimeout); - return res; - } - function disconnect(handle) { - emitter.emit('disconnect'); - } - emitter.on('connection', addClient); - return { - bind, - connect, - disconnect, - remote, - send, - stop, - }; - }; - } - - return udp; - -})); diff --git a/packages/udp/package.json b/packages/udp/package.json index 96f365f..ea6c167 100644 --- a/packages/udp/package.json +++ b/packages/udp/package.json @@ -4,7 +4,8 @@ "description": "UDP transport for Kalm", "main": "bin/udp.js", "scripts": { - "build": "../../scripts/build.sh udp" + "build": "../../scripts/build.sh udp", + "clean": "../../scripts/cleanup.sh" }, "repository": { "type": "git", @@ -30,7 +31,7 @@ "web", "udp" ], - "typings": "./bin/types.d.ts", + "typings": "./types.d.ts", "author": "frederic charette ", "license": "Apache-2.0", "bugs": { diff --git a/packages/ws/bin/ws.min.js b/packages/ws/bin/ws.min.js deleted file mode 100644 index 4136031..0000000 --- a/packages/ws/bin/ws.min.js +++ /dev/null @@ -1,76 +0,0 @@ -(function (factory) { - typeof define === 'function' && define.amd ? define(factory) : - factory(); -}(function () { 'use strict'; - - const isBrowser = (typeof WebSocket !== 'undefined'); - const WS = isBrowser ? WebSocket : require('ws'); - function ws({ cert, key, secure } = {}) { - return function socket(params, emitter) { - let listener; - function bind() { - if (cert && key) { - const server = require('https').createServer({ key, cert }, req => req.socket.end()); - listener = new WS.Server({ port: params.port, server }); - } - else { - listener = new WS.Server({ port: params.port }); - } - listener.on('connection', soc => emitter.emit('socket', soc)); - listener.on('error', err => emitter.emit('error', err)); - emitter.emit('ready'); - } - function send(handle, payload) { - if (handle && handle.readyState === 1) { - handle.send(Buffer.from(payload)); - } - else { - handle['_queue'].push(payload); - } - } - function stop() { - if (listener) - listener.close(); - } - function connect(handle) { - const protocol = secure === true ? 'wss' : 'ws'; - const connection = handle || new WS(`${protocol}://${params.host}:${params.port}`); - connection.binaryType = 'arraybuffer'; - const evtType = isBrowser ? 'addEventListener' : 'on'; - connection['_queue'] = []; - connection[evtType]('message', evt => emitter.emit('frame', Buffer.from(evt.data || evt))); - connection[evtType]('error', err => emitter.emit('error', err)); - connection[evtType]('close', () => emitter.emit('disconnect')); - connection[evtType]('open', () => { - connection['_queue'].forEach(payload => send(connection, payload)); - emitter.emit('connect', connection); - }); - return connection; - } - function remote(handle) { - const h = handle['headers']; - return { - host: ((h && h['x-forwarded-for'] && h['x-forwarded-for'].split(',')[0]) || - (handle['connection'] && handle['connection'].remoteAddress || '0.0.0.0')), - port: handle['connection'] && handle['connection'].remotePort || 0 - }; - } - function disconnect(handle) { - if (handle) { - handle.end(); - handle.close(); - } - } - return { - bind, - connect, - disconnect, - remote, - send, - stop, - }; - }; - } - module.exports = ws; - -})); diff --git a/packages/ws/package.json b/packages/ws/package.json index 8e3229f..a081369 100644 --- a/packages/ws/package.json +++ b/packages/ws/package.json @@ -4,7 +4,8 @@ "description": "WebSocket transport for Kalm", "main": "bin/ws.js", "scripts": { - "build": "../../scripts/build.sh ws" + "build": "../../scripts/build.sh ws", + "clean": "../../scripts/cleanup.sh" }, "repository": { "type": "git", @@ -30,7 +31,7 @@ "web", "ws" ], - "typings": "./bin/types.d.ts", + "typings": "./types.d.ts", "author": "frederic charette ", "license": "Apache-2.0", "bugs": { diff --git a/scripts/build.sh b/scripts/build.sh index 824707c..9ae04ad 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,9 +1,9 @@ +#!/bin/sh + echo "Building" $1 -mkdir -p ./bin -rm -rf ./bin/* +../../scripts/cleanup.sh cp ../../tsconfig.json ./tsconfig.json +cp ../../types.d.ts ./types.d.ts ../../node_modules/typescript/bin/tsc --outDir ./bin -echo "Copying .d.ts file to bin" -cp ../../types.d.ts ./bin/types.d.ts echo "Build completed, cleaning up" rm -rf ./tsconfig.json \ No newline at end of file diff --git a/scripts/cleanup.sh b/scripts/cleanup.sh new file mode 100755 index 0000000..a822ae9 --- /dev/null +++ b/scripts/cleanup.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +mkdir -p ./bin +rm -rf ./bin/* +rm -rf ./tsconfig.json +rm -rf ./types.d.ts \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index d5c4c6a..b95efa0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "module": "esnext", + "module": "none", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "noImplicitAny": false, @@ -8,7 +8,7 @@ "preserveConstEnums": true, "sourceMap": false, "allowJs": true, - "target": "esnext", + "target": "es2019", "outDir": "dist" }, "include": [ diff --git a/types.d.ts b/types.d.ts index 5764950..5d257c0 100644 --- a/types.d.ts +++ b/types.d.ts @@ -35,8 +35,8 @@ interface Provider extends NodeJS.EventEmitter { interface Client extends NodeJS.EventEmitter { write: (channel: string, message: Serializable) => void destroy: () => void - subscribe: (channel: string, handler: () => void) => void - unsubscribe: (channel: string, handler: () => void) => void + subscribe: (channel: string, handler: (body: any, frame: Frame) => any) => void + unsubscribe: (channel: string, handler: (body: any, frame: Frame) => any) => void local: () => Remote remote: () => Remote } @@ -68,14 +68,14 @@ type UDPClientList = { type SocketHandle = NodeJS.Socket | UDPSocketHandle | WebSocket -type KalmRoutine = (channel: string, params: any, emitter: NodeJS.EventEmitter) => Queue +interface KalmRoutine { (channel: string, params: any, emitter: NodeJS.EventEmitter): Queue } interface Queue { add: (packet: Buffer) => void size: () => number flush: () => void } -type KalmTransport = (params: any, emitter: NodeJS.EventEmitter) => Socket +interface KalmTransport { (params: any, emitter: NodeJS.EventEmitter): Socket } interface Socket { bind: () => void remote: (handle: SocketHandle) => Remote From fe84490f96533e8e0c7a8dca220debf6a82097f9 Mon Sep 17 00:00:00 2001 From: frederic charette Date: Thu, 10 Oct 2019 08:16:50 -0400 Subject: [PATCH 4/9] fixed linting, completed jest migration, fixed pipeline --- .eslintignore | 2 +- .eslintrc | 7 +- .travis.yml | 1 + package.json | 2 +- packages/ipc/src/ipc.ts | 4 +- packages/ipc/tests/unit/ipc.spec.ts | 2 +- packages/kalm/src/components/client.ts | 136 +++++++++--------- packages/kalm/src/components/provider.ts | 10 +- packages/kalm/src/kalm.ts | 10 +- packages/kalm/src/routines/dynamic.ts | 56 ++++---- packages/kalm/src/routines/realtime.ts | 24 ++-- packages/kalm/src/routines/tick.ts | 62 ++++---- packages/kalm/src/utils/logger.ts | 8 +- packages/kalm/src/utils/parser.ts | 35 ++--- .../kalm/tests/unit/components/client.spec.ts | 2 +- .../tests/unit/components/provider.spec.ts | 2 +- .../kalm/tests/unit/routines/dynamic.spec.ts | 2 +- .../kalm/tests/unit/routines/realtime.spec.ts | 2 +- .../kalm/tests/unit/routines/tick.spec.ts | 2 +- packages/kalm/tests/unit/utils/logger.spec.ts | 2 +- packages/kalm/tests/unit/utils/parser.spec.ts | 2 +- packages/tcp/tests/unit/tcp.spec.ts | 2 +- packages/udp/src/udp.ts | 85 +++++------ packages/udp/tests/unit/udp.spec.ts | 2 +- packages/ws/src/ws.ts | 14 +- packages/ws/tests/unit/ws.spec.ts | 2 +- scripts/benchmarks/transports/kalm.js | 6 +- tests/integration/index.spec.ts | 20 +-- types.d.ts | 2 +- 29 files changed, 264 insertions(+), 242 deletions(-) diff --git a/.eslintignore b/.eslintignore index 8324a63..538a687 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,4 @@ -**/*.min.js +*.js examples node_modules scripts \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 8dee611..f57c7cf 100644 --- a/.eslintrc +++ b/.eslintrc @@ -17,6 +17,11 @@ "object-curly-newline": 0, "no-plusplus": 0, "no-unused-expressions": 0, + "guard-for-in": 0, + "no-mixed-operators": 0, + "no-param-reassign": 0, + "arrow-parens": [2, "as-needed"], + "no-continue": 0, "no-unused-vars": 0, "global-require": 0, "@typescript-eslint/no-unused-vars": [ @@ -27,7 +32,7 @@ }, "env": { "browser": true, - "mocha": true, + "jest": true, "node": true } } \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 9586e22..9826605 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ node_js: script: - yarn run lint - yarn run test + - yarn run build - yarn run bench sudo: false install: diff --git a/package.json b/package.json index f5b4051..6a88aca 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "description": "The socket optimizer", "main": "packages/kalm/bin/kalm.js", "scripts": { - "lint": "eslint .", + "lint": "eslint **/*.ts **/*.spec.ts", "lint:fix": "yarn lint --fix", "test": "jest ./packages && jest ./tests/integration --forceExit", "build": "yarn workspaces run build --ci", diff --git a/packages/ipc/src/ipc.ts b/packages/ipc/src/ipc.ts index c01c986..e9bb874 100644 --- a/packages/ipc/src/ipc.ts +++ b/packages/ipc/src/ipc.ts @@ -16,8 +16,8 @@ function ipc({ socketTimeout = 30000, path = '/tmp/app.socket-' }: IPCConfig = { function remote(handle: net.Socket): Remote { return { - host: handle['_server']._pipeName, - port: handle['_handle'].fd, + host: handle._server._pipeName, + port: handle._handle.fd, }; } diff --git a/packages/ipc/tests/unit/ipc.spec.ts b/packages/ipc/tests/unit/ipc.spec.ts index 948a7e6..03d1d35 100644 --- a/packages/ipc/tests/unit/ipc.spec.ts +++ b/packages/ipc/tests/unit/ipc.spec.ts @@ -1,5 +1,5 @@ import ipc from '../../src/ipc'; describe('IPC transport', () => { - it('TODO', () => { expect(ipc).not.toBeUndefined(); }); + it('TODO', () => { expect(ipc).not.toBeUndefined(); }); }); diff --git a/packages/kalm/src/components/client.ts b/packages/kalm/src/components/client.ts index 94ba43c..66148e7 100644 --- a/packages/kalm/src/components/client.ts +++ b/packages/kalm/src/components/client.ts @@ -1,8 +1,8 @@ /* Requires ------------------------------------------------------------------*/ +import { EventEmitter } from 'events'; import logger from '../utils/logger'; import parser from '../utils/parser'; -import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ @@ -12,55 +12,12 @@ function Client(params: ClientConfig, emitter: EventEmitter, handle?: SocketHand const socket: Socket = params.transport(params, emitter); emitter.setMaxListeners(50); - function write(channel: string, message: Serializable): void { - emitter.emit('stats.packetWrite'); - return _resolveChannel(channel) - .queue.add(params.json === true ? Buffer.from(JSON.stringify(message)) : message as Buffer); - } - - function destroy(): void { - for (const channel in channels) channels[channel].queue.flush(); - if (connected > 1) setTimeout(() => socket.disconnect(handle), 0); - } - - function subscribe(channel: string, handler: (msg: T, frame: Frame) => void): void { - _resolveChannel(channel).emitter.on('message', handler); - } - - function unsubscribe(channel: string, handler?: (msg: T, frame: Frame) => void): void { - if (!(channel in channels)) return; - if (handler) channels[channel].emitter.off('message', handler); - else channels[channel].emitter.removeAllListeners('message'); - if (channels[channel].emitter.listenerCount('message') === 0) { - channels[channel].queue.flush(); - delete channels[channel]; - } - } - - function remote(): Remote { - if (params.isServer) return socket.remote(handle); - return { - host: params.host, - port: params.port, - }; - } - - function local(): Remote { - if (params.isServer) { - return { - host: params.host, - port: params.port, - }; - } - return null; - } - function _createChannel(channel: string): Channel { const channelEmitter: EventEmitter = new EventEmitter(); return { - emitter: channelEmitter, - queue: params.routine(channel, params, channelEmitter), + emitter: channelEmitter, + queue: params.routine(channel, params, channelEmitter), }; } @@ -72,27 +29,12 @@ function Client(params: ClientConfig, emitter: EventEmitter, handle?: SocketHand function _resolveChannel(channel: string): Channel { if (!(channel in channels)) { - channels[channel] = _createChannel(channel); - channels[channel].emitter.on('runQueue', _wrap); + channels[channel] = _createChannel(channel); + channels[channel].emitter.on('runQueue', _wrap); } return channels[channel]; } - function _handleConnect(): void { - connected = 2; - logger.log(`log: connected to ${params.host}:${params.port}`); - } - - function _handleError(err: Error): void { - logger.log(`error: ${err.message}`); - } - - function _handleRequest(payload: Buffer): void { - emitter.emit('stats.packetReceived'); - const frame: RawFrame = parser.deserialize(payload); - frame.packets.forEach((packet, i) => _handlePackets(frame, packet, i)); - } - function _handlePackets(frame: RawFrame, packet: Buffer, index: number): Promise { if (packet.length === 0) return; const decodedPacket = (params.json === true) ? JSON.parse(packet.toString()) : packet; @@ -115,11 +57,69 @@ function Client(params: ClientConfig, emitter: EventEmitter, handle?: SocketHand } } + function _handleConnect(): void { + connected = 2; + logger.log(`log: connected to ${params.host}:${params.port}`); + } + + function _handleError(err: Error): void { + logger.log(`error: ${err.message}`); + } + + function _handleRequest(payload: Buffer): void { + emitter.emit('stats.packetReceived'); + const frame: RawFrame = parser.deserialize(payload); + frame.packets.forEach((packet, i) => _handlePackets(frame, packet, i)); + } + function _handleDisconnect() { connected = 0; logger.log(`log: lost connection to ${params.host}:${params.port}`); } + function write(channel: string, message: Serializable): void { + emitter.emit('stats.packetWrite'); + return _resolveChannel(channel) + .queue.add(params.json === true ? Buffer.from(JSON.stringify(message)) : message as Buffer); + } + + function destroy(): void { + Object.keys(channels).forEach(channel => channels[channel].queue.flush()); + if (connected > 1) setTimeout(() => socket.disconnect(handle), 0); + } + + function subscribe(channel: string, handler: (msg: any, frame: Frame) => void): void { + _resolveChannel(channel).emitter.on('message', handler); + } + + function unsubscribe(channel: string, handler?: (msg: any, frame: Frame) => void): void { + if (!(channel in channels)) return; + if (handler) channels[channel].emitter.off('message', handler); + else channels[channel].emitter.removeAllListeners('message'); + if (channels[channel].emitter.listenerCount('message') === 0) { + channels[channel].queue.flush(); + delete channels[channel]; + } + } + + function remote(): Remote { + if (params.isServer) return socket.remote(handle); + return { + host: params.host, + port: params.port, + }; + } + + function local(): Remote { + if (params.isServer) { + return { + host: params.host, + port: params.port, + }; + } + return null; + } + emitter.on('connect', _handleConnect); emitter.on('disconnect', _handleDisconnect); emitter.on('error', _handleError); @@ -127,7 +127,15 @@ function Client(params: ClientConfig, emitter: EventEmitter, handle?: SocketHand if (!handle) logger.log(`log: connecting to ${params.host}:${params.port}`); handle = socket.connect(handle); - return Object.assign(emitter, { write, destroy, subscribe, unsubscribe, remote, local, label: params.label }); + return Object.assign(emitter, { + write, + destroy, + subscribe, + unsubscribe, + remote, + local, + label: params.label, + }); } /* Exports -------------------------------------------------------------------*/ diff --git a/packages/kalm/src/components/provider.ts b/packages/kalm/src/components/provider.ts index 7ae949f..27f22d7 100644 --- a/packages/kalm/src/components/provider.ts +++ b/packages/kalm/src/components/provider.ts @@ -1,8 +1,8 @@ /* Requires ------------------------------------------------------------------*/ +import { EventEmitter } from 'events'; import logger from '../utils/logger'; import Client from './client'; -import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ @@ -52,7 +52,13 @@ function Provider(params: ClientConfig, emitter: EventEmitter): Provider { logger.log(`log: listening on ${params.host}:${params.port}`); socket.bind(); - return Object.assign(emitter, { label: params.label, port: params.port, broadcast, stop, connections }); + return Object.assign(emitter, { + label: params.label, + port: params.port, + broadcast, + stop, + connections, + }); } /* Exports -------------------------------------------------------------------*/ diff --git a/packages/kalm/src/kalm.ts b/packages/kalm/src/kalm.ts index 6a799f4..5912841 100644 --- a/packages/kalm/src/kalm.ts +++ b/packages/kalm/src/kalm.ts @@ -1,12 +1,12 @@ /* Requires ------------------------------------------------------------------*/ +import { EventEmitter } from 'events'; import client from './components/client'; import provider from './components/provider'; import dynamic from './routines/dynamic'; import realtime from './routines/realtime'; import tick from './routines/tick'; -import { EventEmitter } from 'events'; /* Local variables -----------------------------------------------------------*/ @@ -20,14 +20,14 @@ const defaults = { /* Methods -------------------------------------------------------------------*/ +const uniqueLabel = () => Math.random().toString(36).substring(7); + function listen(options: ProviderConfig): Provider { - options.label = options.label || Math.random().toString(36).substring(7); - return provider({ ...defaults, ...options }, new EventEmitter()); + return provider({ label: uniqueLabel(), ...defaults, ...options }, new EventEmitter()); } function connect(options: ClientConfig): Client { - options.label = options.label || Math.random().toString(36).substring(7); - return client({ ...defaults, ...options }, new EventEmitter()); + return client({ label: uniqueLabel(), ...defaults, ...options }, new EventEmitter()); } /* Exports -------------------------------------------------------------------*/ diff --git a/packages/kalm/src/routines/dynamic.ts b/packages/kalm/src/routines/dynamic.ts index 2c81618..26e7191 100644 --- a/packages/kalm/src/routines/dynamic.ts +++ b/packages/kalm/src/routines/dynamic.ts @@ -5,36 +5,36 @@ import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ function dynamic(hz: number): KalmRoutine { - if (hz <= 0 || hz > 1000) { - throw new Error(`Unable to set Hertz value of ${hz}. Must be between 0.1e13 and 1000`); + if (hz <= 0 || hz > 1000) { + throw new Error(`Unable to set Hertz value of ${hz}. Must be between 0.1e13 and 1000`); + } + + return function queue(channel: string, params: object, emitter: EventEmitter): Queue { + let timer: NodeJS.Timer = null; + const packets: Buffer[] = []; + let i: number = 0; + + function _step(): void { + emitter.emit('stats.queueRun', { frameId: i, packets: packets.length }); + clearTimeout(timer); + timer = null; + emitter.emit('runQueue', { frameId: i++, channel, packets }); + if (i > 255) i = 0; + packets.length = 0; } - return function queue(channel: string, params: object, emitter: EventEmitter): Queue { - let timer: NodeJS.Timer = null; - const packets: Buffer[] = []; - let i: number = 0; - - function add(packet: Buffer): void { - emitter.emit('stats.queueAdd', { frameId: i, packet: packets.length }); - if (timer === null) { - timer = setTimeout(_step, Math.round(1000 / hz)); - } - packets.push(packet); - } - - function _step(): void { - emitter.emit('stats.queueRun', { frameId: i, packets: packets.length }); - clearTimeout(timer); - timer = null; - emitter.emit('runQueue', { frameId: i++, channel, packets }); - if (i > 255) i = 0; - packets.length = 0; - } - - function size(): number { return packets.length; } - - return { add, size, flush: _step }; - }; + function add(packet: Buffer): void { + emitter.emit('stats.queueAdd', { frameId: i, packet: packets.length }); + if (timer === null) { + timer = setTimeout(_step, Math.round(1000 / hz)); + } + packets.push(packet); + } + + function size(): number { return packets.length; } + + return { add, size, flush: _step }; + }; } /* Exports -------------------------------------------------------------------*/ diff --git a/packages/kalm/src/routines/realtime.ts b/packages/kalm/src/routines/realtime.ts index 570b119..ad44dc5 100644 --- a/packages/kalm/src/routines/realtime.ts +++ b/packages/kalm/src/routines/realtime.ts @@ -5,21 +5,21 @@ import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ function realtime(): KalmRoutine { - return function queue(channel: string, params: object, emitter: EventEmitter): Queue { - let i: number = 0; + return function queue(channel: string, params: object, emitter: EventEmitter): Queue { + let i: number = 0; - function add(packet: Buffer): void { - emitter.emit('stats.queueAdd', { frameId: i, packet: 0 }); - emitter.emit('stats.queueRun', { frameId: i, packets: 1 }); - emitter.emit('runQueue', { frameId: i++, channel, packets: [packet] }); - if (i > 255) i = 0; - } + function add(packet: Buffer): void { + emitter.emit('stats.queueAdd', { frameId: i, packet: 0 }); + emitter.emit('stats.queueRun', { frameId: i, packets: 1 }); + emitter.emit('runQueue', { frameId: i++, channel, packets: [packet] }); + if (i > 255) i = 0; + } - function size(): number { return 0; } - function flush(): void {} + function size(): number { return 0; } + function flush(): void {} - return { add, size, flush }; - }; + return { add, size, flush }; + }; } /* Exports -------------------------------------------------------------------*/ diff --git a/packages/kalm/src/routines/tick.ts b/packages/kalm/src/routines/tick.ts index 36a6779..68a5f92 100644 --- a/packages/kalm/src/routines/tick.ts +++ b/packages/kalm/src/routines/tick.ts @@ -5,41 +5,41 @@ import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ function tick(hz: number, seed: number = Date.now()): KalmRoutine { - if (hz <= 0 || hz > 1000) { - throw new Error(`Unable to set Hertz value of ${hz}. Must be between 0.1e13 and 1000`); + if (hz <= 0 || hz > 1000) { + throw new Error(`Unable to set Hertz value of ${hz}. Must be between 0.1e13 and 1000`); + } + let i: number = 0; + + function _delta(): number { + const now: number = Date.now() - seed; + i = (now / (1000 / hz)) % 255; + return Math.round(now % (1000 / hz)); + } + + return function queue(channel: string, params: object, emitter: EventEmitter): Queue { + let timer: NodeJS.Timer = null; + const packets: Buffer[] = []; + + function _step(): void { + emitter.emit('stats.queueRun', { frameId: i, packets: packets.length }); + clearTimeout(timer); + timer = null; + emitter.emit('runQueue', { frameId: i, channel, packets }); + packets.length = 0; } - let i: number = 0; - function _delta(): number { - const now: number = Date.now() - seed; - i = (now / (1000 / hz)) % 255; - return Math.round(now % (1000 / hz)); + function add(packet: Buffer): void { + emitter.emit('stats.queueAdd', { frameId: i, packet: packets.length }); + if (timer === null) { + timer = setTimeout(_step, _delta()); + } + packets.push(packet); } - return function queue(channel: string, params: object, emitter: EventEmitter): Queue { - let timer: NodeJS.Timer = null; - const packets: Buffer[] = []; - - function add(packet: Buffer): void { - emitter.emit('stats.queueAdd', { frameId: i, packet: packets.length }); - if (timer === null) { - timer = setTimeout(_step, _delta()); - } - packets.push(packet); - } - - function _step(): void { - emitter.emit('stats.queueRun', { frameId: i, packets: packets.length }); - clearTimeout(timer); - timer = null; - emitter.emit('runQueue', { frameId: i, channel, packets }); - packets.length = 0; - } - - function size(): number { return packets.length; } - - return { add, size, flush: _step }; - }; + function size(): number { return packets.length; } + + return { add, size, flush: _step }; + }; } /* Exports -------------------------------------------------------------------*/ diff --git a/packages/kalm/src/utils/logger.ts b/packages/kalm/src/utils/logger.ts index 3271e62..6c86a16 100644 --- a/packages/kalm/src/utils/logger.ts +++ b/packages/kalm/src/utils/logger.ts @@ -3,15 +3,15 @@ declare const window: any; const enabled: boolean = ( - (typeof process === 'object' && process.env.NODE_DEBUG) || - (typeof window === 'object' && window.DEBUG) || - '' + (typeof process === 'object' && process.env.NODE_DEBUG) + || (typeof window === 'object' && window.DEBUG) + || '' ).indexOf('kalm') > -1; /* Methods -------------------------------------------------------------------*/ function log(msg: string): void { - if (enabled) console.log(msg); + if (enabled) console.log(msg); // eslint-disable-line no-console } /* Exports --------------------------------------------------------------------*/ diff --git a/packages/kalm/src/utils/parser.ts b/packages/kalm/src/utils/parser.ts index b79d2a0..8feb08f 100644 --- a/packages/kalm/src/utils/parser.ts +++ b/packages/kalm/src/utils/parser.ts @@ -1,5 +1,13 @@ /* Methods -------------------------------------------------------------------*/ +function _uint16Size(value: number): number[] { + return [value >>> 8, value & 0xff]; +} + +function _numericSize(bytes: Buffer, index: number): number { + return (bytes[index] << 8) | bytes[index + 1]; +} + function serialize(frameId: number, channel: string, packets: Buffer[]): number[] { const channelLen: number = channel.length; const result: number[] = [frameId % 255, channelLen]; @@ -8,35 +16,21 @@ function serialize(frameId: number, channel: string, packets: Buffer[]): number[ result.push(channel.charCodeAt(letter)); } - result.push.apply(result, _uint16Size(packets.length)); + result.push(..._uint16Size(packets.length)); packets.forEach((packet: Buffer) => { if (!(packet instanceof Buffer)) throw new Error(`Cannot send packet ${packet}. Must be of type Buffer`); - result.push.apply(result, _uint16Size(packet.length)); - result.push.apply(result, packet); + result.push(..._uint16Size(packet.length)); + result.push(...packet); }); return result; } -function _uint16Size(value: number): number[] { - return [value >>> 8, value & 0xff]; -} - -function _numericSize(bytes: Buffer, index: number): number { - return (bytes[index] << 8) | bytes[index + 1]; -} - function deserialize(payload: Buffer): RawFrame { const channelLength = payload[1]; let caret = 4 + channelLength; const totalPackets = _numericSize(payload, 2 + channelLength); - const result = { - channel: String.fromCharCode.apply(null, payload.slice(2, 2 + channelLength)), - frameId: payload[0], - packets: _parseFramePacket(), - payloadBytes: payload.length, - }; function _parseFramePacket(): Buffer[] { const packets: Buffer[] = []; @@ -49,6 +43,13 @@ function deserialize(payload: Buffer): RawFrame { return packets; } + const result = { + channel: String.fromCharCode(...payload.slice(2, 2 + channelLength)), + frameId: payload[0], + packets: _parseFramePacket(), + payloadBytes: payload.length, + }; + return result; } diff --git a/packages/kalm/tests/unit/components/client.spec.ts b/packages/kalm/tests/unit/components/client.spec.ts index f895aab..ee9bddc 100644 --- a/packages/kalm/tests/unit/components/client.spec.ts +++ b/packages/kalm/tests/unit/components/client.spec.ts @@ -1,5 +1,5 @@ import client from '../../../src/components/client'; describe('Client', () => { - it('TODO', () => { expect(client).not.toBeUndefined(); }); + it('TODO', () => { expect(client).not.toBeUndefined(); }); }); diff --git a/packages/kalm/tests/unit/components/provider.spec.ts b/packages/kalm/tests/unit/components/provider.spec.ts index 00d93c4..9e0787d 100644 --- a/packages/kalm/tests/unit/components/provider.spec.ts +++ b/packages/kalm/tests/unit/components/provider.spec.ts @@ -1,5 +1,5 @@ import provider from '../../../src/components/provider'; describe('Provider', () => { - it('TODO', () => { expect(provider).not.toBeUndefined(); }); + it('TODO', () => { expect(provider).not.toBeUndefined(); }); }); diff --git a/packages/kalm/tests/unit/routines/dynamic.spec.ts b/packages/kalm/tests/unit/routines/dynamic.spec.ts index c700667..5eb2890 100644 --- a/packages/kalm/tests/unit/routines/dynamic.spec.ts +++ b/packages/kalm/tests/unit/routines/dynamic.spec.ts @@ -1,5 +1,5 @@ import dynamic from '../../../src/routines/dynamic'; describe('Dynamic routine', () => { - it('TODO', () => { expect(dynamic).not.toBeUndefined(); }); + it('TODO', () => { expect(dynamic).not.toBeUndefined(); }); }); diff --git a/packages/kalm/tests/unit/routines/realtime.spec.ts b/packages/kalm/tests/unit/routines/realtime.spec.ts index 5a563f0..3d2fbc5 100644 --- a/packages/kalm/tests/unit/routines/realtime.spec.ts +++ b/packages/kalm/tests/unit/routines/realtime.spec.ts @@ -1,5 +1,5 @@ import realtime from '../../../src/routines/realtime'; describe('Realtime routine', () => { - it('TODO', () => { expect(realtime).not.toBeUndefined(); }); + it('TODO', () => { expect(realtime).not.toBeUndefined(); }); }); diff --git a/packages/kalm/tests/unit/routines/tick.spec.ts b/packages/kalm/tests/unit/routines/tick.spec.ts index 5da6305..eb1fe66 100644 --- a/packages/kalm/tests/unit/routines/tick.spec.ts +++ b/packages/kalm/tests/unit/routines/tick.spec.ts @@ -1,5 +1,5 @@ import tick from '../../../src/routines/tick'; describe('Tick routine', () => { - it('TODO', () => { expect(tick).not.toBeUndefined(); }); + it('TODO', () => { expect(tick).not.toBeUndefined(); }); }); diff --git a/packages/kalm/tests/unit/utils/logger.spec.ts b/packages/kalm/tests/unit/utils/logger.spec.ts index ccc2c4c..4c8ae82 100644 --- a/packages/kalm/tests/unit/utils/logger.spec.ts +++ b/packages/kalm/tests/unit/utils/logger.spec.ts @@ -1,5 +1,5 @@ import logger from '../../../src/utils/logger'; describe('Logger util', () => { - it('TODO', () => { expect(logger).not.toBeUndefined(); }); + it('TODO', () => { expect(logger).not.toBeUndefined(); }); }); diff --git a/packages/kalm/tests/unit/utils/parser.spec.ts b/packages/kalm/tests/unit/utils/parser.spec.ts index 19284c4..d08c58f 100644 --- a/packages/kalm/tests/unit/utils/parser.spec.ts +++ b/packages/kalm/tests/unit/utils/parser.spec.ts @@ -1,5 +1,5 @@ import parser from '../../../src/utils/parser'; describe('Parser util', () => { - it('TODO', () => { expect(parser).not.toBeUndefined(); }); + it('TODO', () => { expect(parser).not.toBeUndefined(); }); }); diff --git a/packages/tcp/tests/unit/tcp.spec.ts b/packages/tcp/tests/unit/tcp.spec.ts index e00cd5d..f7e6477 100644 --- a/packages/tcp/tests/unit/tcp.spec.ts +++ b/packages/tcp/tests/unit/tcp.spec.ts @@ -1,5 +1,5 @@ import tcp from '../../src/tcp'; describe('TCP transport', () => { - it('TODO', () => { expect(tcp).not.toBeUndefined(); }); + it('TODO', () => { expect(tcp).not.toBeUndefined(); }); }); diff --git a/packages/udp/src/udp.ts b/packages/udp/src/udp.ts index d4ed2a2..1edae41 100644 --- a/packages/udp/src/udp.ts +++ b/packages/udp/src/udp.ts @@ -25,45 +25,6 @@ function udp({ type = 'udp4', localAddr = '0.0.0.0', reuseAddr = true, socketTim clientCache[key].data.length = 0; } - function resolveClient(origin, data) { - const handle: UDPSocketHandle = { - host: origin.address, - port: origin.port, - socket: listener, - }; - - // Handle SYN - if (data[0] === 83 && data[1] === 89 && data[2] === 78) { - send(handle, Buffer.from('ACK')); - data = null; - } - - const key: string = `${origin.address}.${origin.port}`; - clearTimeout(clientCache[key] && clientCache[key].timeout); - - if (!clientCache[key]) { - clientCache[key] = { - client: null, - data: [], - timeout: null, - } as UDPClient; - emitter.emit('socket', handle); - } - - if (data) { - if (clientCache[key].client) clientCache[key].client.emit('frame', data); - else clientCache[key].data.push(data); - } - } - - function bind(): void { - listener = dgram.createSocket({ type: type as dgram.SocketType, reuseAddr }); - listener.on('message', (data, origin) => resolveClient(origin, data)); - listener.on('error', err => emitter.emit('error', err)); - listener.bind(params.port, localAddr); - emitter.emit('ready'); - } - function remote(handle: SocketHandle): Remote { return handle as Remote; } @@ -78,6 +39,11 @@ function udp({ type = 'udp4', localAddr = '0.0.0.0', reuseAddr = true, socketTim listener.close(); } + function disconnect(handle?: UDPSocketHandle): void { + if (handle && handle.socket) handle.socket = null; + emitter.emit('disconnect'); + } + function connect(handle?: SocketHandle): SocketHandle { if (handle) return handle; const connection = dgram.createSocket(type as dgram.SocketType); @@ -105,9 +71,44 @@ function udp({ type = 'udp4', localAddr = '0.0.0.0', reuseAddr = true, socketTim return res; } - function disconnect(handle?: SocketHandle): void { - if (handle) handle = null; - emitter.emit('disconnect'); + function resolveClient(origin, data) { + const handle: UDPSocketHandle = { + host: origin.address, + port: origin.port, + socket: listener, + }; + let isSynPacket = false; + + // Handle SYN + if (data[0] === 83 && data[1] === 89 && data[2] === 78) { + send(handle, Buffer.from('ACK')); + isSynPacket = true; + } + + const key: string = `${origin.address}.${origin.port}`; + clearTimeout(clientCache[key] && clientCache[key].timeout); + + if (!clientCache[key]) { + clientCache[key] = { + client: null, + data: [], + timeout: null, + } as UDPClient; + emitter.emit('socket', handle); + } + + if (data && !isSynPacket) { + if (clientCache[key].client) clientCache[key].client.emit('frame', data); + else clientCache[key].data.push(data); + } + } + + function bind(): void { + listener = dgram.createSocket({ type: type as dgram.SocketType, reuseAddr }); + listener.on('message', (data, origin) => resolveClient(origin, data)); + listener.on('error', err => emitter.emit('error', err)); + listener.bind(params.port, localAddr); + emitter.emit('ready'); } emitter.on('connection', addClient); diff --git a/packages/udp/tests/unit/udp.spec.ts b/packages/udp/tests/unit/udp.spec.ts index 466e5ad..87df84f 100644 --- a/packages/udp/tests/unit/udp.spec.ts +++ b/packages/udp/tests/unit/udp.spec.ts @@ -1,5 +1,5 @@ import udp from '../../src/udp'; describe('UDP transport', () => { - it('TODO', () => { expect(udp).not.toBeUndefined(); }); + it('TODO', () => { expect(udp).not.toBeUndefined(); }); }); diff --git a/packages/ws/src/ws.ts b/packages/ws/src/ws.ts index ca3d3de..5afbeb6 100644 --- a/packages/ws/src/ws.ts +++ b/packages/ws/src/ws.ts @@ -27,7 +27,7 @@ function ws({ cert, key, secure }: WSConfig = {}): KalmTransport { if (handle && handle.readyState === 1) { handle.send(Buffer.from(payload)); } else { - handle['_queue'].push(payload); + handle._queue.push(payload); } } @@ -40,12 +40,12 @@ function ws({ cert, key, secure }: WSConfig = {}): KalmTransport { const connection: WebSocket = handle || new WS(`${protocol}://${params.host}:${params.port}`); connection.binaryType = 'arraybuffer'; const evtType: string = isBrowser ? 'addEventListener' : 'on'; - connection['_queue'] = []; + connection._queue = []; connection[evtType]('message', evt => emitter.emit('frame', Buffer.from(evt.data || evt))); connection[evtType]('error', err => emitter.emit('error', err)); connection[evtType]('close', () => emitter.emit('disconnect')); connection[evtType]('open', () => { - connection['_queue'].forEach(payload => send(connection, payload)); + connection._queue.forEach(payload => send(connection, payload)); emitter.emit('connect', connection); }); @@ -53,13 +53,13 @@ function ws({ cert, key, secure }: WSConfig = {}): KalmTransport { } function remote(handle: WebSocket): Remote { - const h = handle['headers']; + const h = handle.headers; return { host: ( - (h && h['x-forwarded-for'] && h['x-forwarded-for'].split(',')[0]) || - (handle['connection'] && handle['connection'].remoteAddress || '0.0.0.0') + (h && h['x-forwarded-for'] && h['x-forwarded-for'].split(',')[0]) + || (handle.connection && handle.connection.remoteAddress || '0.0.0.0') ), - port: handle['connection'] && handle['connection'].remotePort || 0 + port: handle.connection && handle.connection.remotePort || 0, }; } diff --git a/packages/ws/tests/unit/ws.spec.ts b/packages/ws/tests/unit/ws.spec.ts index 319bad5..6105eec 100644 --- a/packages/ws/tests/unit/ws.spec.ts +++ b/packages/ws/tests/unit/ws.spec.ts @@ -1,5 +1,5 @@ import ws from '../../src/ws'; describe('WS transport', () => { - it('TODO', () => { expect(ws).not.toBeUndefined(); }); + it('TODO', () => { expect(ws).not.toBeUndefined(); }); }); diff --git a/scripts/benchmarks/transports/kalm.js b/scripts/benchmarks/transports/kalm.js index 6b31008..a5cba55 100644 --- a/scripts/benchmarks/transports/kalm.js +++ b/scripts/benchmarks/transports/kalm.js @@ -6,7 +6,7 @@ /* Requires ------------------------------------------------------------------*/ const settings = require('../settings'); -const Kalm = require('../../../packages/kalm/bin/kalm'); +const Kalm = require('../../../packages/kalm/bin/kalm').default; const transports = { ipc: require('../../../packages/ipc/bin/ipc'), @@ -29,7 +29,7 @@ function setup(resolve) { server = Kalm.listen({ port: settings.port, json: true, - transport: transports[settings.transport](), + transport: transports[settings.transport].default(), routine: Kalm.routines[settings.routine[0]](settings.routine[1]), }); @@ -59,7 +59,7 @@ function step(resolve) { client = Kalm.connect({ port: settings.port, json: true, - transport: transports[settings.transport](), + transport: transports[settings.transport].default(), routine: Kalm.routines.realtime(), }); client.subscribe(settings.testChannel, () => count++); diff --git a/tests/integration/index.spec.ts b/tests/integration/index.spec.ts index b1b5c59..0323c12 100644 --- a/tests/integration/index.spec.ts +++ b/tests/integration/index.spec.ts @@ -10,7 +10,7 @@ import Kalm from '../../packages/kalm/src/kalm'; /* Suite --------------------------------------------------------------------*/ describe('Integration tests', () => { - ['ipc', 'tcp', 'udp', 'ws'].forEach((transport) => { + ['ipc', 'tcp', 'udp', 'ws'].forEach(transport => { describe(`Testing ${transport} transport`, () => { let server; const soc = require(`../../packages/${transport}/src/${transport}`).default(); /* eslint-disable-line */ @@ -25,7 +25,7 @@ describe('Integration tests', () => { }); // Cleanup afterwards - afterEach((done) => { + afterEach(done => { server.stop(); server = null; setTimeout(() => done(), 100); @@ -33,10 +33,10 @@ describe('Integration tests', () => { /* --- Tests --- */ - it(`should work with ${transport}`, (done) => { + it(`should work with ${transport}`, done => { const payload = { foo: 'bar' }; - server.on('connection', (c) => { - c.subscribe('test', (data) => { + server.on('connection', c => { + c.subscribe('test', data => { expect(data).toEqual(payload); done(); }); @@ -46,14 +46,14 @@ describe('Integration tests', () => { client.write('test', payload); }); - it(`should handle large payloads with ${transport}`, (done) => { + it(`should handle large payloads with ${transport}`, done => { const largePayload = []; while (largePayload.length < 2048) { largePayload.push({ foo: 'bar' }); } - server.on('connection', (c) => { - c.subscribe('test.large', (data) => { + server.on('connection', c => { + c.subscribe('test.large', data => { expect(data).toEqual(largePayload); done(); }); @@ -63,9 +63,9 @@ describe('Integration tests', () => { client.write('test.large', largePayload); }); - it('should not trigger for unsubscribed channels', (done) => { + it('should not trigger for unsubscribed channels', done => { const payload = { foo: 'bar' }; - server.on('connection', (c) => { + server.on('connection', c => { c.subscribe('test', () => { // Throw on purpose expect(false).toBe(true); diff --git a/types.d.ts b/types.d.ts index 5d257c0..6220492 100644 --- a/types.d.ts +++ b/types.d.ts @@ -124,4 +124,4 @@ type Frame = { payloadBytes: number payloadMessages: number } -} \ No newline at end of file +} From 7473d1b7a32ea5bdcade8a285ee4133f668ac5f3 Mon Sep 17 00:00:00 2001 From: frederic charette Date: Thu, 10 Oct 2019 08:22:37 -0400 Subject: [PATCH 5/9] added pre-commit hook for lint --- package.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 6a88aca..5a4db25 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,14 @@ "frederic charette " ], "typings": "./types.d.ts", - "workspaces": [ "packages/*" ], + "workspaces": [ + "packages/*" + ], + "husky": { + "hooks": { + "pre-commit": "yarn lint" + } + }, "devDependencies": { "@types/jest": "^24.0.17", "@types/node": "^12.7.0", @@ -35,6 +42,7 @@ "eslint": "^6.5.0", "eslint-config-airbnb-base": "^14.0.0", "eslint-plugin-import": "^2.18.0", + "husky": "^3.0.8", "jest": "^24.9.0", "socket.io": "^2.3.0", "socket.io-client": "^2.3.0", From 891dbcb298e5bd9cc994468bf8bed79c3697ae02 Mon Sep 17 00:00:00 2001 From: frederic charette Date: Thu, 10 Oct 2019 08:45:41 -0400 Subject: [PATCH 6/9] re-introduced files in sub package.json for publishing --- packages/ipc/package.json | 1 + packages/kalm/package.json | 1 + packages/tcp/package.json | 1 + packages/udp/package.json | 1 + packages/ws/package.json | 1 + 5 files changed, 5 insertions(+) diff --git a/packages/ipc/package.json b/packages/ipc/package.json index 907a4ee..33e09fc 100644 --- a/packages/ipc/package.json +++ b/packages/ipc/package.json @@ -31,6 +31,7 @@ "web", "ipc" ], + "files": ["bin", "types.d.ts"], "author": "frederic charette ", "license": "Apache-2.0", "typings": "./types.d.ts", diff --git a/packages/kalm/package.json b/packages/kalm/package.json index a649ed8..1040e2a 100644 --- a/packages/kalm/package.json +++ b/packages/kalm/package.json @@ -35,6 +35,7 @@ "ws", "core" ], + "files": ["bin", "types.d.ts"], "typings": "./types.d.ts", "author": "frederic charette ", "license": "Apache-2.0", diff --git a/packages/tcp/package.json b/packages/tcp/package.json index 98d286a..397ab78 100644 --- a/packages/tcp/package.json +++ b/packages/tcp/package.json @@ -31,6 +31,7 @@ "web", "tcp" ], + "files": ["bin", "types.d.ts"], "typings": "./types.d.ts", "author": "frederic charette ", "license": "Apache-2.0", diff --git a/packages/udp/package.json b/packages/udp/package.json index ea6c167..564a0e6 100644 --- a/packages/udp/package.json +++ b/packages/udp/package.json @@ -31,6 +31,7 @@ "web", "udp" ], + "files": ["bin", "types.d.ts"], "typings": "./types.d.ts", "author": "frederic charette ", "license": "Apache-2.0", diff --git a/packages/ws/package.json b/packages/ws/package.json index a081369..8fe5b7c 100644 --- a/packages/ws/package.json +++ b/packages/ws/package.json @@ -31,6 +31,7 @@ "web", "ws" ], + "files": ["bin", "types.d.ts"], "typings": "./types.d.ts", "author": "frederic charette ", "license": "Apache-2.0", From ea4f85e6790754f14ad8247336e553570f8883e6 Mon Sep 17 00:00:00 2001 From: frederic charette Date: Fri, 11 Oct 2019 08:51:29 -0400 Subject: [PATCH 7/9] removed default exports, fixed bench and examples --- .eslintrc | 1 + examples/chat_websocket/client.js | 8 +++-- examples/chat_websocket/server.js | 7 ++-- packages/ipc/src/ipc.ts | 15 +++++++-- packages/kalm/README.md | 9 +++++- packages/kalm/src/components/client.ts | 22 ++++++------- packages/kalm/src/components/provider.ts | 18 ++++------- packages/kalm/src/kalm.ts | 32 ++++++++----------- packages/kalm/src/routines/dynamic.ts | 6 +--- packages/kalm/src/routines/realtime.ts | 6 +--- packages/kalm/src/routines/tick.ts | 6 +--- packages/kalm/src/utils/logger.ts | 10 +++--- packages/kalm/src/utils/parser.ts | 8 ++--- .../kalm/tests/unit/components/client.spec.ts | 4 +-- .../tests/unit/components/provider.spec.ts | 4 +-- packages/kalm/tests/unit/kalm.spec.ts | 10 +++--- .../kalm/tests/unit/routines/dynamic.spec.ts | 2 +- .../kalm/tests/unit/routines/realtime.spec.ts | 2 +- .../kalm/tests/unit/routines/tick.spec.ts | 2 +- packages/kalm/tests/unit/utils/logger.spec.ts | 4 +-- packages/kalm/tests/unit/utils/parser.spec.ts | 5 +-- packages/tcp/src/tcp.ts | 4 +-- packages/udp/src/udp.ts | 2 +- packages/ws/src/ws.ts | 2 +- scripts/benchmarks/transports/kalm.js | 6 ++-- tests/integration/index.spec.ts | 12 +++---- 26 files changed, 100 insertions(+), 107 deletions(-) diff --git a/.eslintrc b/.eslintrc index f57c7cf..cbf08d0 100644 --- a/.eslintrc +++ b/.eslintrc @@ -21,6 +21,7 @@ "no-mixed-operators": 0, "no-param-reassign": 0, "arrow-parens": [2, "as-needed"], + "import/prefer-default-export": 0, "no-continue": 0, "no-unused-vars": 0, "global-require": 0, diff --git a/examples/chat_websocket/client.js b/examples/chat_websocket/client.js index 5bd8393..9083f09 100644 --- a/examples/chat_websocket/client.js +++ b/examples/chat_websocket/client.js @@ -1,5 +1,9 @@ -const kalm = require('kalm'); -const ws = require('@kalm/ws'); +//const kalm = require('kalm'); +//const ws = require('@kalm/ws'); + +const kalm = require('../../packages/kalm/bin/kalm'); +const ws = require('../../packages/ws/bin/ws'); + const { randomBytes } = require('crypto'); const Client = kalm.connect({ diff --git a/examples/chat_websocket/server.js b/examples/chat_websocket/server.js index 6a8b821..6df85d7 100644 --- a/examples/chat_websocket/server.js +++ b/examples/chat_websocket/server.js @@ -1,5 +1,8 @@ -const kalm = require('kalm'); -const ws = require('@kalm/ws'); +//const kalm = require('kalm'); +//const ws = require('@kalm/ws'); + +const kalm = require('../../packages/kalm/bin/kalm'); +const ws = require('../../packages/ws/bin/ws'); const Server = kalm.listen({ label: 'server', diff --git a/packages/ipc/src/ipc.ts b/packages/ipc/src/ipc.ts index e9bb874..fb6baa7 100644 --- a/packages/ipc/src/ipc.ts +++ b/packages/ipc/src/ipc.ts @@ -4,7 +4,16 @@ import net from 'net'; /* Methods -------------------------------------------------------------------*/ -function ipc({ socketTimeout = 30000, path = '/tmp/app.socket-' }: IPCConfig = {}): KalmTransport { +interface IPCSocket extends net.Socket { + _server: { + _pipeName: string + } + _handle: { + fd: number + } +} + +export function ipc({ socketTimeout = 30000, path = '/tmp/app.socket-' }: IPCConfig = {}): KalmTransport { return function socket(params: ClientConfig, emitter: NodeJS.EventEmitter): Socket { let listener: net.Server; @@ -14,7 +23,7 @@ function ipc({ socketTimeout = 30000, path = '/tmp/app.socket-' }: IPCConfig = { listener.listen(path + params.port, () => emitter.emit('ready')); } - function remote(handle: net.Socket): Remote { + function remote(handle: IPCSocket): Remote { return { host: handle._server._pipeName, port: handle._handle.fd, @@ -59,4 +68,4 @@ function ipc({ socketTimeout = 30000, path = '/tmp/app.socket-' }: IPCConfig = { /* Exports -------------------------------------------------------------------*/ -export default ipc; +module.exports = ipc; diff --git a/packages/kalm/README.md b/packages/kalm/README.md index 82bf765..27ac09a 100644 --- a/packages/kalm/README.md +++ b/packages/kalm/README.md @@ -44,6 +44,9 @@ Install the transport layer ('tcp' for example) **Server** ```javascript +const kalm = require('kalm'); +const ws = require('@kalm/ws'); + const Server = kalm.listen({ port: 8800, transport: ws(), @@ -65,8 +68,12 @@ const Client = kalm.connect({ routine: kalm.routines.realtime(), }); ``` +To see working implementations, check out our [examples](https://github.com/kalm/kalm.js/tree/master/examples) folder. -See the [examples](https://github.com/kalm/kalm.js/tree/master/examples) folder for great real-world examples! +- [Chat via websockets](https://github.com/kalm/kalm.js/tree/master/examples/chat_websocket) +- [Distributed Pub-Sub](https://github.com/kalm/kalm.js/tree/master/examples/distributed_pub_sub) +- [Packet compressing](https://github.com/kalm/kalm.js/tree/master/examples/compression) +- [Typescript usage](https://github.com/kalm/kalm.js/tree/master/examples/typescript) ## Documentation diff --git a/packages/kalm/src/components/client.ts b/packages/kalm/src/components/client.ts index 66148e7..0496888 100644 --- a/packages/kalm/src/components/client.ts +++ b/packages/kalm/src/components/client.ts @@ -1,12 +1,12 @@ /* Requires ------------------------------------------------------------------*/ import { EventEmitter } from 'events'; -import logger from '../utils/logger'; -import parser from '../utils/parser'; +import { log } from '../utils/logger'; +import { serialize, deserialize } from '../utils/parser'; /* Methods -------------------------------------------------------------------*/ -function Client(params: ClientConfig, emitter: EventEmitter, handle?: SocketHandle): Client { +export function Client(params: ClientConfig, emitter: EventEmitter, handle?: SocketHandle): Client { let connected: number = 1; const channels: ChannelList = {}; const socket: Socket = params.transport(params, emitter); @@ -22,7 +22,7 @@ function Client(params: ClientConfig, emitter: EventEmitter, handle?: SocketHand } function _wrap(event: RawFrame): void { - const payload: number[] = parser.serialize(event.frameId, event.channel, event.packets); + const payload: number[] = serialize(event.frameId, event.channel, event.packets); emitter.emit('stats.packetReady'); socket.send(handle, payload); } @@ -59,22 +59,22 @@ function Client(params: ClientConfig, emitter: EventEmitter, handle?: SocketHand function _handleConnect(): void { connected = 2; - logger.log(`log: connected to ${params.host}:${params.port}`); + log(`connected to ${params.host}:${params.port}`); } function _handleError(err: Error): void { - logger.log(`error: ${err.message}`); + log(`error ${err.message}`); } function _handleRequest(payload: Buffer): void { emitter.emit('stats.packetReceived'); - const frame: RawFrame = parser.deserialize(payload); + const frame: RawFrame = deserialize(payload); frame.packets.forEach((packet, i) => _handlePackets(frame, packet, i)); } function _handleDisconnect() { connected = 0; - logger.log(`log: lost connection to ${params.host}:${params.port}`); + log(`lost connection to ${params.host}:${params.port}`); } function write(channel: string, message: Serializable): void { @@ -124,7 +124,7 @@ function Client(params: ClientConfig, emitter: EventEmitter, handle?: SocketHand emitter.on('disconnect', _handleDisconnect); emitter.on('error', _handleError); emitter.on('frame', _handleRequest); - if (!handle) logger.log(`log: connecting to ${params.host}:${params.port}`); + if (!handle) log(`connecting to ${params.host}:${params.port}`); handle = socket.connect(handle); return Object.assign(emitter, { @@ -137,7 +137,3 @@ function Client(params: ClientConfig, emitter: EventEmitter, handle?: SocketHand label: params.label, }); } - -/* Exports -------------------------------------------------------------------*/ - -export default Client; diff --git a/packages/kalm/src/components/provider.ts b/packages/kalm/src/components/provider.ts index 27f22d7..28ff127 100644 --- a/packages/kalm/src/components/provider.ts +++ b/packages/kalm/src/components/provider.ts @@ -1,12 +1,12 @@ /* Requires ------------------------------------------------------------------*/ import { EventEmitter } from 'events'; -import logger from '../utils/logger'; -import Client from './client'; +import { log } from '../utils/logger'; +import { Client } from './client'; /* Methods -------------------------------------------------------------------*/ -function Provider(params: ClientConfig, emitter: EventEmitter): Provider { +export function Provider(params: ClientConfig, emitter: EventEmitter): Provider { const connections = []; const socket: Socket = params.transport(params, emitter); @@ -15,7 +15,7 @@ function Provider(params: ClientConfig, emitter: EventEmitter): Provider { } function stop(): void { - logger.log('warn: stopping server'); + log('stopping server'); connections.forEach(connection => connection.destroy()); connections.length = 0; @@ -23,7 +23,7 @@ function Provider(params: ClientConfig, emitter: EventEmitter): Provider { } function _handleError(err) { - logger.log(`error: ${err}`); + log(`error ${err}`); } function handleConnection(handle) { @@ -44,12 +44,12 @@ function Provider(params: ClientConfig, emitter: EventEmitter): Provider { connections.push(client); emitter.emit('connection', client); - logger.log(`log: connection from ${origin.host}:${origin.port}`); + log(`connection from ${origin.host}:${origin.port}`); } emitter.on('socket', handleConnection); emitter.on('error', _handleError); - logger.log(`log: listening on ${params.host}:${params.port}`); + log(`listening on ${params.host}:${params.port}`); socket.bind(); return Object.assign(emitter, { @@ -60,7 +60,3 @@ function Provider(params: ClientConfig, emitter: EventEmitter): Provider { connections, }); } - -/* Exports -------------------------------------------------------------------*/ - -export default Provider; diff --git a/packages/kalm/src/kalm.ts b/packages/kalm/src/kalm.ts index 5912841..452ee1b 100644 --- a/packages/kalm/src/kalm.ts +++ b/packages/kalm/src/kalm.ts @@ -1,12 +1,12 @@ /* Requires ------------------------------------------------------------------*/ import { EventEmitter } from 'events'; -import client from './components/client'; -import provider from './components/provider'; +import { Client } from './components/client'; +import { Provider } from './components/provider'; -import dynamic from './routines/dynamic'; -import realtime from './routines/realtime'; -import tick from './routines/tick'; +import { dynamic } from './routines/dynamic'; +import { realtime } from './routines/realtime'; +import { tick } from './routines/tick'; /* Local variables -----------------------------------------------------------*/ @@ -22,22 +22,16 @@ const defaults = { const uniqueLabel = () => Math.random().toString(36).substring(7); -function listen(options: ProviderConfig): Provider { - return provider({ label: uniqueLabel(), ...defaults, ...options }, new EventEmitter()); +export function listen(options: ProviderConfig): Provider { + return Provider({ label: uniqueLabel(), ...defaults, ...options }, new EventEmitter()); } -function connect(options: ClientConfig): Client { - return client({ label: uniqueLabel(), ...defaults, ...options }, new EventEmitter()); +export function connect(options: ClientConfig): Client { + return Client({ label: uniqueLabel(), ...defaults, ...options }, new EventEmitter()); } -/* Exports -------------------------------------------------------------------*/ - -export default { - connect, - listen, - routines: { - dynamic, - realtime, - tick, - }, +export const routines = { + dynamic, + realtime, + tick, }; diff --git a/packages/kalm/src/routines/dynamic.ts b/packages/kalm/src/routines/dynamic.ts index 26e7191..163d416 100644 --- a/packages/kalm/src/routines/dynamic.ts +++ b/packages/kalm/src/routines/dynamic.ts @@ -4,7 +4,7 @@ import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ -function dynamic(hz: number): KalmRoutine { +export function dynamic(hz: number): KalmRoutine { if (hz <= 0 || hz > 1000) { throw new Error(`Unable to set Hertz value of ${hz}. Must be between 0.1e13 and 1000`); } @@ -36,7 +36,3 @@ function dynamic(hz: number): KalmRoutine { return { add, size, flush: _step }; }; } - -/* Exports -------------------------------------------------------------------*/ - -export default dynamic; diff --git a/packages/kalm/src/routines/realtime.ts b/packages/kalm/src/routines/realtime.ts index ad44dc5..35a1e21 100644 --- a/packages/kalm/src/routines/realtime.ts +++ b/packages/kalm/src/routines/realtime.ts @@ -4,7 +4,7 @@ import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ -function realtime(): KalmRoutine { +export function realtime(): KalmRoutine { return function queue(channel: string, params: object, emitter: EventEmitter): Queue { let i: number = 0; @@ -21,7 +21,3 @@ function realtime(): KalmRoutine { return { add, size, flush }; }; } - -/* Exports -------------------------------------------------------------------*/ - -export default realtime; diff --git a/packages/kalm/src/routines/tick.ts b/packages/kalm/src/routines/tick.ts index 68a5f92..79c60b8 100644 --- a/packages/kalm/src/routines/tick.ts +++ b/packages/kalm/src/routines/tick.ts @@ -4,7 +4,7 @@ import { EventEmitter } from 'events'; /* Methods -------------------------------------------------------------------*/ -function tick(hz: number, seed: number = Date.now()): KalmRoutine { +export function tick(hz: number, seed: number = Date.now()): KalmRoutine { if (hz <= 0 || hz > 1000) { throw new Error(`Unable to set Hertz value of ${hz}. Must be between 0.1e13 and 1000`); } @@ -41,7 +41,3 @@ function tick(hz: number, seed: number = Date.now()): KalmRoutine { return { add, size, flush: _step }; }; } - -/* Exports -------------------------------------------------------------------*/ - -export default tick; diff --git a/packages/kalm/src/utils/logger.ts b/packages/kalm/src/utils/logger.ts index 6c86a16..346a773 100644 --- a/packages/kalm/src/utils/logger.ts +++ b/packages/kalm/src/utils/logger.ts @@ -8,12 +8,10 @@ const enabled: boolean = ( || '' ).indexOf('kalm') > -1; +const prefix = `KALM ${typeof process === 'object' && process.pid}`; + /* Methods -------------------------------------------------------------------*/ -function log(msg: string): void { - if (enabled) console.log(msg); // eslint-disable-line no-console +export function log(msg: string): void { + if (enabled) console.log(`${prefix}: ${msg}`); // eslint-disable-line no-console } - -/* Exports --------------------------------------------------------------------*/ - -export default { log }; diff --git a/packages/kalm/src/utils/parser.ts b/packages/kalm/src/utils/parser.ts index 8feb08f..3e42696 100644 --- a/packages/kalm/src/utils/parser.ts +++ b/packages/kalm/src/utils/parser.ts @@ -8,7 +8,7 @@ function _numericSize(bytes: Buffer, index: number): number { return (bytes[index] << 8) | bytes[index + 1]; } -function serialize(frameId: number, channel: string, packets: Buffer[]): number[] { +export function serialize(frameId: number, channel: string, packets: Buffer[]): number[] { const channelLen: number = channel.length; const result: number[] = [frameId % 255, channelLen]; @@ -27,7 +27,7 @@ function serialize(frameId: number, channel: string, packets: Buffer[]): number[ return result; } -function deserialize(payload: Buffer): RawFrame { +export function deserialize(payload: Buffer): RawFrame { const channelLength = payload[1]; let caret = 4 + channelLength; const totalPackets = _numericSize(payload, 2 + channelLength); @@ -52,7 +52,3 @@ function deserialize(payload: Buffer): RawFrame { return result; } - -/* Exports -------------------------------------------------------------------*/ - -export default { serialize, deserialize }; diff --git a/packages/kalm/tests/unit/components/client.spec.ts b/packages/kalm/tests/unit/components/client.spec.ts index ee9bddc..7e7b7a5 100644 --- a/packages/kalm/tests/unit/components/client.spec.ts +++ b/packages/kalm/tests/unit/components/client.spec.ts @@ -1,5 +1,5 @@ -import client from '../../../src/components/client'; +import { Client } from '../../../src/components/client'; describe('Client', () => { - it('TODO', () => { expect(client).not.toBeUndefined(); }); + it('TODO', () => { expect(Client).not.toBeUndefined(); }); }); diff --git a/packages/kalm/tests/unit/components/provider.spec.ts b/packages/kalm/tests/unit/components/provider.spec.ts index 9e0787d..51c3cf3 100644 --- a/packages/kalm/tests/unit/components/provider.spec.ts +++ b/packages/kalm/tests/unit/components/provider.spec.ts @@ -1,5 +1,5 @@ -import provider from '../../../src/components/provider'; +import { Provider } from '../../../src/components/provider'; describe('Provider', () => { - it('TODO', () => { expect(provider).not.toBeUndefined(); }); + it('TODO', () => { expect(Provider).not.toBeUndefined(); }); }); diff --git a/packages/kalm/tests/unit/kalm.spec.ts b/packages/kalm/tests/unit/kalm.spec.ts index 703e9d8..98b27ed 100644 --- a/packages/kalm/tests/unit/kalm.spec.ts +++ b/packages/kalm/tests/unit/kalm.spec.ts @@ -1,4 +1,4 @@ -import kalm from '../../src/kalm'; +import { listen, connect } from '../../src/kalm'; const bindSpy = jest.fn(); const connectSpy = jest.fn(); @@ -9,11 +9,11 @@ describe('Kalm constructors', () => { let server; it('should throw an error if no transports are provided', () => { - expect(kalm.listen).toThrow(); + expect(listen).toThrow(); }); it('listen should bind to a transport if one is provided', () => { - server = kalm.listen({ transport: mockTransport() }); + server = listen({ transport: mockTransport() }); expect(bindSpy).toHaveBeenCalled(); }); @@ -26,11 +26,11 @@ describe('Kalm constructors', () => { let client; it('should throw an error if no transports are provided', () => { - expect(kalm.connect).toThrow(); + expect(connect).toThrow(); }); it('listen should connect via a transport if one is provided', () => { - client = kalm.connect({ transport: mockTransport() }); + client = connect({ transport: mockTransport() }); expect(connectSpy).toHaveBeenCalled(); }); diff --git a/packages/kalm/tests/unit/routines/dynamic.spec.ts b/packages/kalm/tests/unit/routines/dynamic.spec.ts index 5eb2890..87d04ca 100644 --- a/packages/kalm/tests/unit/routines/dynamic.spec.ts +++ b/packages/kalm/tests/unit/routines/dynamic.spec.ts @@ -1,4 +1,4 @@ -import dynamic from '../../../src/routines/dynamic'; +import { dynamic } from '../../../src/routines/dynamic'; describe('Dynamic routine', () => { it('TODO', () => { expect(dynamic).not.toBeUndefined(); }); diff --git a/packages/kalm/tests/unit/routines/realtime.spec.ts b/packages/kalm/tests/unit/routines/realtime.spec.ts index 3d2fbc5..1d50d6b 100644 --- a/packages/kalm/tests/unit/routines/realtime.spec.ts +++ b/packages/kalm/tests/unit/routines/realtime.spec.ts @@ -1,4 +1,4 @@ -import realtime from '../../../src/routines/realtime'; +import { realtime } from '../../../src/routines/realtime'; describe('Realtime routine', () => { it('TODO', () => { expect(realtime).not.toBeUndefined(); }); diff --git a/packages/kalm/tests/unit/routines/tick.spec.ts b/packages/kalm/tests/unit/routines/tick.spec.ts index eb1fe66..03dc147 100644 --- a/packages/kalm/tests/unit/routines/tick.spec.ts +++ b/packages/kalm/tests/unit/routines/tick.spec.ts @@ -1,4 +1,4 @@ -import tick from '../../../src/routines/tick'; +import { tick } from '../../../src/routines/tick'; describe('Tick routine', () => { it('TODO', () => { expect(tick).not.toBeUndefined(); }); diff --git a/packages/kalm/tests/unit/utils/logger.spec.ts b/packages/kalm/tests/unit/utils/logger.spec.ts index 4c8ae82..f1db54f 100644 --- a/packages/kalm/tests/unit/utils/logger.spec.ts +++ b/packages/kalm/tests/unit/utils/logger.spec.ts @@ -1,5 +1,5 @@ -import logger from '../../../src/utils/logger'; +import { log } from '../../../src/utils/logger'; describe('Logger util', () => { - it('TODO', () => { expect(logger).not.toBeUndefined(); }); + it('TODO', () => { expect(log).not.toBeUndefined(); }); }); diff --git a/packages/kalm/tests/unit/utils/parser.spec.ts b/packages/kalm/tests/unit/utils/parser.spec.ts index d08c58f..3029963 100644 --- a/packages/kalm/tests/unit/utils/parser.spec.ts +++ b/packages/kalm/tests/unit/utils/parser.spec.ts @@ -1,5 +1,6 @@ -import parser from '../../../src/utils/parser'; +import { serialize, deserialize } from '../../../src/utils/parser'; describe('Parser util', () => { - it('TODO', () => { expect(parser).not.toBeUndefined(); }); + it('TODO', () => { expect(serialize).not.toBeUndefined(); }); + it('TODO', () => { expect(deserialize).not.toBeUndefined(); }); }); diff --git a/packages/tcp/src/tcp.ts b/packages/tcp/src/tcp.ts index 9998cad..fd8f12a 100644 --- a/packages/tcp/src/tcp.ts +++ b/packages/tcp/src/tcp.ts @@ -4,7 +4,7 @@ import net from 'net'; /* Methods -------------------------------------------------------------------*/ -function tcp({ socketTimeout = 30000 }: TCPConfig = {}): KalmTransport { +export function tcp({ socketTimeout = 30000 }: TCPConfig = {}): KalmTransport { return function socket(params: ClientConfig, emitter: NodeJS.EventEmitter): Socket { let listener: net.Server; @@ -58,4 +58,4 @@ function tcp({ socketTimeout = 30000 }: TCPConfig = {}): KalmTransport { /* Exports -------------------------------------------------------------------*/ -export default tcp; +module.exports = tcp; diff --git a/packages/udp/src/udp.ts b/packages/udp/src/udp.ts index 1edae41..0a0577b 100644 --- a/packages/udp/src/udp.ts +++ b/packages/udp/src/udp.ts @@ -126,4 +126,4 @@ function udp({ type = 'udp4', localAddr = '0.0.0.0', reuseAddr = true, socketTim /* Exports -------------------------------------------------------------------*/ -export default udp; +module.exports = udp; diff --git a/packages/ws/src/ws.ts b/packages/ws/src/ws.ts index 5afbeb6..34697d5 100644 --- a/packages/ws/src/ws.ts +++ b/packages/ws/src/ws.ts @@ -83,4 +83,4 @@ function ws({ cert, key, secure }: WSConfig = {}): KalmTransport { /* Exports -------------------------------------------------------------------*/ -export default ws; +module.exports = ws; diff --git a/scripts/benchmarks/transports/kalm.js b/scripts/benchmarks/transports/kalm.js index a5cba55..6b31008 100644 --- a/scripts/benchmarks/transports/kalm.js +++ b/scripts/benchmarks/transports/kalm.js @@ -6,7 +6,7 @@ /* Requires ------------------------------------------------------------------*/ const settings = require('../settings'); -const Kalm = require('../../../packages/kalm/bin/kalm').default; +const Kalm = require('../../../packages/kalm/bin/kalm'); const transports = { ipc: require('../../../packages/ipc/bin/ipc'), @@ -29,7 +29,7 @@ function setup(resolve) { server = Kalm.listen({ port: settings.port, json: true, - transport: transports[settings.transport].default(), + transport: transports[settings.transport](), routine: Kalm.routines[settings.routine[0]](settings.routine[1]), }); @@ -59,7 +59,7 @@ function step(resolve) { client = Kalm.connect({ port: settings.port, json: true, - transport: transports[settings.transport].default(), + transport: transports[settings.transport](), routine: Kalm.routines.realtime(), }); client.subscribe(settings.testChannel, () => count++); diff --git a/tests/integration/index.spec.ts b/tests/integration/index.spec.ts index 0323c12..a8fc485 100644 --- a/tests/integration/index.spec.ts +++ b/tests/integration/index.spec.ts @@ -5,7 +5,7 @@ /* Requires ------------------------------------------------------------------*/ -import Kalm from '../../packages/kalm/src/kalm'; +import { connect, listen } from '../../packages/kalm/src/kalm'; /* Suite --------------------------------------------------------------------*/ @@ -13,13 +13,13 @@ describe('Integration tests', () => { ['ipc', 'tcp', 'udp', 'ws'].forEach(transport => { describe(`Testing ${transport} transport`, () => { let server; - const soc = require(`../../packages/${transport}/src/${transport}`).default(); /* eslint-disable-line */ + const soc = require(`../../packages/${transport}/src/${transport}`)(); /* eslint-disable-line */ /* --- Setup ---*/ // Create a server before each scenario beforeEach(() => { - server = Kalm.listen({ + server = listen({ transport: soc, }); }); @@ -42,7 +42,7 @@ describe('Integration tests', () => { }); }); - const client = Kalm.connect({ transport: soc }); + const client = connect({ transport: soc }); client.write('test', payload); }); @@ -59,7 +59,7 @@ describe('Integration tests', () => { }); }); - const client = Kalm.connect({ transport: soc }); + const client = connect({ transport: soc }); client.write('test.large', largePayload); }); @@ -75,7 +75,7 @@ describe('Integration tests', () => { c.unsubscribe('test'); }); - const client = Kalm.connect({ transport: soc }); + const client = connect({ transport: soc }); setTimeout(() => client.write('test', payload), 100); setTimeout(() => done(), 200); }); From db7276b22af166e50af26c59448e3cbf46af051f Mon Sep 17 00:00:00 2001 From: frederic charette Date: Fri, 11 Oct 2019 14:43:42 -0400 Subject: [PATCH 8/9] fixed unit test import syntax, events and their documentation --- packages/ipc/src/ipc.ts | 2 +- packages/ipc/tests/unit/ipc.spec.ts | 2 +- packages/kalm/README.md | 15 +++++++++++++++ packages/kalm/src/components/client.ts | 7 ++----- packages/tcp/src/tcp.ts | 2 +- packages/tcp/tests/unit/tcp.spec.ts | 2 +- packages/udp/src/udp.ts | 4 ++-- packages/udp/tests/unit/udp.spec.ts | 2 +- packages/ws/src/ws.ts | 2 +- packages/ws/tests/unit/ws.spec.ts | 2 +- 10 files changed, 26 insertions(+), 14 deletions(-) diff --git a/packages/ipc/src/ipc.ts b/packages/ipc/src/ipc.ts index fb6baa7..06c460b 100644 --- a/packages/ipc/src/ipc.ts +++ b/packages/ipc/src/ipc.ts @@ -32,7 +32,7 @@ export function ipc({ socketTimeout = 30000, path = '/tmp/app.socket-' }: IPCCon function connect(handle: net.Socket): net.Socket { const connection: net.Socket = handle || net.connect(`${path}${params.port}`); - connection.on('data', req => emitter.emit('frame', req)); + connection.on('data', req => emitter.emit('rawFrame', req)); connection.on('error', err => emitter.emit('error', err)); connection.on('connect', () => emitter.emit('connect', connection)); connection.on('close', () => emitter.emit('disconnect')); diff --git a/packages/ipc/tests/unit/ipc.spec.ts b/packages/ipc/tests/unit/ipc.spec.ts index 03d1d35..392b854 100644 --- a/packages/ipc/tests/unit/ipc.spec.ts +++ b/packages/ipc/tests/unit/ipc.spec.ts @@ -1,4 +1,4 @@ -import ipc from '../../src/ipc'; +import * as ipc from '../../src/ipc'; describe('IPC transport', () => { it('TODO', () => { expect(ipc).not.toBeUndefined(); }); diff --git a/packages/kalm/README.md b/packages/kalm/README.md index 27ac09a..6543ceb 100644 --- a/packages/kalm/README.md +++ b/packages/kalm/README.md @@ -90,6 +90,21 @@ Example: `NODE_DEBUG=net,kalm node myApp.js` +## Events + +Kalm offers events to track when packets are processed by routines or when a raw frame is received. + +| Event | Payload | Description | +| --- | --- | --- | +| `error` | Error | (provider, client) Emits on errors. | +| `ready` | void | (provider) Indicates that the provider is now actively listeneing for new connections | +| `connection` | [Client](./types.d.ts#L35) | (provider) Indicates that a client has successfuly connected | +| `connect` | [Client](./types.d.ts#L35) | (client) Indicates that a client has successfuly connected | +| `disconnect` | void | (client) Indicates that a client has disconnected | +| `frame` | [RawFrame](./types.d.ts#L111) | (client) Triggered when recieving a parsed full frame. | +| `stats.queueAdd` | ```{ frameId: number, packets: number}``` | (client) Indicates that a packet was queued to a frame. | +| `stats.queueRun` | ```{ frameId: number, packets: number}``` | (client) Indicates that a frame is being sent. | + ## Testing `npm test` diff --git a/packages/kalm/src/components/client.ts b/packages/kalm/src/components/client.ts index 0496888..0009677 100644 --- a/packages/kalm/src/components/client.ts +++ b/packages/kalm/src/components/client.ts @@ -23,7 +23,6 @@ export function Client(params: ClientConfig, emitter: EventEmitter, handle?: Soc function _wrap(event: RawFrame): void { const payload: number[] = serialize(event.frameId, event.channel, event.packets); - emitter.emit('stats.packetReady'); socket.send(handle, payload); } @@ -38,7 +37,6 @@ export function Client(params: ClientConfig, emitter: EventEmitter, handle?: Soc function _handlePackets(frame: RawFrame, packet: Buffer, index: number): Promise { if (packet.length === 0) return; const decodedPacket = (params.json === true) ? JSON.parse(packet.toString()) : packet; - emitter.emit('stats.packetDecoded'); if (channels[frame.channel]) { channels[frame.channel].emitter.emit( 'message', @@ -67,8 +65,8 @@ export function Client(params: ClientConfig, emitter: EventEmitter, handle?: Soc } function _handleRequest(payload: Buffer): void { - emitter.emit('stats.packetReceived'); const frame: RawFrame = deserialize(payload); + emitter.emit('frame', frame); frame.packets.forEach((packet, i) => _handlePackets(frame, packet, i)); } @@ -78,7 +76,6 @@ export function Client(params: ClientConfig, emitter: EventEmitter, handle?: Soc } function write(channel: string, message: Serializable): void { - emitter.emit('stats.packetWrite'); return _resolveChannel(channel) .queue.add(params.json === true ? Buffer.from(JSON.stringify(message)) : message as Buffer); } @@ -123,7 +120,7 @@ export function Client(params: ClientConfig, emitter: EventEmitter, handle?: Soc emitter.on('connect', _handleConnect); emitter.on('disconnect', _handleDisconnect); emitter.on('error', _handleError); - emitter.on('frame', _handleRequest); + emitter.on('rawFrame', _handleRequest); if (!handle) log(`connecting to ${params.host}:${params.port}`); handle = socket.connect(handle); diff --git a/packages/tcp/src/tcp.ts b/packages/tcp/src/tcp.ts index fd8f12a..6bc41aa 100644 --- a/packages/tcp/src/tcp.ts +++ b/packages/tcp/src/tcp.ts @@ -22,7 +22,7 @@ export function tcp({ socketTimeout = 30000 }: TCPConfig = {}): KalmTransport { } function connect(handle: net.Socket): net.Socket { const connection: net.Socket = handle || net.connect(params.port, params.host); - connection.on('data', req => emitter.emit('frame', req)); + connection.on('data', req => emitter.emit('rawFrame', req)); connection.on('error', err => emitter.emit('error', err)); connection.on('connect', () => emitter.emit('connect', connection)); connection.on('close', () => emitter.emit('disconnect')); diff --git a/packages/tcp/tests/unit/tcp.spec.ts b/packages/tcp/tests/unit/tcp.spec.ts index f7e6477..b024b76 100644 --- a/packages/tcp/tests/unit/tcp.spec.ts +++ b/packages/tcp/tests/unit/tcp.spec.ts @@ -1,4 +1,4 @@ -import tcp from '../../src/tcp'; +import * as tcp from '../../src/tcp'; describe('TCP transport', () => { it('TODO', () => { expect(tcp).not.toBeUndefined(); }); diff --git a/packages/udp/src/udp.ts b/packages/udp/src/udp.ts index 0a0577b..fa898df 100644 --- a/packages/udp/src/udp.ts +++ b/packages/udp/src/udp.ts @@ -54,7 +54,7 @@ function udp({ type = 'udp4', localAddr = '0.0.0.0', reuseAddr = true, socketTim if (req[0] === 65 && req[1] === 67 && req[2] === 75) { clearTimeout(timeout); emitter.emit('connect', connection); - } else emitter.emit('frame', req); + } else emitter.emit('rawFrame', req); }); connection.bind(null, localAddr); @@ -98,7 +98,7 @@ function udp({ type = 'udp4', localAddr = '0.0.0.0', reuseAddr = true, socketTim } if (data && !isSynPacket) { - if (clientCache[key].client) clientCache[key].client.emit('frame', data); + if (clientCache[key].client) clientCache[key].client.emit('rawFrame', data); else clientCache[key].data.push(data); } } diff --git a/packages/udp/tests/unit/udp.spec.ts b/packages/udp/tests/unit/udp.spec.ts index 87df84f..d43e569 100644 --- a/packages/udp/tests/unit/udp.spec.ts +++ b/packages/udp/tests/unit/udp.spec.ts @@ -1,4 +1,4 @@ -import udp from '../../src/udp'; +import * as udp from '../../src/udp'; describe('UDP transport', () => { it('TODO', () => { expect(udp).not.toBeUndefined(); }); diff --git a/packages/ws/src/ws.ts b/packages/ws/src/ws.ts index 34697d5..f672ecf 100644 --- a/packages/ws/src/ws.ts +++ b/packages/ws/src/ws.ts @@ -41,7 +41,7 @@ function ws({ cert, key, secure }: WSConfig = {}): KalmTransport { connection.binaryType = 'arraybuffer'; const evtType: string = isBrowser ? 'addEventListener' : 'on'; connection._queue = []; - connection[evtType]('message', evt => emitter.emit('frame', Buffer.from(evt.data || evt))); + connection[evtType]('message', evt => emitter.emit('rawFrame', Buffer.from(evt.data || evt))); connection[evtType]('error', err => emitter.emit('error', err)); connection[evtType]('close', () => emitter.emit('disconnect')); connection[evtType]('open', () => { diff --git a/packages/ws/tests/unit/ws.spec.ts b/packages/ws/tests/unit/ws.spec.ts index 6105eec..6923313 100644 --- a/packages/ws/tests/unit/ws.spec.ts +++ b/packages/ws/tests/unit/ws.spec.ts @@ -1,4 +1,4 @@ -import ws from '../../src/ws'; +import * as ws from '../../src/ws'; describe('WS transport', () => { it('TODO', () => { expect(ws).not.toBeUndefined(); }); From f5839250c8f12d3314a55a5058a30f709bd433dd Mon Sep 17 00:00:00 2001 From: frederic charette Date: Fri, 11 Oct 2019 14:53:42 -0400 Subject: [PATCH 9/9] reverted test imports in chat example --- examples/chat_websocket/client.js | 7 ++----- examples/chat_websocket/server.js | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/examples/chat_websocket/client.js b/examples/chat_websocket/client.js index 9083f09..9903069 100644 --- a/examples/chat_websocket/client.js +++ b/examples/chat_websocket/client.js @@ -1,8 +1,5 @@ -//const kalm = require('kalm'); -//const ws = require('@kalm/ws'); - -const kalm = require('../../packages/kalm/bin/kalm'); -const ws = require('../../packages/ws/bin/ws'); +const kalm = require('kalm'); +const ws = require('@kalm/ws'); const { randomBytes } = require('crypto'); diff --git a/examples/chat_websocket/server.js b/examples/chat_websocket/server.js index 6df85d7..6a8b821 100644 --- a/examples/chat_websocket/server.js +++ b/examples/chat_websocket/server.js @@ -1,8 +1,5 @@ -//const kalm = require('kalm'); -//const ws = require('@kalm/ws'); - -const kalm = require('../../packages/kalm/bin/kalm'); -const ws = require('../../packages/ws/bin/ws'); +const kalm = require('kalm'); +const ws = require('@kalm/ws'); const Server = kalm.listen({ label: 'server',