spacebro-client
Advanced tools
Comparing version 0.0.11 to 1.0.0-0
'use strict' | ||
console.warn('this example is deprecated') | ||
const spacebroClient = require('../') | ||
@@ -4,0 +6,0 @@ |
'use strict' | ||
const spacebroClient = require('../') | ||
console.warn('this example is deprecated') | ||
var spacebroClient = require('../') | ||
var actionList = [ | ||
@@ -6,0 +8,0 @@ { |
{ | ||
"name": "spacebro-client", | ||
"version": "0.0.11", | ||
"version": "1.0.0-0", | ||
"description": "Allow to automagically 🌟 connect to a Spacebro server", | ||
"main": "build/index.js", | ||
"main": "dist/index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"example": "node ./example/index-example.js", | ||
"test": "echo \"Warning: no test specified\" && exit 0", | ||
"example": "node ./example/ponger.js", | ||
"example-no-mdns": "node ./example/index-example-no-mdns.js", | ||
"transform-example": "node ./node_modules/babel-cli/bin/babel ./example/src --out-dir ./example", | ||
"build": "babel src -d build", | ||
@@ -38,11 +39,18 @@ "start": "node ./example/index-example.js" | ||
"mdns": "2.2.11", | ||
"socket.io-client": "1.3.7" | ||
"signals": "^1.0.0", | ||
"socket.io-client": "^1.3.7", | ||
"socketio-wildcard": "^0.3.0" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.3.17", | ||
"babel-preset-es2015": "^6.3.13" | ||
"babel-polyfill": "^6.13.0", | ||
"babel-preset-es2015": "^6.3.13", | ||
"gulp": "^3.9.1", | ||
"gulp-babel": "^6.1.2" | ||
}, | ||
"babel": { | ||
"presets": ["es2015"] | ||
"presets": [ | ||
"es2015" | ||
] | ||
} | ||
} |
@@ -6,48 +6,69 @@ # Spacebro client | ||
# Install | ||
## Installation | ||
```bash | ||
npm i -S spacebro-client | ||
``` | ||
npm install --save spacebro-client | ||
## Basic Usage | ||
# API | ||
First, you need to start a [spaceBro server](https://github.com/soixantecircuits/spacebro). To run one locally, run the following line in your terminal (mind that you need to have spaceBro installed): | ||
```bash | ||
spacebro | ||
``` | ||
spacebroClient = require('spacebro-client') | ||
// This means you will use mdns | ||
spacebroClient.registerToMaster(actionList, clientName, zeroconfName) | ||
// This means you know where to connect | ||
spacebroClient.socketioConnect(server, port, actionList, clientName, zeroconfName) | ||
spacebroClient.emit('event', data) | ||
``` | ||
The actionList parameter is a list of events associated with action (functions) : | ||
Then, it's time to write some code: | ||
```js | ||
const spacebroClient = require('spacebro-client') | ||
spacebroClient.connect('localhost', 8888, { | ||
computer: 'foo', | ||
channel: 'bar' | ||
}) | ||
spacebroClient.on('pong', function () { console.log('pong') }) | ||
spacebroClient.emit('ping') | ||
``` | ||
var actionList = [ | ||
{ | ||
name: 'shoot', | ||
trigger: function (data) { | ||
console.log('someone shoot: ', data) | ||
} | ||
}, | ||
{ | ||
name: 'stop', | ||
trigger: function (data) { | ||
console.log('someone stop: ', data) | ||
} | ||
} | ||
] | ||
``` | ||
Do not forget to add the event you want to broadcast to the actionList. | ||
## Basic API | ||
### spacebroClient.connect(address, port, options) or spacebroClient.connect(options) | ||
The clientName parameter is the name of you client. You will see it in the Spacebro log. | ||
Allows you to connect to a spaceBro server. Options is hash table of settings that will be used to define your client. | ||
If you choose not to pass an address (*string*) and a port (*integer*), spaceBro will try to connect to a server using MDNS. | ||
The zeroconfName is the name of the Spacebro service you want to connect. | ||
Available options are : | ||
- **clientName** (strongly advised) : The name of your app that will be used to receive and send events. | ||
- **channelName** (strongly advised) : The common channel your apps will share. This will allow your to have multiple apps using the same server without worring about conflicts. | ||
- **zeroconfName** (optional) : String that is the name of the service that will be looked for if no address is given. | ||
- **packers** (optional) : Array of packers (see Hooks below), defined as hash object with the properties *handler* (required), *eventName* (all if null), *priority* (0 if null). | ||
- **unpackers** (optional) : Array of unpackers (see Hooks below), defined as hash object with the properties *handler* (required), *eventName* (all if null), *priority* (0 if null). | ||
- **verbose** (optional) : Boolean, if set to false, spaceBro will not show any log. | ||
- **sendBack** (optional) : Boolean, if set to false, you will not receive the event you broadcast. | ||
Enjoy ! | ||
### spacebroClient.emit(eventName, data) | ||
Broadcast a specific event to all the apps in the channel. data must be an object. | ||
Please follow [standard style](https://github.com/feross/standard) conventions. | ||
### spacebroClient.sendTo(eventName, target, data) | ||
Send an event to a specific target in the channel. data must be an object. | ||
### spacebroClient.on(eventName, handler) | ||
Listen to a specific event. | ||
### spacebroClient.once(eventName, handler) | ||
Listen to a specific event, the listener only once. | ||
## Hooks | ||
### Packers | ||
Before you send an event to the server, all packers associated with that event and all global packers (with no associated event) are called and applied to that event. They receive a single argument which is an object with two properties, the eventName and the data, and can return a new version of those data. If nothing is returned, the message will remain unchanged. | ||
### Unpackers | ||
Unpackers are call when you receive a message from the server, before any handler is called. You can use to alter data (same as packers) but also to check the message as if an unpacker returns *false*, the message will not be sent to the handlers, it will also break the unpacking chain. | ||
## Contribute | ||
You can modify the source in `src/index.js`. Run `npm run build` to transpile and test. | ||
Please follow [standard style](https://github.com/feross/standard) conventions. | ||
You can modify the source in `src/index.js`. Run `npm run build` to transpile and test. | ||
Enjoy ! |
205
src/index.js
'use strict' | ||
const io = require('socket.io-client') | ||
const _ = require('lodash') | ||
let staticPort, staticAddress | ||
import patchMaker from 'socketio-wildcard' | ||
import io from 'socket.io-client' | ||
import Signal from 'signals' | ||
import mdns from './mdns' | ||
import _ from 'lodash' | ||
import 'babel-polyfill' | ||
// Default config | ||
let config = { | ||
zeroconfName: 'spacebro', | ||
channelName: null, | ||
clientName: null, | ||
packers: [], | ||
unpackers: [], | ||
sendBack: true, | ||
verbose: true | ||
} | ||
// Variables | ||
let connected = false | ||
let unpackers = [] | ||
let packers = [] | ||
let events = {} | ||
let sockets = [] | ||
const patch = patchMaker(io.Manager) | ||
var socketioInit = function (err, address, port, actionList, clientName) { | ||
if (err) { | ||
console.log(err.stack) | ||
// Initialization | ||
function connect (address, port, options) { | ||
if (typeof address === 'object') { | ||
return connect(false, false, address) | ||
} | ||
let socket | ||
console.log('---------------------------') | ||
socket = io('http://' + address + ':' + port) | ||
socket.on('connect', function () { | ||
sockets.push(socket) | ||
console.log('socketio connected to ' + 'http://' + address + ':' + port) | ||
var nameList = _.map(actionList, function (el) { | ||
return el.name | ||
config = _.merge(config, options) | ||
log('Connect with the config:', config) | ||
if (address && port) { | ||
socketioInit(null, address, port) | ||
} else { | ||
mdns.connectToService(config.zeroconfName, function (err, address, port) { | ||
socketioInit(err, address, port) | ||
}) | ||
socket.emit('register', { eventsList: nameList, clientName: clientName || 'pid-' + process.pid }) | ||
console.log('List of actions registered:') | ||
for (let action of actionList) { | ||
console.log(action.name) | ||
socket.on(action.name, function (data) { | ||
if (action.trigger) { | ||
action.trigger(data) | ||
} | ||
}) | ||
} | ||
console.log('---------------------------') | ||
}) | ||
socket.on('disconnect', function () { | ||
console.log('socket down: ', address + ':' + port) | ||
sockets.splice(sockets.indexOf(socket), 1) | ||
}) | ||
} | ||
for (let packer of config.packers) | ||
addPacker(packer.handler, packer.priority, packer.eventName) | ||
for (let unpacker of config.unpackers) | ||
addUnpacker(unpacker.handler, unpacker.priority, unpacker.eventName) | ||
} | ||
var registerToMaster = function (actionList, clientName, zeroconfName) { | ||
if (staticAddress) { | ||
socketioInit(null, staticAddress, staticPort, actionList, clientName) | ||
} else { | ||
let mdns = require('../lib/mdns.js') | ||
// event propagation for andling error at the top level | ||
// next is implement EventEmitter in spacebro | ||
/* | ||
mdns.on('service-down', function (data) { | ||
console.log(data + ' is down =(') | ||
function socketioInit (err, address, port) { | ||
if (err) log(err.stack) | ||
let url = 'http://' + address + ':' + port | ||
let socket = io(url) | ||
patch(socket) | ||
socket | ||
.on('connect', function () { | ||
log('Socket', url, 'connected') | ||
socket.emit('register', { | ||
clientName: config.clientName, | ||
channelName: config.channelName | ||
}) | ||
sockets.push(socket) | ||
connected = true | ||
}) | ||
*/ | ||
console.log('Waiting for spacebro...') | ||
mdns.connectToService(zeroconfName || 'spacebro', function (err, address, port) { | ||
socketioInit(err, address, port, actionList, clientName) | ||
.on('error', function (err) { | ||
log('Socket', url, 'error:', err) | ||
}) | ||
} | ||
.on('disconnect', function () { | ||
log('Socket', url, 'down') | ||
sockets.splice(sockets.indexOf(socket), 1) | ||
connected = false | ||
}) | ||
.on('*', function ({ data }) { | ||
let [eventName, args] = data | ||
log('Socket', url, 'received', eventName, 'with data:', args) | ||
if (config.sendBack && args._from === config.clientName) return | ||
for (let unpack of filterHooks(eventName, unpackers)) { | ||
let unpacked = unpack({ eventName, data: args }) | ||
if (unpacked === false) return | ||
data = unpacked || data | ||
} | ||
if (_.has(events, eventName)) events[eventName].dispatch(args) | ||
}) | ||
} | ||
var iKnowMyMaster = function (address, port) { | ||
staticPort = port | ||
staticAddress = address | ||
function addPacker (handler, priority, eventName) { addHook(packers, eventName, handler, priority) } | ||
function addUnpacker (handler, priority, eventName) { addHook(unpackers, eventName, handler, priority) } | ||
// Emission | ||
function emit (eventName, data) { | ||
sendTo(eventName, null, data) | ||
} | ||
function sendTo (eventName, to = null, data = {}) { | ||
if (!connected) return log('You\'re not connected.') | ||
data._to = to | ||
data._from = config.clientName | ||
for (let pack of filterHooks(eventName, packers)) | ||
data = pack({ eventName, data }) || data | ||
for (let socket of sockets) socket.emit(eventName, data) | ||
} | ||
// Reception | ||
function on (eventName, handler, handlerContext, priority) { | ||
return touch(eventName).add(handler, handlerContext, priority) | ||
} | ||
function once (eventName, handler, handlerContext, priority) { | ||
return touch(eventName).addOnce(handler, handlerContext, priority) | ||
} | ||
// Disposal | ||
function clear (eventName) { | ||
return touch(eventName).removeAll() | ||
} | ||
function remove (eventName, listener, context) { | ||
return touch(eventName).remove(listener, context) | ||
} | ||
function dispose () { | ||
for (let eventName in events) touch(eventName).dispose() | ||
} | ||
module.exports = { | ||
registerToMaster: registerToMaster, | ||
iKnowMyMaster: iKnowMyMaster, | ||
emit: function (event, data) { | ||
sockets.forEach(function (socket) { | ||
socket.emit(event, data) | ||
}) | ||
connect, addPacker, addUnpacker, | ||
emit, sendTo, | ||
on, once, | ||
clear, remove, dispose, | ||
// Old Stuff | ||
registerToMaster, iKnowMyMaster | ||
} | ||
// = Helpers === | ||
function log (...args) { | ||
if (!config.verbose) return | ||
console.log('SpaceBro -', ...args) | ||
} | ||
function filterHooks (eventName, hooks) { | ||
return hooks | ||
.filter(hook => [eventName, '*'].indexOf(hook.eventName) !== -1) | ||
.sort(hook => -hook.priority || 0) | ||
.map(hook => hook.handler) | ||
} | ||
function addHook (hooks, eventName = '*', handler, priority = 0) { | ||
hooks.push({ eventName, handler, priority }) | ||
} | ||
function touch (eventName) { | ||
if (!_.has(events, eventName)) { | ||
events[eventName] = new Signal() | ||
} | ||
return events[eventName] | ||
} | ||
// Old Stuff | ||
let staticAddress, staticPort | ||
function iKnowMyMaster (address, port) { | ||
staticAddress = address | ||
staticPort = port | ||
} | ||
function registerToMaster (actionList, clientName, zeroconfName) { | ||
return connect(staticAddress, staticPort, { clientName, zeroconfName }) | ||
} |
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
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
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
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
37340
21
769
74
5
5
1
+ Addedsignals@^1.0.0
+ Addedsocketio-wildcard@^0.3.0
+ Addedafter@0.8.2(transitive)
+ Addedbase64-arraybuffer@0.1.5(transitive)
+ Addedcomponent-emitter@1.2.1(transitive)
+ Addeddebug@2.2.02.3.3(transitive)
+ Addedengine.io-client@1.8.6(transitive)
+ Addedengine.io-parser@1.3.2(transitive)
+ Addedhas-binary@0.1.7(transitive)
+ Addedhas-cors@1.1.0(transitive)
+ Addedjson3@3.3.2(transitive)
+ Addedms@0.7.10.7.2(transitive)
+ Addedparsejson@0.0.3(transitive)
+ Addedparseqs@0.0.5(transitive)
+ Addedparseuri@0.0.5(transitive)
+ Addedsignals@1.0.0(transitive)
+ Addedsocket.io-client@1.7.4(transitive)
+ Addedsocket.io-parser@2.3.1(transitive)
+ Addedsocketio-wildcard@0.3.0(transitive)
+ Addedto-array@0.1.4(transitive)
+ Addedws@1.1.5(transitive)
+ Addedwtf-8@1.0.0(transitive)
+ Addedxmlhttprequest-ssl@1.6.3(transitive)
+ Addedyeast@0.1.2(transitive)
- Removedafter@0.8.1(transitive)
- Removedbase64-arraybuffer@0.1.2(transitive)
- Removedbenchmark@1.0.0(transitive)
- Removedbufferutil@1.2.1(transitive)
- Removeddebug@0.7.41.0.4(transitive)
- Removedengine.io-client@1.5.4(transitive)
- Removedengine.io-parser@1.2.2(transitive)
- Removedhas-binary@0.1.6(transitive)
- Removedhas-cors@1.0.3(transitive)
- Removedjson3@3.2.6(transitive)
- Removedms@0.6.2(transitive)
- Removednan@2.4.0(transitive)
- Removedparsejson@0.0.1(transitive)
- Removedparseqs@0.0.2(transitive)
- Removedparseuri@0.0.20.0.4(transitive)
- Removedsocket.io-client@1.3.7(transitive)
- Removedsocket.io-parser@2.2.4(transitive)
- Removedto-array@0.1.3(transitive)
- Removedutf-8-validate@1.2.2(transitive)
- Removedutf8@2.1.0(transitive)
- Removedws@0.8.0(transitive)
Updatedsocket.io-client@^1.3.7