New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

webworker-threads

Package Overview
Dependencies
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

webworker-threads - npm Package Compare versions

Comparing version 0.4.0 to 0.4.1

src/jslib.cc

8

CHANGES.md

@@ -0,1 +1,9 @@

## 0.4.1
### Global Worker API
* Add `importScripts` for loading on-disk files.
* Add `console.log` and `console.error` from thread.js.
## 0.4.0

@@ -2,0 +10,0 @@

6

package.json
{
"name": "webworker-threads",
"version": "0.4.0",
"version": "0.4.1",
"main": "build/Release/WebWorkerThreads.node",
"description": "Lightweight Web Worker API implementation with POSIX threads",
"description": "Lightweight Web Worker API implementation with native threads",
"keywords": [

@@ -36,3 +36,3 @@ "threads",

"scripts": {
"js": "env PATH=./node_modules/.bin:\"$PATH\" lsc -cj package.ls;\ngcc deps/minifier/src/minify.c -o deps/minifier/bin/minify;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/load.ls > src/load.js;\n./deps/minifier/bin/minify kLoad_js < src/load.js > src/load.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/worker.ls > src/worker.js;\n./deps/minifier/bin/minify kWorker_js < src/worker.js > src/worker.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/events.ls > src/events.js;\n./deps/minifier/bin/minify kEvents_js < src/events.js > src/events.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/thread_nextTick.ls > src/thread_nextTick.js;\n./deps/minifier/bin/minify kThread_nextTick_js 1 < src/thread_nextTick.js > src/thread_nextTick.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/createPool.ls > src/createPool.js;\n./deps/minifier/bin/minify kCreatePool_js < src/createPool.js > src/createPool.js.c;"
"js": "env PATH=./node_modules/.bin:\"$PATH\" lsc -cj package.ls;\ngcc deps/minifier/src/minify.c -o deps/minifier/bin/minify;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/worker.ls > src/worker.js;\n./deps/minifier/bin/minify kWorker_js < src/worker.js > src/worker.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/events.ls > src/events.js;\n./deps/minifier/bin/minify kEvents_js < src/events.js > src/events.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/createPool.ls > src/createPool.js;\n./deps/minifier/bin/minify kCreatePool_js < src/createPool.js > src/createPool.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/thread_nextTick.ls > src/thread_nextTick.js;\n./deps/minifier/bin/minify kThread_nextTick_js 1 < src/thread_nextTick.js > src/thread_nextTick.js.c;\nenv PATH=./node_modules/.bin:\"$PATH\" lsc -cbp src/load.ls > src/load.js;\n./deps/minifier/bin/minify kLoad_js 1 1 < src/load.js > src/load.js.c;"
},

@@ -39,0 +39,0 @@ "devDependencies": {

@@ -51,7 +51,166 @@ # WebWorker Threads

do spin = ->
process.stdout.write '.'
process.nextTick spin
do spin = -> process.nextTick spin
```
## Introduction
After the initialization phase of a Node program, whose purpose is to setup listeners and callbacks to be executed in response to events, the next phase, the proper execution of the program, is orchestrated by the event loop whose duty is to [juggle events, listeners and callbacks quickly and without any hiccups nor interruptions that would ruin its performance](http://youtube.com/v/D0uA_NOb0PE?autoplay=1)
Both the event loop and said listeners and callbacks run sequentially in a single thread of execution, Node's main thread. If any of them ever blocks, nothing else will happen for the duration of the block: no more events will be handled, no more callbacks nor listeners nor timeouts nor nextTick()ed functions will have the chance to run and do their job, because they won't be called by the blocked event loop, and the program will turn sluggish at best, or appear to be frozen and dead at worst.
### What is WebWorker-Threads
`webworker-threads` provides an asynchronous API for CPU-bound tasks that's missing in Node.js:
``` javascript
var Worker = require('webworker-threads').Worker;
require('http').createServer(function (req,res) {
var fibo = new Worker(function() {
function fibo (n) {
return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
}
self.onmessage = function (event) {
self.postMessage(fibo(event.data));
}
});
fibo.onmessage = function (event) {
res.end('fib(40) = ' + event.data);
};
fibo.postMessage(40);
}).listen(port);
```
And it won't block the event loop because for each request, the `fibo` worker will run in parallel in a separate background thread.
## API
### Module API
``` javascript
var Threads= require('webworker-threads');
```
##### .Worker
`new Threads.Worker( [ file | function ] )` -> Worker object
##### .create()
`Threads.create( /* no arguments */ )` -> thread object
##### .createPool( numThreads )
`Threads.createPool( numberOfThreads )` -> threadPool object
***
### Web Worker API
``` javascript
var worker= new Threads.Worker('worker.js');
var worker= new Threads.Worker(function(){ ... });
var worker= new Threads.Worker();
```
##### .postMessage( data )
`worker.postMessage({ x: 1, y: 2 })` -> sends a data structure into the worker. The worker can reive it using the `onmessage` handler.
##### .onmessage
`worker.onmessage = function (event) { console.log(event.data) };` -> receives data from the worker's `.postMessage` calls.
##### .terminate()
`worker.terminate()` -> terminates the worker thread.
##### .addEventListener( type, cb )
`worker.addEventListener('message', callback)` is equivalent to setting `worker.onmesssage = callback`.
##### .dispatchEvent( event )
Currently unimplemented.
##### .removeEventListener( type )
Currently unimplemented.
##### .thread
Returns the underlying `thread` object; see the next section for details.
Note that this attribute is implementation-specific, and not part of W3C Web Worker API.
***
### Thread API
``` javascript
var thread= Threads.create();
```
##### .id
`thread.id` -> a sequential thread serial number
##### .load( absolutePath [, cb] )
`thread.load( absolutePath [, cb] )` -> reads the file at `absolutePath` and `thread.eval(fileContents, cb)`.
##### .eval( program [, cb])
`thread.eval( program [, cb])` -> converts `program.toString()` and eval()s it in the thread's global context, and (if provided) returns the completion value to `cb(err, completionValue)`.
##### .on( eventType, listener )
`thread.on( eventType, listener )` -> registers the listener `listener(data)` for any events of `eventType` that the thread `thread` may emit.
##### .once( eventType, listener )
`thread.once( eventType, listener )` -> like `thread.on()`, but the listener will only be called once.
##### .removeAllListeners( [eventType] )
`thread.removeAllListeners( [eventType] )` -> deletes all listeners for all eventTypes. If `eventType` is provided, deletes all listeners only for the event type `eventType`.
##### .emit( eventType, eventData [, eventData ... ] )
`thread.emit( eventType, eventData [, eventData ... ] )` -> emit an event of `eventType` with `eventData` inside the thread `thread`. All its arguments are .toString()ed.
##### .destroy( /* no arguments */ )
`thread.destroy( /* no arguments */ )` -> destroys the thread.
***
### Thread pool API
``` javascript
threadPool= Threads.createPool( numberOfThreads );
```
##### .load( absolutePath [, cb] )
`threadPool.load( absolutePath [, cb] )` -> `thread.load( absolutePath [, cb] )` in all the pool's threads.
##### .any.eval( program, cb )
`threadPool.any.eval( program, cb )` -> like `thread.eval()`, but in any of the pool's threads.
##### .any.emit( eventType, eventData [, eventData ... ] )
`threadPool.any.emit( eventType, eventData [, eventData ... ] )` -> like `thread.emit()` but in any of the pool's threads.
##### .all.eval( program, cb )
`threadPool.all.eval( program, cb )` -> like `thread.eval()`, but in all the pool's threads.
##### .all.emit( eventType, eventData [, eventData ... ] )
`threadPool.all.emit( eventType, eventData [, eventData ... ] )` -> like `thread.emit()` but in all the pool's threads.
##### .on( eventType, listener )
`threadPool.on( eventType, listener )` -> like `thread.on()`, registers listeners for events from any of the threads in the pool.
##### .totalThreads()
`threadPool.totalThreads()` -> returns the number of threads in this pool: as supplied in `.createPool( number )`
##### .idleThreads()
`threadPool.idleThreads()` -> returns the number of threads in this pool that are currently idle (sleeping)
##### .pendingJobs()
`threadPool.pendingJobs()` -> returns the number of jobs pending.
##### .destroy( [ rudely ] )
`threadPool.destroy( [ rudely ] )` -> waits until `pendingJobs()` is zero and then destroys the pool. If `rudely` is truthy, then it doesn't wait for `pendingJobs === 0`.
***
### Global Web Worker API
Inside every Worker instance from webworker-threads, there's a global `self` object with these properties:
##### .postMessage( data )
`self.postMessage({ x: 1, y: 2 })` -> sends a data structure back to the main thread.
##### .onmessage
`self.onmessage = function (event) { ... };` -> receives data from the main thread's `.postMessage` calls.
##### .close()
`self.close()` -> stops the current thread.
##### .addEventListener( type, cb )
`self.addEventListener('message', callback)` is equivalent to setting `self.onmesssage = callback`.
##### .dispatchEvent( event )
`self.dispatchEvent({ type: 'message', data: data })` -> same as `self.postMessage(data)`.
##### .removeEventListener( type )
Currently unimplemented.
##### .importScripts( file [, file...] )
Loads one or more files from the disk and `eval` them in the worker instance scope.
##### .thread
Returns the underlying `thread` object; see the next section for details.
Note that this attribute is implementation-specific, and not part of W3C Web Worker API.
***
### Global thread API
Inside every thread .create()d by webworker-threads, there's a global `thread` object with these properties:
##### .id
`thread.id` -> the serial number of this thread
##### .on( eventType, listener )
`thread.on( eventType, listener )` -> just like `thread.on()` above.
##### .once( eventType, listener )
`thread.once( eventType, listener )` -> just like `thread.once()` above.
##### .emit( eventType, eventData [, eventData ... ] )
`thread.emit( eventType, eventData [, eventData ... ] )` -> just like `thread.emit()` above.
##### .removeAllListeners( [eventType] )
`thread.removeAllListeners( [eventType] )` -> just like `thread.removeAllListeners()` above.
##### .nextTick( function )
`thread.nextTick( function )` -> like `process.nextTick()`, but twice as fast.
***
### Global puts
Inside every thread .create()d by webworker-threads, there's a global `puts`:
##### puts(arg1 [, arg2 ...])
`puts(arg1 [, arg2 ...])` -> .toString()s and prints its arguments to stdout.
-----------

@@ -63,8 +222,4 @@ WIP WIP WIP

## (not so) Quick Intro
## Examples
After the initialization phase of a Node program, whose purpose is to setup listeners and callbacks to be executed in response to events, the next phase, the proper execution of the program, is orchestrated by the event loop whose duty is to [juggle events, listeners and callbacks quickly and without any hiccups nor interruptions that would ruin its performance](http://youtube.com/v/D0uA_NOb0PE?autoplay=1)
Both the event loop and said listeners and callbacks run sequentially in a single thread of execution, Node's main thread. If any of them ever blocks, nothing else will happen for the duration of the block: no more events will be handled, no more callbacks nor listeners nor timeouts nor nextTick()ed functions will have the chance to run and do their job, because they won't be called by the blocked event loop, and the program will turn sluggish at best, or appear to be frozen and dead at worst.
**A.-** Here's a program that makes Node's event loop spin freely and as fast as possible: it simply prints a dot to the console in each turn:

@@ -76,3 +231,2 @@

(function spinForever () {
process.stdout.write(".");
process.nextTick(spinForever);

@@ -97,3 +251,2 @@ })();

(function spinForever () {
process.stdout.write(".");
process.nextTick(spinForever);

@@ -122,3 +275,2 @@ })();

(function spinForever () {
process.stdout.write(".");
process.nextTick(spinForever);

@@ -151,3 +303,2 @@ })();

(function spinForever () {
process.stdout.write(".");
process.nextTick(spinForever);

@@ -175,3 +326,2 @@ })();

(function spinForever () {
process.stdout.write(".");
process.nextTick(spinForever);

@@ -212,3 +362,2 @@ })();

(function spinForever () {
process.stdout.write(".");
process.nextTick(spinForever);

@@ -250,3 +399,2 @@ })();

(function spinForever () {
process.stdout.write(".");
process.nextTick(spinForever);

@@ -267,131 +415,2 @@ })();

## API
### Module API
``` javascript
var Threads= require('webworker-threads');
```
##### .Worker
`new Threads.Worker( [ file | function ] )` -> Worker object
##### .create()
`Threads.create( /* no arguments */ )` -> thread object
##### .createPool( numThreads )
`Threads.createPool( numberOfThreads )` -> threadPool object
***
### Web Worker API
``` javascript
var worker= new Threads.Worker('worker.js');
var worker= new Threads.Worker(function(){ ... });
var worker= new Threads.Worker();
```
##### .postMessage( data )
`worker.postMessage({ x: 1, y: 2 })` -> sends a data structure into the worker. The worker can reive it using the `onmessage` handler.
##### .onmessage
`worker.onmessage = function (event) { console.log(event.data) };` -> receives data from the worker's `.postMessage` calls.
##### .terminate()
`worker.terminate()` -> terminates the worker thread.
##### .addEventListener( type, cb )
`worker.addEventListener('message', callback)` is equivalent to setting `worker.onmesssage = callback`.
##### .dispatchEvent( event )
Currently unimplemented.
##### .removeEventListener( type )
Currently unimplemented.
##### .thread
Returns the underlying `thread` object; see the next section for details.
Note that this attribute is implementation-specific, and not part of W3C Web Worker API.
***
### Thread API
``` javascript
var thread= Threads.create();
```
##### .id
`thread.id` -> a sequential thread serial number
##### .load( absolutePath [, cb] )
`thread.load( absolutePath [, cb] )` -> reads the file at `absolutePath` and `thread.eval(fileContents, cb)`.
##### .eval( program [, cb])
`thread.eval( program [, cb])` -> converts `program.toString()` and eval()s it in the thread's global context, and (if provided) returns the completion value to `cb(err, completionValue)`.
##### .on( eventType, listener )
`thread.on( eventType, listener )` -> registers the listener `listener(data)` for any events of `eventType` that the thread `thread` may emit.
##### .once( eventType, listener )
`thread.once( eventType, listener )` -> like `thread.on()`, but the listener will only be called once.
##### .removeAllListeners( [eventType] )
`thread.removeAllListeners( [eventType] )` -> deletes all listeners for all eventTypes. If `eventType` is provided, deletes all listeners only for the event type `eventType`.
##### .emit( eventType, eventData [, eventData ... ] )
`thread.emit( eventType, eventData [, eventData ... ] )` -> emit an event of `eventType` with `eventData` inside the thread `thread`. All its arguments are .toString()ed.
##### .destroy( /* no arguments */ )
`thread.destroy( /* no arguments */ )` -> destroys the thread.
***
### Thread pool API
``` javascript
threadPool= Threads.createPool( numberOfThreads );
```
##### .load( absolutePath [, cb] )
`threadPool.load( absolutePath [, cb] )` -> `thread.load( absolutePath [, cb] )` in all the pool's threads.
##### .any.eval( program, cb )
`threadPool.any.eval( program, cb )` -> like `thread.eval()`, but in any of the pool's threads.
##### .any.emit( eventType, eventData [, eventData ... ] )
`threadPool.any.emit( eventType, eventData [, eventData ... ] )` -> like `thread.emit()` but in any of the pool's threads.
##### .all.eval( program, cb )
`threadPool.all.eval( program, cb )` -> like `thread.eval()`, but in all the pool's threads.
##### .all.emit( eventType, eventData [, eventData ... ] )
`threadPool.all.emit( eventType, eventData [, eventData ... ] )` -> like `thread.emit()` but in all the pool's threads.
##### .on( eventType, listener )
`threadPool.on( eventType, listener )` -> like `thread.on()`, registers listeners for events from any of the threads in the pool.
##### .totalThreads()
`threadPool.totalThreads()` -> returns the number of threads in this pool: as supplied in `.createPool( number )`
##### .idleThreads()
`threadPool.idleThreads()` -> returns the number of threads in this pool that are currently idle (sleeping)
##### .pendingJobs()
`threadPool.pendingJobs()` -> returns the number of jobs pending.
##### .destroy( [ rudely ] )
`threadPool.destroy( [ rudely ] )` -> waits until `pendingJobs()` is zero and then destroys the pool. If `rudely` is truthy, then it doesn't wait for `pendingJobs === 0`.
***
### Global Web Worker API
Inside every Worker instance from webworker-threads, there's a global `self` object with these properties:
##### .postMessage( data )
`self.postMessage({ x: 1, y: 2 })` -> sends a data structure back to the main thread.
##### .onmessage
`self.onmessage = function (event) { ... };` -> receives data from the main thread's `.postMessage` calls.
##### .close()
`self.close()` -> stops the current thread.
##### .addEventListener( type, cb )
`self.addEventListener('message', callback)` is equivalent to setting `self.onmesssage = callback`.
##### .dispatchEvent( event )
`self.dispatchEvent({ type: 'message', data: data })` -> same as `self.postMessage(data)`.
##### .removeEventListener( type )
Currently unimplemented.
##### .thread
Returns the underlying `thread` object; see the next section for details.
Note that this attribute is implementation-specific, and not part of W3C Web Worker API.
***
### Global thread API
Inside every thread .create()d by webworker-threads, there's a global `thread` object with these properties:
##### .id
`thread.id` -> the serial number of this thread
##### .on( eventType, listener )
`thread.on( eventType, listener )` -> just like `thread.on()` above.
##### .once( eventType, listener )
`thread.once( eventType, listener )` -> just like `thread.once()` above.
##### .emit( eventType, eventData [, eventData ... ] )
`thread.emit( eventType, eventData [, eventData ... ] )` -> just like `thread.emit()` above.
##### .removeAllListeners( [eventType] )
`thread.removeAllListeners( [eventType] )` -> just like `thread.removeAllListeners()` above.
##### .nextTick( function )
`thread.nextTick( function )` -> like `process.nextTick()`, but twice as fast.
***
### Global puts
Inside every thread .create()d by webworker-threads, there's a global `puts`:
##### puts(arg1 [, arg2 ...])
`puts(arg1 [, arg2 ...])` -> .toString()s and prints its arguments to stdout.
## Rationale

@@ -430,27 +449,2 @@

### What is Threads A GoGo for Node.js
`webworker-threads` provides the asynchronous API for CPU-bound tasks that's missing in Node.js. Both in continuation passing style (callbacks), and in event emitter style (event listeners).
The same API Node uses to delegate a longish I/O task to a background (libeio) thread:
`asyncIOTask(what, cb);`
`webworker-threads` uses to delegate a longish CPU task to a background (JavaScript) thread:
`thread.eval(program, cb);`
So with `webworker-threads` you can write:
``` javascript
http.createServer(function (req,res) {
thread.eval('fibonacci(40)', function cb (err, data) {
res.end(data);
});
}).listen(port);
```
And it won't block the event loop because the `fibonacci(40)` will run in parallel in a separate background thread.
### Why Threads

@@ -468,3 +462,2 @@

### Why not multiple processes.

@@ -471,0 +464,0 @@

@@ -1,3 +0,14 @@

function load(p, cb){
return this.eval(require('fs').readFileSync(p, 'utf8'), cb);
function addEventListener(event, cb){
return this.thread.on(event, cb);
}
function close(){
return this.thread.emit('close');
}
function importScripts(){
var i$, len$, p, results$ = [];
for (i$ = 0, len$ = arguments.length; i$ < len$; ++i$) {
p = arguments[i$];
results$.push(self.eval(native_fs_.readFileSync(p, 'utf8')));
}
return results$;
}

@@ -28,8 +28,2 @@ function ThreadNextTick(){

thread.nextTick = nextTick;
self.addEventListener = function(event, cb){
return this.thread.on(event, cb);
};
self.close = function(){
return this.thread.emit('close');
};
Object.defineProperty(self, 'onmessage', {

@@ -36,0 +30,0 @@ set: function(cb){

* Worker API
* `importScripts`
Probably just forward to `require`.
* `setTimeout` / `clearTimeout` / `setInterval` / `clearInterval`

@@ -5,0 +3,0 @@ Forwarding to the default implementation.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc