├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.js ├── package.json └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | sandbox.js 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | - "8" 5 | - "10" 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Mathias Buus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cross-pipe 2 | 3 | Create two streams that are cross piped. 4 | 5 | ``` 6 | npm install cross-pipe 7 | ``` 8 | 9 | Useful if you have an API that accepts a stream 10 | but want to return a stream that represents that pipeline as well 11 | 12 | ## Usage 13 | 14 | ```js 15 | const crossPipe = require('cross-pipe') 16 | 17 | const [ a, b ] = crossPipe() 18 | 19 | a.write('hi') 20 | 21 | b.on('data', function (data) { 22 | console.log('b: ' + data) // prints hi 23 | b.write('hey') 24 | a.on('data', function (data) { 25 | console.log('a: ' + data) // prints hey 26 | }) 27 | }) 28 | ``` 29 | 30 | If you are using something like [noise-peer](https://github.com/emilbayes/noise-peer) that accepts the underlying socket in the constructor but you want to return a generic stream in a pipeline you do it with a cross pipe like so 31 | 32 | ```js 33 | function replicate () { 34 | const [ a, b ] = crossPipe() 35 | 36 | const stream = noise(b) 37 | 38 | // do stuff with stream 39 | 40 | // a reprensents the pipeline now 41 | return a 42 | } 43 | ``` 44 | 45 | ## License 46 | 47 | MIT 48 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const duplexify = require('duplexify') 2 | const stream = require('readable-stream') 3 | 4 | module.exports = createCrossPiper(false) 5 | module.exports.obj = createCrossPiper(true) 6 | 7 | function createCrossPiper (objectMode) { 8 | const make = objectMode ? duplexify.obj : duplexify 9 | 10 | return createCrossPipe 11 | 12 | function createCrossPipe () { 13 | const inc = new stream.PassThrough({ objectMode }) 14 | const out = new stream.PassThrough({ objectMode }) 15 | return [ 16 | make(inc, out), 17 | make(out, inc) 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cross-pipe", 3 | "version": "1.0.0", 4 | "description": "Create two streams that are cross piped", 5 | "main": "index.js", 6 | "dependencies": { 7 | "duplexify": "^3.6.0", 8 | "readable-stream": "^3.0.6" 9 | }, 10 | "devDependencies": { 11 | "standard": "^12.0.1", 12 | "tape": "^4.9.1" 13 | }, 14 | "scripts": { 15 | "test": "standard && tape test.js" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/mafintosh/cross-pipe.git" 20 | }, 21 | "author": "Mathias Buus (@mafintosh)", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/mafintosh/cross-pipe/issues" 25 | }, 26 | "homepage": "https://github.com/mafintosh/cross-pipe" 27 | } 28 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | const tape = require('tape') 2 | const xp = require('./') 3 | 4 | tape('basic', function (t) { 5 | const [ a, b ] = xp() 6 | 7 | b.once('readable', function () { 8 | t.same(b.read(), Buffer.from('hi')) 9 | b.write('ho') 10 | a.once('readable', function () { 11 | t.same(a.read(), Buffer.from('ho')) 12 | t.end() 13 | }) 14 | }) 15 | 16 | a.write('hi') 17 | }) 18 | 19 | tape('basic obj', function (t) { 20 | const [ a, b ] = xp.obj() 21 | 22 | b.once('readable', function () { 23 | t.same(b.read(), { hi: true }) 24 | b.write({ ho: true }) 25 | a.once('readable', function () { 26 | t.same(a.read(), { ho: true }) 27 | t.end() 28 | }) 29 | }) 30 | 31 | a.write({ hi: true }) 32 | }) 33 | --------------------------------------------------------------------------------