Comparing version 3.0.1 to 4.0.0
@@ -0,1 +1,3 @@ | ||
/* eslint-disable no-console */ | ||
'use strict'; | ||
@@ -9,3 +11,3 @@ var osc = require('../lib'); | ||
} | ||
client.kill(); | ||
client.close(); | ||
}); | ||
@@ -12,0 +14,0 @@ |
@@ -0,1 +1,3 @@ | ||
/* eslint-disable no-console */ | ||
'use strict'; | ||
@@ -8,2 +10,3 @@ var osc = require('../lib'); | ||
console.log(msg); | ||
oscServer.kill(); | ||
}); |
'use strict'; | ||
var dgram = require('dgram'); | ||
const { deprecate } = require('util'); | ||
const { createSocket } = require('dgram'); | ||
var min = require('osc-min'); | ||
const { toBuffer } = require('osc-min'); | ||
var Message = require('./Message'); | ||
const Message = require('./Message'); | ||
var Client = function (host, port) { | ||
class Client { | ||
constructor(host, port) { | ||
this.host = host; | ||
this.port = port; | ||
this._sock = dgram.createSocket({ | ||
this._sock = createSocket({ | ||
type: 'udp4', | ||
reuseAddr: true | ||
}); | ||
this.kill = function() { | ||
this._sock.close(); | ||
}; | ||
}; | ||
this.kill = deprecate( | ||
this.close, | ||
'Client.kill() and Server.kill() are deprecated and will be removed in the next major version.\n' | ||
+ 'Use Server.close() and Client.close().', | ||
'DEP0001' | ||
); | ||
} | ||
close(cb) { | ||
this._sock.close(cb); | ||
} | ||
send(...args) { | ||
let message = args[0]; | ||
let callback = () => {}; | ||
if (typeof args[args.length - 1] === 'function') { | ||
callback = args.pop(); | ||
} | ||
Client.prototype = { | ||
send: function (message) { | ||
var mes; | ||
var buf; | ||
var callback; | ||
var args = Array.prototype.slice.call(arguments); | ||
var last = args[args.length - 1]; | ||
if (typeof last === 'function') { | ||
callback = args.pop(); | ||
if (message instanceof Array) { | ||
message = { | ||
address: message[0], | ||
args: message.splice(1) | ||
}; | ||
} | ||
let mes; | ||
let buf; | ||
switch (typeof message) { | ||
case 'object': | ||
buf = toBuffer(message); | ||
this._sock.send(buf, 0, buf.length, this.port, this.host, callback); | ||
break; | ||
case 'string': | ||
mes = new Message(args[0]); | ||
for (let i = 1; i < args.length; i++) { | ||
mes.append(args[i]); | ||
} | ||
else { | ||
callback = function () {}; | ||
} | ||
if (message instanceof Array) { | ||
message = { | ||
address: message[0], | ||
args: message.splice(1) | ||
} | ||
} | ||
switch (typeof message) { | ||
case 'object': | ||
buf = min.toBuffer(message); | ||
this._sock.send(buf, 0, buf.length, this.port, this.host, callback); | ||
break; | ||
case 'string': | ||
mes = new Message(args[0]); | ||
for (var i = 1; i < args.length; i++) { | ||
mes.append(args[i]); | ||
} | ||
buf = min.toBuffer(mes); | ||
this._sock.send(buf, 0, buf.length, this.port, this.host, callback); | ||
break; | ||
default: | ||
throw new Error('That Message Just Doesn\'t Seem Right'); | ||
} | ||
buf = toBuffer(mes); | ||
this._sock.send(buf, 0, buf.length, this.port, this.host, callback); | ||
break; | ||
default: | ||
throw new Error('That Message Just Doesn\'t Seem Right'); | ||
} | ||
}; | ||
} | ||
} | ||
module.exports = Client; |
'use strict'; | ||
var types = require('./types'); | ||
const { deprecate } = require('util'); | ||
var TInt = types.TInt; | ||
var TFloat = types.TFloat; | ||
var TString = types.TString; | ||
var TBlob = types.TBlob; | ||
var TDouble = types.TDouble; | ||
var TTime = types.TTime; | ||
var TTrue = types.TTrue; | ||
var TFalse = types.TFalse; | ||
const { | ||
TInt, | ||
TFloat, | ||
TString, | ||
TBlob, | ||
TDouble, | ||
TTime, | ||
TTrue, | ||
TFalse | ||
} = require('./types'); | ||
// for each OSC type tag we use a specific constructor function to decode its respective data | ||
var tagToConstructor = { 'i': function () { return new TInt(); }, | ||
'f': function () { return new TFloat(); }, | ||
's': function () { return new TString(); }, | ||
'b': function () { return new TBlob(); }, | ||
'd': function () { return new TDouble(); }, | ||
'T': function () { return new TTrue(); }, | ||
'F': function () { return new TFalse(); } }; | ||
const tagToConstructor = { | ||
i: TInt, | ||
f: TFloat, | ||
s: TString, | ||
b: TBlob, | ||
d: TDouble, | ||
T: TTrue, | ||
F: TFalse | ||
}; | ||
function decode (data) { | ||
/* istanbul ignore next */ | ||
function decodeBundle(data, message) { | ||
var time = new TTime(); | ||
data = time.decode(data); | ||
message.push('#bundle'); | ||
message.push(time.value); | ||
var length, part; | ||
while(data.length > 0) { | ||
length = new TInt(); | ||
data = length.decode(data); | ||
part = data.slice(0, length.value); | ||
//message = message.concat(decode(part)); | ||
message.push(decode(part)); | ||
data = data.slice(length.value, data.length); | ||
} | ||
return message; | ||
} | ||
const deprecatedDecodeBundle = deprecate( | ||
decodeBundle, | ||
'Decoding TUIO is planned to be deprecated. Please open an issue if you rely on this feature.', | ||
'DEP0002' | ||
); | ||
function decode(data) { | ||
// this stores the decoded data as an array | ||
var message = []; | ||
const message = []; | ||
// we start getting the <address> and <rest> of OSC msg /<address>\0<rest>\0<typetags>\0<data> | ||
var address = new TString(); | ||
const address = new TString(); | ||
data = address.decode(data); | ||
if (data.length <= 0) { | ||
return message; | ||
} | ||
// Checking if we received a bundle (typical for TUIO/OSC) | ||
/* istanbul ignore if */ | ||
if (address.value === '#bundle') { | ||
var time = new TTime(); | ||
data = time.decode(data); | ||
return deprecatedDecodeBundle(data, message); | ||
} | ||
message.push('#bundle'); | ||
message.push(time.value); | ||
message.push(address.value); | ||
var length, part; | ||
while(data.length > 0) { | ||
length = new TInt(); | ||
data = length.decode(data); | ||
// if we have rest, maybe we have some typetags... let see... | ||
part = data.slice(0, length.value); | ||
//message = message.concat(decode(part)); | ||
message.push(decode(part)); | ||
data = data.slice(length.value, data.length); | ||
// now we advance on the old rest, getting <typetags> | ||
var typetags = new TString(); | ||
data = typetags.decode(data); | ||
typetags = typetags.value; | ||
// so we start building our message list | ||
if (typetags[0] !== ',') { | ||
throw new Error('invalid type tag in incoming OSC message, must start with comma'); | ||
} | ||
for (var i = 1; i < typetags.length; i++) { | ||
var constructor = tagToConstructor[typetags[i]]; | ||
if (!constructor) { | ||
throw new Error('Unsupported OSC type tag ' + typetags[i] + ' in incoming message'); | ||
} | ||
} else if (data.length > 0) { | ||
message.push(address.value); | ||
// if we have rest, maybe we have some typetags... let see... | ||
// now we advance on the old rest, getting <typetags> | ||
var typetags = new TString(); | ||
data = typetags.decode(data); | ||
typetags = typetags.value; | ||
// so we start building our message list | ||
if (typetags[0] !== ',') { | ||
throw new Error('invalid type tag in incoming OSC message, must start with comma'); | ||
} | ||
for (var i = 1; i < typetags.length; i++) { | ||
var constructor = tagToConstructor[typetags[i]]; | ||
if (!constructor) { | ||
throw new Error('Unsupported OSC type tag ' + typetags[i] + ' in incoming message'); | ||
} | ||
var argument = constructor(); | ||
data = argument.decode(data); | ||
message.push(argument.value); | ||
} | ||
var argument = new constructor(); | ||
data = argument.decode(data); | ||
message.push(argument.value); | ||
} | ||
@@ -74,0 +93,0 @@ |
'use strict'; | ||
const Message = require('./Message'); | ||
const Client = require('./Client'); | ||
const Server = require('./Server'); | ||
module.exports = { | ||
Message: require('./Message'), | ||
Client: require('./Client'), | ||
Server: require('./Server') | ||
Message, | ||
Client, | ||
Server | ||
}; |
'use strict'; | ||
function Message(address) { | ||
this.oscType = 'message'; | ||
this.address = address; | ||
this.args = []; | ||
for (var i = 1; i < arguments.length; i++) { | ||
this.append(arguments[i]); | ||
} | ||
} | ||
function Argument(type, value){ | ||
class Argument { | ||
constructor(type, value) { | ||
this.type = type; | ||
this.value = value; | ||
} | ||
} | ||
Message.prototype = { | ||
append: function (arg) { | ||
var argOut; | ||
switch (typeof arg) { | ||
case 'object': | ||
if (arg instanceof Array) { | ||
for (var i = 0; i < arg.length; i++) { | ||
this.append(arg[i]); | ||
} | ||
} else if (arg.type) { | ||
this.args.push(arg); | ||
} else { | ||
throw new Error('don\'t know how to encode object ' + arg); | ||
} | ||
break; | ||
case 'number': | ||
if (Math.floor(arg) === arg) { | ||
argOut = new Argument('integer', arg); | ||
this.args.push(argOut); | ||
} else { | ||
argOut = new Argument('float', arg); | ||
this.args.push(argOut); | ||
} | ||
break; | ||
case 'string': | ||
argOut = new Argument('string', arg); | ||
this.args.push(argOut); | ||
break; | ||
default: | ||
throw new Error('don\'t know how to encode ' + arg); | ||
class Message { | ||
constructor(address, ...args) { | ||
this.oscType = 'message'; | ||
this.address = address; | ||
this.args = args; | ||
} | ||
append(arg) { | ||
var argOut; | ||
switch (typeof arg) { | ||
case 'object': | ||
if (arg instanceof Array) { | ||
for (var i = 0; i < arg.length; i++) { | ||
this.append(arg[i]); | ||
} | ||
} else if (arg.type) { | ||
this.args.push(arg); | ||
} else { | ||
throw new Error('don\'t know how to encode object ' + arg); | ||
} | ||
break; | ||
case 'number': | ||
if (Math.floor(arg) === arg) { | ||
argOut = new Argument('integer', arg); | ||
this.args.push(argOut); | ||
} else { | ||
argOut = new Argument('float', arg); | ||
this.args.push(argOut); | ||
} | ||
break; | ||
case 'string': | ||
argOut = new Argument('string', arg); | ||
this.args.push(argOut); | ||
break; | ||
case 'boolean': | ||
argOut = new Argument('boolean', arg); | ||
this.args.push(argOut); | ||
break; | ||
default: | ||
throw new Error('don\'t know how to encode ' + arg); | ||
} | ||
}; | ||
} | ||
} | ||
module.exports = Message; |
@@ -0,15 +1,17 @@ | ||
/* eslint-disable no-console */ | ||
'use strict'; | ||
var dgram = require('dgram'); | ||
var util = require('util'); | ||
var events = require('events'); | ||
const { deprecate } = require('util'); | ||
const { createSocket } = require('dgram'); | ||
const { EventEmitter } = require('events'); | ||
var decode = require('./decode'); | ||
const decode = require('./decode'); | ||
var Server = function(port, host) { | ||
var server; | ||
events.EventEmitter.call(this); | ||
class Server extends EventEmitter { | ||
constructor(port, host) { | ||
super(); | ||
let decoded; | ||
this.port = port; | ||
this.host = host; | ||
this._sock = dgram.createSocket({ | ||
this._sock = createSocket({ | ||
type: 'udp4', | ||
@@ -19,24 +21,29 @@ reuseAddr: true | ||
this._sock.bind(port); | ||
server = this; | ||
this._sock.on('message', function (msg, rinfo) { | ||
try { | ||
var decoded = decode(msg); | ||
// [<address>, <typetags>, <values>*] | ||
} | ||
catch (e) { | ||
console.log('can\'t decode incoming message: ' + e.message); | ||
} | ||
this._sock.on('message', (msg, rinfo) => { | ||
try { | ||
decoded = decode(msg); | ||
// [<address>, <typetags>, <values>*] | ||
} | ||
catch (e) { | ||
const error = new Error(`can't decode incoming message: ${e.message}`); | ||
this.emit('error', error, rinfo); | ||
} | ||
if (decoded) { | ||
server.emit('message', decoded, rinfo); | ||
server.emit(decoded[0], decoded, rinfo); | ||
} | ||
if (decoded) { | ||
this.emit('message', decoded, rinfo); | ||
this.emit(decoded[0], decoded, rinfo); | ||
} | ||
}); | ||
this.kill = function() { | ||
this._sock.close(); | ||
}; | ||
}; | ||
this.kill = deprecate( | ||
this.close, | ||
'Client.kill() and Server.kill() are deprecated and will be removed in the next major version.\n' | ||
+ 'Use Server.close() and Client.close().', | ||
'DEP0001' | ||
); | ||
} | ||
close(cb) { | ||
this._sock.close(cb); | ||
} | ||
} | ||
util.inherits(Server, events.EventEmitter); | ||
module.exports = Server; |
246
lib/types.js
'use strict'; | ||
var jspack = require('jspack').jspack; | ||
const jspack = require('jspack').jspack; | ||
var pack = jspack.packTo; | ||
function ShortBuffer(type, buf, requiredLength) | ||
{ | ||
class ShortBuffer { | ||
constructor(type, buf, requiredLength) { | ||
this.type = 'ShortBuffer'; | ||
var message = 'buffer ['; | ||
for (var i = 0; i < buf.length; i++) { | ||
if (i) { | ||
message += ', '; | ||
} | ||
message += buf.charCodeAt(i); | ||
let message = 'buffer ['; | ||
for (let i = 0; i < buf.length; i++) { | ||
if (i) { | ||
message += ', '; | ||
} | ||
message += buf.charCodeAt(i); | ||
} | ||
message += '] too short for ' + type + ', ' + requiredLength + ' bytes required'; | ||
message += `] too short for ${type}, ${requiredLength} bytes requiredLength`; | ||
this.message = message; | ||
} | ||
} | ||
function TString (value) { this.value = value; } | ||
class TString { | ||
constructor(value) { | ||
this.value = value; | ||
this.typetag = 's'; | ||
} | ||
decode(data) { | ||
let end = 0; | ||
while (data[end] && end < data.length) { | ||
end++; | ||
} | ||
if (end === data.length) { | ||
throw Error('OSC string not null terminated'); | ||
} | ||
this.value = data.toString('ascii', 0, end); | ||
const nextData = parseInt(Math.ceil((end + 1) / 4.0) * 4); | ||
return data.slice(nextData); | ||
} | ||
} | ||
TString.prototype = { | ||
typetag: 's', | ||
decode: function (data) { | ||
var end = 0; | ||
while (data[end] && end < data.length) { | ||
end++; | ||
} | ||
if (end === data.length) { | ||
throw Error('OSC string not null terminated'); | ||
} | ||
this.value = data.toString('ascii', 0, end); | ||
var nextData = parseInt(Math.ceil((end + 1) / 4.0) * 4); | ||
return data.slice(nextData); | ||
}, | ||
encode: function (buf, pos) { | ||
var len = Math.ceil((this.value.length + 1) / 4.0) * 4; | ||
return pack('>' + len + 's', buf, pos, [ this.value ]); | ||
class TInt { | ||
constructor(value) { | ||
this.value = value; | ||
this.typetag = 'i'; | ||
} | ||
decode(data) { | ||
if (data.length < 4) { | ||
throw new ShortBuffer('int', data, 4); | ||
} | ||
}; | ||
this.value = jspack.Unpack('>i', data.slice(0, 4))[0]; | ||
return data.slice(4); | ||
} | ||
} | ||
exports.TString = TString; | ||
class TFloat { | ||
constructor(value) { | ||
this.value = value; | ||
this.typetag = 'f'; | ||
} | ||
decode(data) { | ||
if (data.length < 4) { | ||
throw new ShortBuffer('float', data, 4); | ||
} | ||
function TInt (value) { this.value = value; } | ||
this.value = jspack.Unpack('>f', data.slice(0, 4))[0]; | ||
return data.slice(4); | ||
} | ||
} | ||
TInt.prototype = { | ||
typetag: 'i', | ||
decode: function (data) { | ||
if (data.length < 4) { | ||
throw new ShortBuffer('int', data, 4); | ||
} | ||
this.value = jspack.Unpack('>i', data.slice(0, 4))[0]; | ||
return data.slice(4); | ||
}, | ||
encode: function (buf, pos) { | ||
return pack('>i', buf, pos, [ this.value ]); | ||
class TDouble { | ||
constructor(value) { | ||
this.value = value; | ||
this.typetag = 'd'; | ||
} | ||
decode(data) { | ||
if (data.length < 8) { | ||
throw new ShortBuffer('double', data, 8); | ||
} | ||
}; | ||
this.value = jspack.Unpack('>d', data.slice(0, 8))[0]; | ||
return data.slice(8); | ||
} | ||
} | ||
exports.TInt = TInt; | ||
class TTrue { | ||
constructor(value) { | ||
this.value = value; | ||
this.typetag = 'T'; | ||
} | ||
decode(data) { | ||
this.value = true; | ||
return data; | ||
} | ||
} | ||
class TFalse { | ||
constructor(value) { | ||
this.value = value; | ||
this.typetag = 'F'; | ||
} | ||
decode(data) { | ||
this.value = false; | ||
return data; | ||
} | ||
} | ||
class TBlob { | ||
constructor(value) { | ||
this.value = value; | ||
this.typetag = 'b'; | ||
} | ||
decode(data) { | ||
const length = jspack.Unpack('>i', data.slice(0, 4))[0]; | ||
const nextData = parseInt(Math.ceil((length) / 4.0) * 4) + 4; | ||
this.value = data.slice(4, length + 4); | ||
return data.slice(nextData); | ||
} | ||
} | ||
function TTime (value) { this.value = value; } | ||
TTime.prototype = { | ||
@@ -72,93 +124,19 @@ typetag: 't', | ||
} | ||
var raw = jspack.Unpack('>LL', data.slice(0, 8)); | ||
var secs = raw[0]; | ||
var fracs = raw[1]; | ||
const raw = jspack.Unpack('>LL', data.slice(0, 8)); | ||
const secs = raw[0]; | ||
const fracs = raw[1]; | ||
this.value = secs + fracs / 4294967296; | ||
return data.slice(8); | ||
}, | ||
encode: function (buf, pos) { | ||
return pack('>LL', buf, pos, this.value); | ||
} | ||
}; | ||
exports.TTime = TTime; | ||
function TFloat (value) { this.value = value; } | ||
TFloat.prototype = { | ||
typetag: 'f', | ||
decode: function (data) { | ||
if (data.length < 4) { | ||
throw new ShortBuffer('float', data, 4); | ||
} | ||
this.value = jspack.Unpack('>f', data.slice(0, 4))[0]; | ||
return data.slice(4); | ||
}, | ||
encode: function (buf, pos) { | ||
return pack('>f', buf, pos, [ this.value ]); | ||
} | ||
module.exports = { | ||
TString, | ||
TInt, | ||
TTime, | ||
TFloat, | ||
TBlob, | ||
TDouble, | ||
TTrue, | ||
TFalse | ||
}; | ||
exports.TFloat = TFloat; | ||
function TBlob (value) { this.value = value; } | ||
TBlob.prototype = { | ||
typetag: 'b', | ||
decode: function (data) { | ||
var length = jspack.Unpack('>i', data.slice(0, 4))[0]; | ||
var nextData = parseInt(Math.ceil((length) / 4.0) * 4) + 4; | ||
this.value = data.slice(4, length + 4); | ||
return data.slice(nextData); | ||
}, | ||
encode: function (buf, pos) { | ||
var len = Math.ceil((this.value.length) / 4.0) * 4; | ||
return pack('>i' + len + 's', buf, pos, [len, this.value]); | ||
} | ||
}; | ||
exports.TBlob = TBlob; | ||
function TDouble (value) { this.value = value; } | ||
TDouble.prototype = { | ||
typetag: 'd', | ||
decode: function (data) { | ||
if (data.length < 8) { | ||
throw new ShortBuffer('double', data, 8); | ||
} | ||
this.value = jspack.Unpack('>d', data.slice(0, 8))[0]; | ||
return data.slice(8); | ||
}, | ||
encode: function (buf, pos) { | ||
return pack('>d', buf, pos, [ this.value ]); | ||
} | ||
}; | ||
exports.TDouble = TDouble; | ||
function TTrue (value) { this.value = value; } | ||
TTrue.prototype = { | ||
typetag: 'T', | ||
decode: function (data) { | ||
this.value = true | ||
return data; | ||
}, | ||
encode: function (buf, pos) { | ||
return pack('>T', buf, pos, [ true ]); | ||
} | ||
}; | ||
exports.TTrue = TTrue; | ||
function TFalse (value) { this.value = value; } | ||
TFalse.prototype = { | ||
typetag: 'F', | ||
decode: function (data) { | ||
this.value = false | ||
return data; | ||
}, | ||
encode: function (buf, pos) { | ||
return pack('>F', buf, pos, [ false ]); | ||
} | ||
}; | ||
exports.TFalse = TFalse; |
{ | ||
"name": "node-osc", | ||
"description": "pyOSC inspired library", | ||
"version": "3.0.1", | ||
"version": "4.0.0", | ||
"main": "lib/index.js", | ||
@@ -11,3 +11,3 @@ "author": { | ||
"engines": { | ||
"node": ">6" | ||
"node": ">8" | ||
}, | ||
@@ -18,2 +18,4 @@ "license": "LGPL-2.1", | ||
"tap": "tap test/*.js", | ||
"coverage": "npm run tap -- --coverage", | ||
"coverage-html": "npm run tap -- --coverage-report=html", | ||
"lint": "eslint **/*.js" | ||
@@ -35,6 +37,2 @@ }, | ||
], | ||
"dependencies": { | ||
"jspack": "0.0.4", | ||
"osc-min": "^1.1.1" | ||
}, | ||
"keywords": [ | ||
@@ -48,6 +46,10 @@ "osc", | ||
}, | ||
"dependencies": { | ||
"jspack": "0.0.4", | ||
"osc-min": "^1.1.1" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^5.9.0", | ||
"eslint": "^5.16.0", | ||
"tap": "^12.6.1" | ||
} | ||
} |
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
48759
18
750
3