var Stream = require("stream") , writeMethods = ["write", "end", "destroy"] , readMethods = ["resume", "pause"] , readEvents = ["data", "close"] , slice = Array.prototype.slice module.exports = duplex function duplex(writer, reader) { var stream = new Stream() , ended = false Object.defineProperties(stream, { writable: { get: getWritable } , readable: { get: getReadable } }) writeMethods.forEach(proxyWriter) readMethods.forEach(proxyReader) readEvents.forEach(proxyStream) reader.on("end", handleEnd) writer.on("error", reemit) reader.on("error", reemit) return stream function getWritable() { return writer.writable } function getReadable() { return reader.readable } function proxyWriter(methodName) { stream[methodName] = method function method() { return writer[methodName].apply(writer, arguments) } } function proxyReader(methodName) { stream[methodName] = method function method() { stream.emit(methodName) var func = reader[methodName] if (func) { return func.apply(reader, arguments) } reader.emit(methodName) } } function proxyStream(methodName) { reader.on(methodName, reemit) function reemit() { var args = slice.call(arguments) args.unshift(methodName) stream.emit.apply(stream, args) } } function handleEnd() { if (ended) { return } ended = true var args = slice.call(arguments) args.unshift("end") stream.emit.apply(stream, args) } function reemit(err) { stream.emit("error", err) } }