nsolid-manager
Version:
A manager that sets up and runs N|Solid for you
101 lines (84 loc) • 2.16 kB
JavaScript
/**
* Wrapper interface for executing N|Solid CLI commands
*/
import split from 'split'
import async from 'async'
import through from 'through'
import Client from 'nsolid-rpcclient'
import createConfig from './config'
const defaultConfig = createConfig(process.argv)
module.exports.broadcast = broadcast
module.exports.createStream = createStream
module.exports.json = json
function json (s) {
try {
return JSON.parse(s.replace(/\\/g, '\\\\'))
} catch (e) {
return { error: e }
}
}
function createStream (cmd, args, hub, config) {
config = config || defaultConfig
const timeout = (args && args.timeout) || config.timeout
const passthrough = through()
try {
const client = new Client(hub)
let s = null
if (args && args.id) {
s = client.routeTo(cmd, args, null, timeout)
} else {
s = client.send(cmd, null, timeout)
}
// if the stream is not piped, provide a noop destination
// so things flow instead of buffering and never ending
let piped = false
s.once('pipe', () => piped = true)
process.nextTick(() => {
if (!piped) {
s.pipe(passthrough)
}
})
return s
} catch (e) {
process.nextTick(() => {
passthrough.emit('error', e)
})
return passthrough
}
}
function broadcast (cmd, config, fn) {
async.map(config.hub, function broadcastToHub (hub, done) {
const s = createStream(cmd, null, hub, config)
const res = []
s.on('error', (e) => {
done(null, {
error: e,
hub: hub
})
})
s.pipe(split()).on('data', function gotLine (line) {
var obj = json((line || '').toString())
if (!obj.error) {
if (obj.meta) {
obj.meta.hub = hub
}
res.push(obj)
}
})
s.on('end', function streamEnded () {
done(null, res)
})
}, function concatAndRespond (e, res) {
if (e) return fn(e)
const valid = []
const errors = []
res.forEach((r) => {
if (r.error) {
errors.push(r)
} else {
Array.prototype.push.apply(valid, r)
}
})
fn(errors.length ? errors : null, valid)
})
}