├── .gitignore
├── demo-worker.js
├── demo.html
├── demo.js
├── index.js
├── one-filler.js
├── package.json
├── parent.js
├── readme.md
└── test
├── ps-loopback-worker.js
└── ps.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/demo-worker.js:
--------------------------------------------------------------------------------
1 | var oneFiller = require('./one-filler')
2 |
3 | self.onmessage = function(event) {
4 | var ab = event.data
5 | ab = oneFiller(ab)
6 | self.postMessage(ab, [ab])
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | DOMNode WebWorker
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/demo.js:
--------------------------------------------------------------------------------
1 | var workerstream = require('./index')
2 |
3 | var worker = workerstream('demo-worker.js')
4 |
5 | worker.on('data', function(data) {
6 | console.log(new Uint8Array(data))
7 | })
8 |
9 | var ab = new ArrayBuffer( 10 )
10 | worker.write( ab )
11 | worker.end()
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var stream = require('stream')
2 | var inherits = require('inherits');
3 |
4 | function WorkerStream(path) {
5 | stream.Stream.call(this)
6 | this.readable = true
7 | this.writable = true
8 | this.worker = typeof path === 'string'
9 | ? new Worker(path)
10 | : path
11 | this.worker.onmessage = this.workerMessage.bind(this)
12 | this.worker.onerror = this.workerError.bind(this)
13 | }
14 |
15 | inherits(WorkerStream, stream.Stream)
16 |
17 | module.exports = function(path) {
18 | return new WorkerStream(path)
19 | }
20 |
21 | module.exports.WorkerStream = WorkerStream
22 |
23 | WorkerStream.prototype.workerMessage = function(e) {
24 | this.emit('data', e.data, e)
25 | }
26 |
27 | WorkerStream.prototype.workerError = function(err) {
28 | this.emit('error', err)
29 | }
30 |
31 | // opts is for transferable objects
32 | WorkerStream.prototype.write = function(data, opts) {
33 | this.worker.postMessage(data, opts)
34 | return true
35 | }
36 |
37 | WorkerStream.prototype.end = function() {
38 | this.emit('end')
39 | }
40 |
--------------------------------------------------------------------------------
/one-filler.js:
--------------------------------------------------------------------------------
1 | // fills an arraybuffer with 1's
2 | module.exports = function(ab) {
3 | var buf = new Uint8Array(ab.byteLength)
4 | for (var n = 0; n < buf.length; n++) buf[n] = 1
5 | return buf.buffer
6 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "workerstream",
3 | "version": "1.2.1",
4 | "description": "use HTML5 web workers with the node stream API",
5 | "scripts": {
6 | "start": "beefy demo.js:demo-bundle.js demo-worker.js",
7 | "test": "beefy test/ps.js"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git://github.com/maxogden/workerstream.git"
12 | },
13 | "author": "max ogden",
14 | "license": "BSD",
15 | "readmeFilename": "readme.md",
16 | "gitHead": "4a95a44ec08edaa96cc458630193afbe6408944d",
17 | "devDependencies": {
18 | "tape": "~2.3.2",
19 | "webworkify": "~0.1.0"
20 | },
21 | "dependencies": {
22 | "inherits": "^2.0.1"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/parent.js:
--------------------------------------------------------------------------------
1 | var stream = require('stream')
2 | var inherits = require('inherits');
3 |
4 | function ParentStream(workerGlobal){
5 | stream.Stream.call(this)
6 | this.readable = true
7 | this.writable = true
8 | this.parent = workerGlobal || self
9 | this.parent.onmessage = this.parentMessage.bind(this)
10 | this.parent.onerror = this.parentError.bind(this)
11 | }
12 |
13 | inherits(ParentStream, stream.Stream)
14 |
15 | module.exports = function(workerGlobal) {
16 | return new ParentStream(workerGlobal)
17 | }
18 |
19 | module.exports.ParentStream = ParentStream
20 |
21 | ParentStream.prototype.parentMessage = function(e) {
22 | this.emit('data', e.data, e)
23 | }
24 |
25 | ParentStream.prototype.parentError = function(err) {
26 | this.emit('error', err)
27 | }
28 |
29 | // opts is for transferable objects
30 | ParentStream.prototype.write = function(data, opts) {
31 | this.parent.postMessage(data, opts)
32 | return true
33 | }
34 |
35 | ParentStream.prototype.end = function() {
36 | this.emit('end')
37 | }
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # workerstream
2 |
3 | npm install workerstream
4 |
5 | use HTML5 [web workers](https://developer.mozilla.org/En/Using_web_workers) with the node streams API
6 |
7 | var workerstream = require('workerstream')
8 | var worker = workerstream('my-worker.js')
9 |
10 | `worker` is a stream and speaks stream events: `data`, `error` and `end`. that means you can pipe worker output to anything that accepts streams, such as an XHR. you can also pipe data into workers (such as a webcam feed or audio data)
11 |
12 | ## example
13 |
14 | in your app:
15 |
16 | ```js
17 | var worker = workerstream('worker.js')
18 | worker.on('data', function(data) {
19 | console.log(data)
20 | })
21 | worker.on('error', function(e) { console.log('err', e)})
22 | worker.write({ hello: 'world' })
23 | ```
24 |
25 | the worker code (`worker.js` above):
26 |
27 | ```
28 | self.onmessage = function(event) {
29 | self.postMessage({whats: 'up'})
30 | }
31 | ```
32 |
33 | you can also pass in existing webworker instances
34 |
35 |
36 | ## using with webworkify
37 |
38 | [webworkify](https://npmjs.org/package/webworkify) allows you to simply create browserified webworkers.
39 |
40 | ```js
41 | var WebWorkify = require('webworkify')
42 | var WorkerStream = require('workerstream')
43 |
44 | var worker = WebWorkify(require('./worker.js'))
45 | var workerStream = WorkerStream(worker)
46 | ```
47 |
48 | Your `worker.js` can use this module's `ParentStream` to create a stream connecting back to the parent
49 |
50 | ```js
51 | var ParentStream = require('workerstream/parent')
52 |
53 | module.exports = function(){
54 | var parentStream = ParentStream()
55 | parentStream.pipe(somewhereAwesome).pipe(parentStream)
56 | }
57 | ```
58 |
59 | ## transferable objects
60 |
61 | ```js
62 | worker.write(arraybuffer, [arraybuffer])
63 | ```
64 |
65 | MIT LICENSE
66 |
--------------------------------------------------------------------------------
/test/ps-loopback-worker.js:
--------------------------------------------------------------------------------
1 | var ParentStream = require('../parent.js')
2 |
3 | module.exports = function(){
4 | var parentStream = ParentStream()
5 | // just loopback data
6 | parentStream.pipe(parentStream)
7 | }
--------------------------------------------------------------------------------
/test/ps.js:
--------------------------------------------------------------------------------
1 | var WebWorkify = require('webworkify')
2 | var WorkerStream = require('../index.js')
3 | var test = require('tape')
4 |
5 | test('Data can be transfered bidirectionally with ParentStream',function(t){
6 | t.plan(1)
7 |
8 | var worker = WebWorkify(require('./ps-loopback-worker.js'))
9 | var workerStream = WorkerStream(worker)
10 |
11 | var testSlug = 'this is a test slug'
12 |
13 | workerStream.on('data', function(data) {
14 | t.equal(testSlug,data)
15 | t.end()
16 | })
17 |
18 | workerStream.write( testSlug )
19 | workerStream.end()
20 |
21 | })
--------------------------------------------------------------------------------