feedme-transport-ws
Advanced tools
Comparing version 0.0.3 to 0.0.4
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.default = feedmeTransportWsClient; | ||
var _ws = _interopRequireDefault(require("ws")); | ||
var _client = _interopRequireDefault(require("./client.main")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
* Create a Node client with the ws module injected (dependency injection to | ||
* facilitate unit testing). | ||
* @param {string} address | ||
* @param {?Object} options | ||
* @returns {Client} | ||
*/ | ||
function feedmeTransportWsClient(address, options) { | ||
return (0, _client.default)(_ws.default, address, options || {}); | ||
} | ||
module.exports = exports.default; | ||
//# sourceMappingURL=client.js.map |
23
index.js
@@ -1,2 +0,21 @@ | ||
// Copied by Gulp into the build as an entry-point | ||
module.exports = require("./main.js"); | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.default = void 0; | ||
var _client = _interopRequireDefault(require("./client")); | ||
var _browser = _interopRequireDefault(require("./browser")); | ||
var _server = _interopRequireDefault(require("./server")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
* Common entry point for server, client, and browser modules. | ||
* @returns {Object} | ||
*/ | ||
var _default = exports.default = { | ||
client: _client.default, | ||
browser: _browser.default, | ||
server: _server.default | ||
}; | ||
module.exports = exports.default; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "feedme-transport-ws", | ||
"version": "0.0.3", | ||
"description": "Feedme WebSocket transport for Node.js", | ||
"version": "0.0.4", | ||
"description": "Feedme WebSocket transport for Node.js and the browser", | ||
"main": "index.js", | ||
"scripts": { | ||
"build": "npm run test-src && gulp build && npm run test-build-node", | ||
"docs": "documentation build src/client.node.js src/client.browser.js src/server.js -f html -o docs --access public --access private --access undefined --sort-order alpha", | ||
"build": "npm run test-src && babel-node build.js && npm run test-build-node", | ||
"lint-src": "eslint src/**", | ||
"lint-build-tests": "eslint tests/**", | ||
"lint-build-tests": "eslint \"tests/browsers/*.js\" && eslint \"tests/node/*.js\"", | ||
"test": "npm run test-src", | ||
"test-src": "npm run lint-src && jest /src", | ||
"test-build-node": "npm run lint-build-tests && jest /tests", | ||
"test-src": "npm run lint-src && jest src", | ||
"test-build-node": "npm run lint-build-tests && jest tests/node", | ||
"test-build-browsers": "npm run lint-build-tests && babel-node tests/browsers/test.js", | ||
"coverage": "jest --coverage", | ||
"coveralls": "jest --coverage --coverageReporters=text-lcov | coveralls" | ||
}, | ||
"dependencies": { | ||
"check-types": "^11.2.3", | ||
"component-emitter": "^1.3.1", | ||
"debug": "^4.1.1", | ||
"json-expressible": "^1.0.5", | ||
"lodash": "^4.17.21", | ||
"source-map-support": "^0.5.11", | ||
"uuid": "^9.0.1", | ||
"ws": "^6.2.1" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.2.3", | ||
"@babel/core": "^7.3.4", | ||
"@babel/preset-env": "^7.3.4", | ||
"@babel/register": "^7.0.0", | ||
"babel-core": "^7.0.0-bridge.0", | ||
"babel-plugin-add-module-exports": "^1.0.0", | ||
"babelify": "^10.0.0", | ||
"browserify": "^16.2.3", | ||
"coveralls": "^3.0.3", | ||
"del": "^4.0.0", | ||
"eslint": "^5.12.0", | ||
"eslint-config-airbnb-base": "^13.1.0", | ||
"eslint-config-prettier": "^3.1.0", | ||
"eslint-plugin-import": "^2.14.0", | ||
"eslint-plugin-prettier": "^3.0.1", | ||
"@babel/cli": "^7.23.9", | ||
"@babel/core": "^7.23.9", | ||
"@babel/node": "^7.23.9", | ||
"@babel/preset-env": "^7.23.9", | ||
"@babel/register": "^7.23.7", | ||
"async": "^3.2.5", | ||
"babel-loader": "^9.1.3", | ||
"babel-plugin-add-module-exports": "^1.0.4", | ||
"core-js": "^3.6.5", | ||
"documentation": "^14.0.3", | ||
"eslint": "^8.57.0", | ||
"eslint-config-airbnb-base": "^15.0.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-import": "^2.29.1", | ||
"eslint-plugin-prettier": "^5.1.3", | ||
"express": "^4.16.4", | ||
"feedme-client": "0.0.35", | ||
"feedme-server-core": "0.0.4", | ||
"fs-copy-file-sync": "^1.1.1", | ||
"ghooks": "^2.0.4", | ||
"gulp": "^4.0.0", | ||
"gulp-babel": "^8.0.0", | ||
"gulp-cli": "^2.0.1", | ||
"gulp-rename": "^1.4.0", | ||
"gulp-replace": "^1.0.0", | ||
"gulp-sourcemaps": "^2.6.5", | ||
"gulp-uglify": "^3.0.2", | ||
"prettier": "^1.14.3", | ||
"jest": "^23.6.0", | ||
"jest-cli": "^23.6.0", | ||
"vinyl-buffer": "^1.0.1", | ||
"vinyl-source-stream": "^2.0.0" | ||
"glob": "^10.3.10", | ||
"hostile": "^1.3.2", | ||
"jest": "^29.7.0", | ||
"jest-cli": "^29.7.0", | ||
"make-promises-safe": "^5.1.0", | ||
"prettier": "^3.2.5", | ||
"promise-timeout": "^1.3.0", | ||
"promisify-event": "^1.0.0", | ||
"promisify-function": "^1.3.2", | ||
"request": "^2.88.2", | ||
"sauce-connect-launcher": "^1.2.4", | ||
"webpack": "^5.90.3" | ||
}, | ||
"overrides": { | ||
"feedme-client": { | ||
"feedme-util": "0.2.1" | ||
}, | ||
"feedme-server-core": { | ||
"feedme-util": "0.2.1" | ||
} | ||
}, | ||
"repository": { | ||
@@ -66,3 +90,3 @@ "type": "git", | ||
"collectCoverageFrom": [ | ||
"src/**/*.{js}" | ||
"src/**/*.js" | ||
], | ||
@@ -69,0 +93,0 @@ "testMatch": [ |
425
README.md
@@ -1,2 +0,2 @@ | ||
[![Build Status](https://travis-ci.com/aarong/feedme-transport-ws.svg?branch=master)](https://travis-ci.com/aarong/feedme-transport-ws) | ||
[![CI-CD](https://github.com/aarong/feedme-transport-ws/actions/workflows/built-test-deploy.yml/badge.svg)](https://github.com/aarong/feedme-transport-ws/actions/workflows/built-test-deploy.yml) | ||
[![Coverage Status](https://coveralls.io/repos/github/aarong/feedme-transport-ws/badge.svg?branch=master)](https://coveralls.io/github/aarong/feedme-transport-ws?branch=master) | ||
@@ -6,8 +6,423 @@ | ||
# Feedme WebSocket Transport | ||
# Feedme Javascript WebSocket Transport | ||
Client and server Feedme transport. | ||
WebSocket transports for the | ||
[Feedme Javascript Client](https://github.com/aarong/feedme-client) and | ||
[Feedme Node.js Server Core](https://github.com/aarong/feedme-server-core) | ||
libraries. | ||
Works with: | ||
The server transport runs on Node.js. The client transport runs on Node.js and | ||
in the browser. | ||
aarong/feedme-client aarong/feedme-server-core | ||
Created and maintained as a core part of the [Feedme](https://feedme.global) | ||
project. | ||
<!-- TOC depthFrom:2 --> | ||
- [Feedme Javascript WebSocket Transport](#feedme-javascript-websocket-transport) | ||
- [Server](#server) | ||
- [Installation](#installation) | ||
- [Initialization](#initialization) | ||
- [Usage: Feedme API on a Stand-Alone WebSocket Server](#usage-feedme-api-on-a-stand-alone-websocket-server) | ||
- [Usage: Feedme API on an Existing HTTP/S Server](#usage-feedme-api-on-an-existing-https-server) | ||
- [Usage: Multiple Feedme APIs on a Single HTTP/S Server](#usage-multiple-feedme-apis-on-a-single-https-server) | ||
- [WebSocket Errors](#websocket-errors) | ||
- [Node.js Client](#nodejs-client) | ||
- [Installation](#installation-1) | ||
- [Initialization](#initialization-1) | ||
- [WebSocket Errors](#websocket-errors-1) | ||
- [Browser Client](#browser-client) | ||
- [Installation](#installation-2) | ||
- [Initialization](#initialization-2) | ||
- [WebSocket Errors](#websocket-errors-2) | ||
- [Compatibility](#compatibility) | ||
<!-- /TOC --> | ||
## Server | ||
The server transport lets you serve a Feedme API over WebSockets in Node.js. | ||
The server transport is built on top of the | ||
[ws module](https://github.com/websockets/ws) and supports everything that it | ||
does, including HTTPS and compression. The transport depends on ws version 6.2.x | ||
in order to retain Node 6 support. | ||
### Installation | ||
To install the NPM package: | ||
`npm install feedme-server-core feedme-transport-ws` | ||
### Initialization | ||
To initialize a Feedme server: | ||
```javascript | ||
const feedmeServerCore = require("feedme-server-core"); | ||
const feedmeTransportWs = require("feedme-transport-ws/server"); | ||
const server = feedmeServerCore({ | ||
transport: feedmeTransportWs(options), | ||
}); | ||
``` | ||
The `options` argument is passed internally to the ws module and can be used to | ||
configure the underlying WebSocket server. See the | ||
[ws documentation](https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback) | ||
for options. The application must not specify the `handleProtocols` option, | ||
which is used internally by the transport. | ||
The transport also incorporates a heartbeat system, which can be confired using: | ||
- `options.heartbeatIntervalMs` - Optional non-negative integer. Defaults | ||
to 5000. | ||
Specifies how often to send a WebSocket ping to each client to ensure | ||
continued responsiveness. | ||
If set to 0, then the server will not ping clients. | ||
- `options.heartbeatTimeoutMs` - Optional positive integer. Defaults to 4500. | ||
Specifies how long to wait after pinging a client until the connection is | ||
considered to have been lost and the WebSocket is terminated. | ||
Must be strictly less than `options.heartbeatIntervalMs` if specified. | ||
Errors thrown: | ||
- `err.message === "INVALID_ARGUMENT"` | ||
There was a problem with one or more of the supplied arguments. | ||
### Usage: Feedme API on a Stand-Alone WebSocket Server | ||
To serve a Feedme API on a single-purpose WebSocket server accepting connections | ||
on all paths: | ||
```javascript | ||
const feedmeServerCore = require("feedme-server-core"); | ||
const feedmeTransportWs = require("feedme-transport-ws/server"); | ||
const server = feedmeServerCore({ | ||
transport: feedmeTransportWs({ | ||
port: 8080, | ||
}), | ||
}); | ||
server.start(); | ||
``` | ||
### Usage: Feedme API on an Existing HTTP/S Server | ||
To serve a Feedme API on a specific path of an existing HTTP/S server: | ||
```javascript | ||
const http = require("http"); | ||
const feedmeServerCore = require("feedme-server-core"); | ||
const feedmeTransportWs = require("feedme-transport-ws/server"); | ||
const httpServer = http.createServer(function (req, res) => { | ||
res.writeHead(200); | ||
res.end("Welcome"); | ||
}); | ||
httpServer.listen(8080); | ||
const feedmeServer = feedmeServerCore({ | ||
transport: feedmeTransportWs({ | ||
server: httpServer, | ||
path: "/feedme" | ||
}) | ||
}); | ||
feedmeServer.start(); | ||
``` | ||
When serving a Feedme API on an existing HTTP/S server: | ||
- The external HTTP server is not required to be listening in order to | ||
initialize the Feedme transport and server. The transport does not attempt to | ||
start or stop the external HTTP server. | ||
- If there is a call to `feedmeServer.start()` and the external HTTP server is | ||
not already listening, then `feedmeServer` will become `starting` and wait for | ||
the HTTP server to be started by the application, at which point | ||
`feedmeServer` will become `started`. If the HTTP server is already listening | ||
when the application calls `feedmeServer.start()`, then `feedmeServer` will | ||
become `started` immediately. | ||
- If the external HTTP server stops listening for new connections, either due to | ||
a failure or an application call to `httpServer.close()`, then `feedmeServer` | ||
will automatically become `stopped` and any existing clients will be | ||
disconnected. If the external HTTP server is subsequently restarted then the | ||
application must call `feedmeServer.start()` to re-launch the Feedme server. | ||
- If there is a call to `feedmeServer.stop()` while the external HTTP server is | ||
running then the WebSocket endpoint is removed and the external server is left | ||
running. | ||
### Usage: Multiple Feedme APIs on a Single HTTP/S Server | ||
To serve multiple Feedme APIs on a single HTTP/S server: | ||
```javascript | ||
const http = require("http"); | ||
const feedmeServerCore = require("feedme-server-core"); | ||
const feedmeTransportWs = require("feedme-transport-ws/server"); | ||
// Create the basic HTTP server | ||
const httpServer = http.createServer((req, res) => { | ||
res.writeHead(200); | ||
res.end("Welcome"); | ||
}); | ||
httpServer.listen(port); | ||
// Create the first Feedme server | ||
const feedmeTransport1 = feedmeTransportWs({ | ||
noServer: true, | ||
}); | ||
const feedmeServer1 = feedmeServerCore({ | ||
transport: feedmeTransport1, | ||
}); | ||
feedmeServer1.start(); | ||
// Create the second Feedme server | ||
const feedmeTransport2 = feedmeTransportWs({ | ||
noServer: true, | ||
}); | ||
const feedmeServer2 = feedmeServerCore({ | ||
transport: feedmeTransport2, | ||
}); | ||
feedmeServer2.start(); | ||
// Route WebSocket upgrade requests to the appropriate Feedme transport | ||
httpServer.on("upgrade", (request, socket, head) => { | ||
const { pathname } = url.parse(request.url); | ||
if (pathname === "/feedme1") { | ||
feedmeTransport1.handleUpgrade(request, socket, head); | ||
} else if (pathname === "/feedme2") { | ||
feedmeTransport2.handleUpgrade(request, socket, head); | ||
} else { | ||
socket.destroy(); | ||
} | ||
}); | ||
``` | ||
When serving a Feedme API in `noServer` mode: | ||
- The transport has no way of knowing whether the external HTTP server is | ||
listening for connections. It is up to the application to start and stop the | ||
Feedme server as appropriate. | ||
- The application must call `feedmeServerX.start()` before making calls to | ||
`feedmeTransportX.handleUpgrade()`. The Feedme server will immediately become | ||
`started`. | ||
- A call to `httpServer.close()` will cause the external HTTP server to stop | ||
listening for new connections, but it will not terminate existing connections | ||
and `httpServer` will not emit close until all WebSocket clients have | ||
disconnected. If the application closes the external HTTP server, it should | ||
also call `feedmeServerX.stop()`, which will cause the transport to close all | ||
existing WebSocket connections. | ||
### WebSocket Errors | ||
The transport makes the following ws-level error information available to | ||
applications via the Feedme server library. | ||
- If there is a problem initializing the ws module then the error thrown by ws | ||
is made available to server library | ||
[stopping](https://github.com/aarong/feedme-server-core#stopping) and | ||
[stop](https://github.com/aarong/feedme-server-core#stop) event handlers as | ||
`err.wsError`. | ||
- If the ws module or an external HTTP server emits a `close` event then the | ||
associated error is made available to the server library | ||
[stopping](https://github.com/aarong/feedme-server-core#stopping) and | ||
[stop](https://github.com/aarong/feedme-server-core#stop) event handlers as | ||
`err.wsError`. | ||
* When a client connection closes unexpectedly, the WebSocket disconnect code | ||
and reason are made available to server library | ||
[disconnect](https://github.com/aarong/feedme-server-core#disconnectg) event | ||
handlers as `err.wsCode` and `err.wsReason`. | ||
* If the ws module calls back an error when attempting to send a message or a | ||
ping to a client then the error is made available to server library | ||
[disconnect](https://github.com/aarong/feedme-server-core#disconnectg) event | ||
handlers as `err.wsError`. | ||
## Node.js Client | ||
The Node.js client transport lets you connect to a Feedme API server over | ||
Webockets from Node.js. | ||
The Node.js client is built on top of the | ||
[ws module](https://github.com/websockets/ws) and supports everything it does, | ||
including HTTPS and compression. The client depends on ws version 6.2.x in order | ||
to retain Node 6 support. | ||
### Installation | ||
To install the NPM package: | ||
`npm install feedme-transport-ws` | ||
### Initialization | ||
To initialize a Feedme client: | ||
```javascript | ||
const feedmeClient = require("feedme-client"); | ||
const feedmeTransportWs = require("feedme-transport-ws/client"); | ||
const client = feedmeClient({ | ||
transport: feedmeTransportWs(address, options); | ||
}); | ||
``` | ||
Transport factory function arguments: | ||
- `address` - Required string. The server WebSocket URL (ws://...) | ||
- `options` Optional object. The object is passed to the ws module and can be | ||
used to configure the underlying WebSocket client. See the | ||
[ws documentation](https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketaddress-protocols-options) | ||
for options. | ||
The Node transport client also incorporates a heartbeat system, which can be | ||
configured using: | ||
- `options.heartbeatIntervalMs` - Optional non-negative integer. Defaults | ||
to 5000. | ||
Specifies how often to send a WebSocket ping to the server to ensure | ||
responsiveness. | ||
If set to 0, then the client will not ping the server. | ||
- `options.heartbeatTimeoutMs` - Optional positive integer. Defaults to 4999. | ||
Specifies how long to wait after pinging the server until the connection is | ||
considered to have been lost. | ||
Must be strictly less than `options.heartbeatIntervalMs` if specified. | ||
Errors thrown: | ||
- `err.message === "INVALID_ARGUMENT"` | ||
There was a problem with one or more of the supplied arguments. | ||
### WebSocket Errors | ||
The transport makes the following ws-level error information available to | ||
applications via the Feedme client library. | ||
- If there is a problem initializing the ws module then the error thrown by ws | ||
is made available to client library | ||
[disconnect]((https://github.com/aarong/feedme-client#disconnect) event | ||
handlers as `err.wsError`. | ||
- If the connection closes unexpectedly, the WebSocket disconnect code and | ||
reason are made available to client library | ||
[disconnect](https://github.com/aarong/feedme-client#disconnect) event | ||
handlers as `err.wsCode` and `err.wsReason`. | ||
- If the ws module calls back an error when attempting to send a message or a | ||
ping to the server then the error is made available to client library | ||
[disconnect]((https://github.com/aarong/feedme-client#disconnect) event | ||
handlers as `err.wsError`. | ||
## Browser Client | ||
The browser client transport lets you connect to a Feedme API server over | ||
Webockets using the native WebSocket implementation available in the browser. | ||
Unlike the Node.js client, the browser client does not have a heartbeat feature | ||
because browser WebSocket implementations do not expose a ping API. Heartbeat | ||
functionality is left to the browser. | ||
### Installation | ||
To install the NPM package: | ||
`npm install feedme-transport-ws` | ||
To access using a CDN: | ||
```html | ||
<script | ||
type="text/javascript" | ||
src="https://cdn.jsdelivr.net/npm/feedme-transport-ws" | ||
></script> | ||
``` | ||
The module is named `feedmeTransportWs` in the global scope. | ||
### Initialization | ||
To initialize a Feedme client: | ||
```javascript | ||
const feedmeClient = require("feedme-client"); | ||
const feedmeTransportWs = require("feedme-transport-ws/browser"); | ||
const client = feedmeClient({ | ||
transport: feedmeTransportWs(address); | ||
}); | ||
client.connect(); | ||
``` | ||
Transport factory function arguments: | ||
- `address` - Required string. The server WebSocket URL. | ||
Errors thrown: | ||
- `err.message === "INVALID_ARGUMENT"` | ||
There was a problem with one or more of the supplied arguments. | ||
- `err.message === "NO_WEBSOCKETS"` | ||
There is no WebSocket implementation available. | ||
### WebSocket Errors | ||
The transport makes the following WebSocket-level error information available to | ||
applications via the Feedme client library. | ||
- If an error is thrown when initializing a WebSocket object then the error is | ||
made available to client library | ||
[disconnect]((https://github.com/aarong/feedme-client#disconnect) event | ||
handlers as `err.wsError`. | ||
- If the connection closes unexpectedly, the WebSocket disconnect code and | ||
reason are made available to client library | ||
[disconnect](https://github.com/aarong/feedme-client#disconnect) event | ||
handlers as `err.wsCode` and `err.wsReason`. | ||
- If an error is thrown when attempting to send a message to the server then the | ||
error is made available to client library | ||
[disconnect]((https://github.com/aarong/feedme-client#disconnect) event | ||
handlers as `err.wsError`. | ||
## Compatibility | ||
The server module should be compatible be with third-party WebSocket client | ||
transports that: | ||
1. Specify either no WebSocket subprotocol or a `feedme` subprotocol. | ||
2. Transmit Feedme messages by sending a single string across the WebSocket. | ||
3. Do not transmit anything else on the WebSocket. | ||
The client module should be compatible with third-party WebSocket server | ||
transports that: | ||
1. Accept connections with a `feedme` WebSocket subprotocol. | ||
2. Transmit Feedme messages by sending a single string across the WebSocket. | ||
3. Do not transmit anything else on the WebSocket. |
@@ -6,7 +6,16 @@ "use strict"; | ||
}); | ||
exports["default"] = serverFactory; | ||
function serverFactory() {} | ||
exports.default = feedmeTransportWsServer; | ||
var _ws = _interopRequireDefault(require("ws")); | ||
var _server = _interopRequireDefault(require("./server.main")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
* Create a server with the ws module injected (dependency injection to | ||
* facilitate unit testing). | ||
* @param {Object} options | ||
* @returns {Server} | ||
*/ | ||
function feedmeTransportWsServer(options) { | ||
return (0, _server.default)(_ws.default.Server, options); | ||
} | ||
module.exports = exports.default; | ||
//# sourceMappingURL=server.js.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1352776
25
1883
428
8
32
2
+ Addedcheck-types@^11.2.3
+ Addedcomponent-emitter@^1.3.1
+ Addeddebug@^4.1.1
+ Addedjson-expressible@^1.0.5
+ Addedlodash@^4.17.21
+ Addedsource-map-support@^0.5.11
+ Addeduuid@^9.0.1
+ Addedws@^6.2.1
+ Addedasync-limiter@1.0.1(transitive)
+ Addedbuffer-from@1.1.2(transitive)
+ Addedcheck-types@11.2.3(transitive)
+ Addedcomponent-emitter@1.3.1(transitive)
+ Addeddebug@4.4.0(transitive)
+ Addedjson-expressible@1.0.5(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedms@2.1.3(transitive)
+ Addedsource-map@0.6.1(transitive)
+ Addedsource-map-support@0.5.21(transitive)
+ Addeduuid@9.0.1(transitive)
+ Addedws@6.2.3(transitive)