es.duplex = function (writer, reader) { var thepipe = new Stream() thepipe.__defineGetter__('writable', function () { return writer.writable }) thepipe.__defineGetter__('readable', function () { return reader.readable }) ;['write', 'end', 'close'].forEach(function (func) { thepipe[func] = function () { return writer[func].apply(writer, arguments) } }) ;['resume', 'pause'].forEach(function (func) { thepipe[func] = function () { thepipe.emit(func) if(reader[func]) return reader[func].apply(reader, arguments) else reader.emit(func) } }) ;['data', 'close'].forEach(function (event) { reader.on(event, function () { var args = [].slice.call(arguments) args.unshift(event) thepipe.emit.apply(thepipe, args) }) }) //only emit end once var ended = false reader.on('end', function () { if(ended) return ended = true var args = [].slice.call(arguments) args.unshift('end') thepipe.emit.apply(thepipe, args) }) return thepipe }