This repository has been archived on 2022-07-06. You can view files and clone it, but cannot push or open issues or pull requests.
websocket-webcam/node_modules/jsftp/node_modules/event-stream/node_modules/map-stream/index.js

106 lines
2.5 KiB
JavaScript

//filter will reemit the data if cb(err,pass) pass is truthy
// reduce is more tricky
// maybe we want to group the reductions or emit progress updates occasionally
// the most basic reduce just emits one 'data' event after it has recieved 'end'
var Stream = require('stream').Stream
//create an event stream and apply function to each .write
//emitting each response as data
//unless it's an empty callback
module.exports = function (mapper) {
var stream = new Stream()
, inputs = 0
, outputs = 0
, ended = false
, paused = false
, destroyed = false
stream.writable = true
stream.readable = true
stream.write = function () {
if(ended) throw new Error('map stream is not writable')
inputs ++
var args = [].slice.call(arguments)
, r
, inNext = false
//pipe only allows one argument. so, do not
function next (err) {
if(destroyed) return
inNext = true
outputs ++
var args = [].slice.call(arguments)
if(err) {
args.unshift('error')
return inNext = false, stream.emit.apply(stream, args)
}
args.shift() //drop err
if (args.length) {
args.unshift('data')
r = stream.emit.apply(stream, args)
}
if(inputs == outputs) {
if(paused) paused = false, stream.emit('drain') //written all the incoming events
if(ended) end()
}
inNext = false
}
args.push(next)
try {
//catch sync errors and handle them like async errors
var written = mapper.apply(null, args)
paused = (written === false)
return !paused
} catch (err) {
//if the callback has been called syncronously, and the error
//has occured in an listener, throw it again.
if(inNext)
throw err
next(err)
return !paused
}
}
function end (data) {
//if end was called with args, write it,
ended = true //write will emit 'end' if ended is true
stream.writable = false
if(data !== undefined)
return stream.write(data)
else if (inputs == outputs) //wait for processing
stream.readable = false, stream.emit('end'), stream.destroy()
}
stream.end = function (data) {
if(ended) return
end()
}
stream.destroy = function () {
ended = destroyed = true
stream.writable = stream.readable = paused = false
process.nextTick(function () {
stream.emit('close')
})
}
stream.pause = function () {
paused = true
}
stream.resume = function () {
paused = false
}
return stream
}