New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

koa-ws-socket

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

koa-ws-socket - npm Package Compare versions

Comparing version 0.0.1 to 0.1.0

CHANGELOG.md

344

dist/koa-ws-socket.umd.js

@@ -1,11 +0,339 @@

(function(global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? factory()
: typeof define === 'function' && define.amd ? define(factory) : factory();
})(this, function() {
'use strict';
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('ws'), require('crypto')) :
typeof define === 'function' && define.amd ? define(['exports', 'ws', 'crypto'], factory) :
(factory((global.koaWsSocket = {}),global.WebSocket,global.crypto));
}(this, (function (exports,WebSocket,crypto) { 'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
exports.default = {};
crypto = crypto && crypto.hasOwnProperty('default') ? crypto['default'] : crypto;
/**
* Expose compositor.
*/
var koaCompose = compose;
/**
* Compose `middleware` returning
* a fully valid middleware comprised
* of all those which are passed.
*
* @param {Array} middleware
* @return {Function}
* @api public
*/
function compose (middleware) {
if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')
for (const fn of middleware) {
if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')
}
/**
* @param {Object} context
* @return {Promise}
* @api public
*/
return function (context, next) {
// last called middleware #
let index = -1;
return dispatch(0)
function dispatch (i) {
if (i <= index) return Promise.reject(new Error('next() called multiple times'))
index = i;
let fn = middleware[i];
if (i === middleware.length) fn = next;
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn(context, function next () {
return dispatch(i + 1)
}))
} catch (err) {
return Promise.reject(err)
}
}
}
}
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var base64id = createCommonjsModule(function (module, exports) {
/*!
* base64id v0.1.0
*/
/**
* Module dependencies
*/
/**
* Constructor
*/
var Base64Id = function() { };
/**
* Get random bytes
*
* Uses a buffer if available, falls back to crypto.randomBytes
*/
Base64Id.prototype.getRandomBytes = function(bytes) {
var BUFFER_SIZE = 4096;
var self = this;
bytes = bytes || 12;
if (bytes > BUFFER_SIZE) {
return crypto.randomBytes(bytes);
}
var bytesInBuffer = parseInt(BUFFER_SIZE/bytes);
var threshold = parseInt(bytesInBuffer*0.85);
if (!threshold) {
return crypto.randomBytes(bytes);
}
if (this.bytesBufferIndex == null) {
this.bytesBufferIndex = -1;
}
if (this.bytesBufferIndex == bytesInBuffer) {
this.bytesBuffer = null;
this.bytesBufferIndex = -1;
}
// No buffered bytes available or index above threshold
if (this.bytesBufferIndex == -1 || this.bytesBufferIndex > threshold) {
if (!this.isGeneratingBytes) {
this.isGeneratingBytes = true;
crypto.randomBytes(BUFFER_SIZE, function(err, bytes) {
self.bytesBuffer = bytes;
self.bytesBufferIndex = 0;
self.isGeneratingBytes = false;
});
}
// Fall back to sync call when no buffered bytes are available
if (this.bytesBufferIndex == -1) {
return crypto.randomBytes(bytes);
}
}
var result = this.bytesBuffer.slice(bytes*this.bytesBufferIndex, bytes*(this.bytesBufferIndex+1));
this.bytesBufferIndex++;
return result;
};
/**
* Generates a base64 id
*
* (Original version from socket.io <http://socket.io>)
*/
Base64Id.prototype.generateId = function () {
var rand = new Buffer(15); // multiple of 3 for base64
if (!rand.writeInt32BE) {
return Math.abs(Math.random() * Math.random() * Date.now() | 0).toString()
+ Math.abs(Math.random() * Math.random() * Date.now() | 0).toString();
}
this.sequenceNumber = (this.sequenceNumber + 1) | 0;
rand.writeInt32BE(this.sequenceNumber, 11);
if (crypto.randomBytes) {
this.getRandomBytes(12).copy(rand);
} else {
// not secure for node 0.4
[0, 4, 8].forEach(function(i) {
rand.writeInt32BE(Math.random() * Math.pow(2, 32) | 0, i);
});
}
return rand.toString('base64').replace(/\//g, '_').replace(/\+/g, '-');
};
/**
* Export
*/
exports = module.exports = new Base64Id();
});
var Socket = /** @class */ (function () {
function Socket(ws, request, listeners, middleware) {
this.ws = ws;
this.request = request;
this.middleware = middleware;
this.update(listeners, middleware);
}
Socket.prototype.update = function (listeners, middleware) {
var _this = this;
this.ws.removeAllListeners();
this.middleware = middleware;
listeners.forEach(function (handlers, event) {
if (event === 'connection') {
return;
}
handlers.forEach(function (handler) {
_this.on(event, handler);
});
});
};
/**
* Adds a specific event and callback to this socket
*/
Socket.prototype.on = function (event, handler) {
var _this = this;
this.ws.on(event, function (message) {
var ctx = {
event: event,
data: message,
request: _this.request,
socket: _this.ws,
};
if (!_this.middleware) {
handler(ctx, message);
return;
}
_this.middleware(ctx).then(function () {
handler(ctx, message);
});
});
};
return Socket;
}());
var WsSocket = /** @class */ (function () {
function WsSocket() {
var _this = this;
this.middleware = [];
this.composed = null;
this.connections = new Map();
this.listeners = new Map();
this.wss = null;
this.onConnection = function (ws, request) {
var socketId = base64id.generateId();
var socketInstance = new Socket(ws, request, _this.listeners, _this.composed);
_this.connections.set(socketId, socketInstance);
ws.on('disconnect', function () {
_this.connections.delete(socketId);
});
var handlers = _this.listeners.get('connection');
if (handlers) {
handlers.forEach(function (handler) {
handler({
event: 'connection',
data: socketInstance,
request: request,
socket: ws,
}, null);
});
}
};
}
WsSocket.prototype.attach = function (app, https, tlsOpts) {
if (https === void 0) { https = false; }
if (tlsOpts === void 0) { tlsOpts = {}; }
var enhancedApp = app;
if (enhancedApp.server &&
enhancedApp.server.constructor.name !== 'Server') {
throw new Error("app.server already exists but it's not an http server");
}
if (!enhancedApp.server) {
// Create a server if it doesn't already exists
enhancedApp.server = https
? require('https').createServer(tlsOpts, enhancedApp.callback())
: require('http').createServer(enhancedApp.callback());
// Patch `app.listen()` to call `app.server.listen()`
enhancedApp.listen = function listen() {
enhancedApp.server.listen.apply(enhancedApp.server, arguments);
return enhancedApp.server;
};
}
this.wss = new WebSocket.Server({ server: enhancedApp.server });
enhancedApp.ws = this;
this.wss.on('connection', this.onConnection);
};
/**
* Pushes a middleware on to the stack
* @param fn <Function> the middleware function to execute
*/
WsSocket.prototype.use = function (fn) {
this.middleware.push(fn);
this.composed = koaCompose(this.middleware);
this.updateConnections();
return this;
};
/**
* Adds a new listener to the stack
* @param event <String> the event id
* @param handler <Function> the callback to execute
* @return this
*/
WsSocket.prototype.on = function (event, handler) {
var listeners = this.listeners.get(event);
// If this is a new event then just set it
if (!listeners) {
this.listeners.set(event, [handler]);
this.updateConnections();
return this;
}
listeners.push(handler);
this.listeners.set(event, listeners);
this.updateConnections();
return this;
};
/**
* Removes a listener from the event
* @param event <String> if omitted will remove all listeners
* @param handler <Function> if omitted will remove all from the event
* @return this
*/
WsSocket.prototype.off = function (event, handler) {
if (!event) {
this.listeners = new Map();
this.updateConnections();
return this;
}
if (!handler) {
this.listeners.delete(event);
this.updateConnections();
return this;
}
var listeners = this.listeners.get(event) || [];
var i = listeners.length - 1;
while (i) {
if (listeners[i] === handler) {
break;
}
i--;
}
listeners.splice(i, 1);
this.updateConnections();
return this;
};
/**
* Updates all existing connections with current listeners and middleware
* @private
*/
WsSocket.prototype.updateConnections = function () {
var _this = this;
this.connections.forEach(function (connection) {
return connection.update(_this.listeners, _this.composed);
});
};
return WsSocket;
}());
exports.WsSocket = WsSocket;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=koa-ws-socket.umd.js.map

@@ -1,2 +0,51 @@

declare const _default: {};
export default _default;
/// <reference types="node" />
/// <reference types="ws" />
/// <reference types="koa-compose" />
/// <reference types="koa" />
import * as http from 'http';
import { TlsOptions } from 'tls';
import * as Koa from 'koa';
import compose from 'koa-compose';
import * as WebSocket from 'ws';
import Socket from './socket';
export interface SocketContext {
data: any;
event: string;
request: http.ServerRequest;
socket: WebSocket;
}
export declare type EventHandler = (ctx: SocketContext, data: any) => any;
export declare type Middleware = (ctx: SocketContext, next: () => Promise<any>) => any;
export declare class WsSocket {
middleware: Middleware[];
composed: compose.ComposedMiddleware<SocketContext> | null;
connections: Map<string, Socket>;
listeners: Map<string, EventHandler[]>;
wss: WebSocket.Server | null;
attach(app: Koa, https?: boolean, tlsOpts?: TlsOptions): void;
onConnection: (ws: WebSocket, request: http.IncomingMessage) => void;
/**
* Pushes a middleware on to the stack
* @param fn <Function> the middleware function to execute
*/
use(fn: Middleware): this;
/**
* Adds a new listener to the stack
* @param event <String> the event id
* @param handler <Function> the callback to execute
* @return this
*/
on(event: string, handler: EventHandler): this;
/**
* Removes a listener from the event
* @param event <String> if omitted will remove all listeners
* @param handler <Function> if omitted will remove all from the event
* @return this
*/
off(event: string, handler: EventHandler): this;
/**
* Updates all existing connections with current listeners and middleware
* @private
*/
updateConnections(): void;
}

32

package.json
{
"name": "koa-ws-socket",
"version": "0.0.1",
"description":
"Attaches ws sockets to koa and allows koa-style middleware for them",
"files": ["dist"],
"version": "0.1.0",
"description": "Attaches ws sockets to koa using koa-style middleware",
"files": [
"dist"
],
"main": "dist/koa-ws-socket.umd.js",
"module": "dist/koa-ws-socket.es5.js",
"typings": "dist/types/koa-ws-socket.d.ts",
"types": "dist/types/index.d.ts",
"repository": "https://github.com/pbomb/koa-ws-socket.git",

@@ -20,6 +21,4 @@ "author": "Matt Parrish <matt.r.parrish@gmail.com>",

"prebuild": "rimraf dist && rimraf compiled",
"build":
"npm run tsc && BUILD_INPUT=compiled/index.js kcd-scripts build --bundle --no-clean",
"lint":
"tslint -c tslint.json -e **/node_modules/**/* -e **/typings/**/* **/*.ts",
"build": "rollup --config rollup.config.ts --no-clean",
"lint": "tslint -c tslint.json -e **/node_modules/**/* -e **/typings/**/* **/*.ts",
"test": "kcd-scripts test",

@@ -38,2 +37,4 @@ "test:cover": "kcd-scripts test --coverage",

"@types/koa": "2.0.39",
"@types/koa-compose": "3.2.2",
"@types/ws": "3.2.0",
"kcd-scripts": "0.24.0",

@@ -43,3 +44,7 @@ "koa": "2.3.0",

"rimraf": "2.6.2",
"rollup": "0.50.0",
"rollup-plugin-commonjs": "8.2.1",
"rollup-plugin-node-resolve": "3.0.0",
"rollup-plugin-sourcemaps": "0.4.2",
"rollup-plugin-typescript2": "0.7.0",
"tslint": "5.7.0",

@@ -53,7 +58,6 @@ "typescript": "2.5.3",

},
"lint-staged": {
"*.ts": ["prettier --write", "git add"],
"*.js": ["prettier --write", "git add"],
"*.json": ["prettier --write", "git add"]
"dependencies": {
"base64id": "^1.0.0",
"koa-compose": "^4.0.0"
}
}
}

@@ -0,2 +1,61 @@

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [koa-ws-socket](#koa-ws-socket)
- [Contributors](#contributors)
- [LICENSE](#license)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# koa-ws-socket
Attaches ws sockets to koa and allows koa-style middleware for them
Attaches [ws](https://github.com/websockets/ws) sockets to koa using koa-style middleware.
[![Build Status][build-badge]][build]
[![Code Coverage][coverage-badge]][coverage]
[![version][version-badge]][package]
[![downloads][downloads-badge]][npmcharts]
[![MIT License][license-badge]][LICENSE]
[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors)
[![PRs Welcome][prs-badge]][prs]
[![Code of Conduct][coc-badge]][coc]
## Contributors
Thanks goes to these people ([emoji key][emojis]):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
| [<img src="https://avatars0.githubusercontent.com/u/1402095?v=4" width="100px;"/><br /><sub>Matt Parrish</sub>](https://github.com/pbomb)<br />[💻](https://github.com/pbomb/koa-ws-socket/commits?author=pbomb "Code") [📖](https://github.com/pbomb/koa-ws-socket/commits?author=pbomb "Documentation") [⚠️](https://github.com/pbomb/koa-ws-socket/commits?author=pbomb "Tests") [👀](#review-pbomb "Reviewed Pull Requests") |
| :---: |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors][all-contributors] specification.
Contributions of any kind welcome!
## LICENSE
MIT
[build-badge]: https://img.shields.io/travis/pbomb/koa-ws-socket.svg?style=flat-square
[build]: https://travis-ci.org/pbomb/koa-ws-socket
[coverage-badge]: https://img.shields.io/codecov/c/github/pbomb/koa-ws-socket.svg?style=flat-square
[coverage]: https://codecov.io/github/pbomb/koa-ws-socket
[version-badge]: https://img.shields.io/npm/v/koa-ws-socket.svg?style=flat-square
[package]: https://www.npmjs.com/package/koa-ws-socket
[downloads-badge]: https://img.shields.io/npm/dm/koa-ws-socket.svg?style=flat-square
[npmcharts]: https://npmcharts.com/compare/koa-ws-socket
[license-badge]: https://img.shields.io/npm/l/koa-ws-socket.svg?style=flat-square
[license]: https://github.com/pbomb/koa-ws-socket/blob/master/LICENSE
[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[prs]: http://makeapullrequest.com
[chat]: https://gitter.im/pbomb/koa-ws-socket
[chat-badge]: https://img.shields.io/gitter/room/pbomb/koa-ws-socket.svg?style=flat-square
[coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square
[coc]: https://github.com/pbomb/koa-ws-socket/blob/master/other/CODE_OF_CONDUCT.md
[github-watch-badge]: https://img.shields.io/github/watchers/pbomb/koa-ws-socket.svg?style=social
[github-watch]: https://github.com/pbomb/koa-ws-socket/watchers
[github-star-badge]: https://img.shields.io/github/stars/pbomb/koa-ws-socket.svg?style=social
[github-star]: https://github.com/pbomb/koa-ws-socket/stargazers
[emojis]: https://github.com/kentcdodds/all-contributors#emoji-key
[all-contributors]: https://github.com/kentcdodds/all-contributors

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc