Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

a module is born

  • Loading branch information...
commit ae4f843014fe12d0d0679a5fe5ffdc02fdef6e76 0 parents
@dannycoates authored
Showing with 147 additions and 0 deletions.
  1. +60 −0 main.js
  2. +20 −0 package.json
  3. +34 −0 readme.md
  4. +33 −0 test.js
60 main.js
@@ -0,0 +1,60 @@
+module.exports = function tap(dest) {
+ var source = this
+ var open = true
+
+ function writeDest(data) {
+ if (dest.writable && open) {
+ open = dest.write(data)
+ }
+ }
+
+ function endDest() {
+ cleanup()
+ dest.end()
+ }
+
+ function maybeThrow(error) {
+ cleanup()
+ if (this.listeners('error').length === 0) {
+ throw error
+ }
+ }
+
+ function openDest() { open = true }
+
+ function destroyDest() {
+ cleanup()
+ dest.destroy()
+ }
+
+ if (!dest._isStdio) {
+ source.on('end', endDest)
+ source.on('close', destroyDest)
+ }
+
+ source.on('data', writeDest)
+ source.on('error', maybeThrow)
+ source.on('end', cleanup)
+ source.on('close', cleanup)
+
+ dest.on('drain', openDest)
+ dest.on('error', cleanup)
+ dest.on('end', cleanup)
+ dest.on('close', cleanup)
+
+ function cleanup() {
+ source.removeListener('data', writeDest)
+ source.removeListener('end', endDest)
+ source.removeListener('close', destroyDest)
+ source.removeListener('end', cleanup)
+ source.removeListener('close', cleanup)
+ source.removeListener('error', maybeThrow)
+
+ dest.removeListener('drain', openDest)
+ dest.removeListener('end', cleanup)
+ dest.removeListener('close', cleanup)
+ dest.removeListener('error', cleanup)
+ }
+
+ return source
+}
20 package.json
@@ -0,0 +1,20 @@
+{
+ "author": "Danny Coates <dannycoates@gmail.com>",
+ "name": "streamtap",
+ "description": "silently tap into a stream",
+ "version": "0.1.0",
+ "homepage": "https://github.com/dannycoates/streamtap",
+ "repository": {
+ "url": "http://github.com/dannycoates/streamtap.git"
+ },
+ "main": "main.js",
+ "scripts": {
+ "test": "node test.js"
+ },
+ "dependencies": {},
+ "devDependencies": {},
+ "optionalDependencies": {},
+ "engines": {
+ "node": ">=0.6.0"
+ }
+}
34 readme.md
@@ -0,0 +1,34 @@
+# streamtap
+
+Tap into a stream. Read-only and drop data instead of applying backpressure
+
+Useful for "monitoring" a stream
+
+## Example
+
+```js
+var fs = require('fs')
+var http = require('http')
+var Stream = require('stream')
+Stream.prototype.tap = require('streamtap')
+
+http.get({
+ host: 'google.com',
+ port: 80,
+ path: '/index.html'
+},
+function (res) {
+ res
+ .tap(process.stdout)
+ .pipe(fs.createWriteStream('index.html'))
+})
+```
+
+## Testing
+
+ $ npm test
+
+
+## License
+
+MIT
33 test.js
@@ -0,0 +1,33 @@
+var Stream = require('stream')
+Stream.prototype.tap = require('./main')
+
+var http = require('http')
+var fs = require('fs')
+
+var index = 'index.html'
+var tapped = 'index.html.tap'
+
+var fin = new Stream()
+fin.destroy = function () {
+ var i = fs.readFileSync(index, 'utf8')
+ var t = fs.readFileSync(tapped, 'utf8')
+ // i and t aren't required to be equal since 'tap' is allowed to drop data,
+ // but if they are we know it worked
+ console.assert(i === t)
+ console.log("it worked!")
+
+ fs.unlinkSync(index)
+ fs.unlinkSync(tapped)
+}
+
+http.get({
+ host: 'google.com',
+ port: 80,
+ path: '/' + index
+},
+function (res) {
+ res
+ .tap(fs.createWriteStream(tapped))
+ .pipe(fs.createWriteStream(index))
+ .pipe(fin)
+})

0 comments on commit ae4f843

Please sign in to comment.
Something went wrong with that request. Please try again.