├── CONTRIBUTING.md ├── .gitignore ├── .travis.yml ├── binding.gyp ├── tests └── single-worker.js ├── example ├── main.worker.js └── app.js ├── .gitlab-ci.yml ├── package.json ├── src ├── WebWorkerWrap.h ├── bootstrap_worker.js ├── WebWorkerWrap.cc └── internal │ ├── errors.js │ ├── events.js │ └── path.js ├── README.md ├── lib └── index.js └── LICENSE /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | See https://opensource.guide/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | 3 | node_modules/ 4 | build/ 5 | coverage/ 6 | .nyc_output/ 7 | 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | dist: trusty 3 | sudo: required 4 | 5 | node_js: 6 | - "8.0.0" 7 | 8 | cache: 9 | directories: 10 | - node_modules # NPM packages 11 | 12 | install: 13 | - npm install 14 | 15 | script: 16 | - npm test 17 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [{ 3 | "target_name": "webworker", 4 | "include_dirs": [ 5 | "/usr/local/include/node", 6 | " { 7 | t.plan(1); 8 | let worker = new WebWorker(function() { 9 | console.log('foobar'); 10 | }); 11 | worker.onstdout = function(data) { 12 | t.equal(data, 'foobar'); 13 | t.end(); 14 | worker.terminate(); 15 | process.exit(); 16 | }; 17 | }); -------------------------------------------------------------------------------- /example/main.worker.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let aliveTimer = setInterval(() => { 4 | console.log('i am still in alive...', Date()); 5 | }, 2000); 6 | 7 | module.exports = function(self) { 8 | 9 | self.onmessage = function(data) { 10 | console.log('received the message from host', JSON.stringify(data)); 11 | }; 12 | 13 | self.postMessage({ 14 | worker: true 15 | }); 16 | 17 | setTimeout(() => { 18 | self.postMessage({ 19 | stopWorker2: true 20 | }); 21 | }, 6000); 22 | 23 | }; 24 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # Official framework image. Look for the different tagged releases at: 2 | # https://hub.docker.com/r/library/node/tags/ 3 | image: node:8 4 | 5 | before_script: 6 | - npm install 7 | 8 | # This folder is cached between builds 9 | # http://docs.gitlab.com/ce/ci/yaml/README.html#cache 10 | cache: 11 | paths: 12 | - node_modules/ 13 | 14 | # test:lint: 15 | # script: 16 | # - npm run lint 17 | 18 | test: 19 | script: 20 | - npm test 21 | 22 | # Publish tagged versions to npm 23 | # publish: 24 | # stage: deploy 25 | # only: 26 | # - tags 27 | # - triggers 28 | # script: 29 | # - npm publish -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webworker-ng", 3 | "version": "0.6.19", 4 | "description": "The Web Worker implementation based on thread for Node.js", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "test": "nyc --reporter=lcov tape tests/*.js" 8 | }, 9 | "keywords": [ 10 | "threads", 11 | "webworker", 12 | "rokid" 13 | ], 14 | "author": "Yazhong Liu ", 15 | "license": "UNLICENSED", 16 | "dependencies": { 17 | "bindings": "1.3.0", 18 | "is-plain-object": "^2.0.4", 19 | "nan": "2.6.2" 20 | }, 21 | "devDependencies": { 22 | "tape": "4.8.0", 23 | "nyc": "^11.2.1" 24 | }, 25 | "nyc": { 26 | "exclude": [ 27 | "build", 28 | "node_modules", 29 | "coverage", 30 | "tests/*.js" 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /example/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const WebWorker = require('../').WebWorker; 4 | const worker = new WebWorker((self) => { 5 | // Note: code is in new v8 runtime 6 | require('./example/main.worker.js')(self); 7 | }); 8 | 9 | let shouldStopWorker2 = false; 10 | 11 | worker.onstdout = function(text) { 12 | console.log('onstdout', text); 13 | }; 14 | 15 | worker.onstderr = function(err) { 16 | console.log('onstderr', err); 17 | }; 18 | 19 | worker.onmessage = function(data) { 20 | if (data && data.stopWorker2 === true) { 21 | shouldStopWorker2 = true; 22 | return; 23 | } 24 | console.log('received message from worker:', data); 25 | setTimeout(() => { 26 | worker.postMessage({ host: true }); 27 | }, 100); 28 | }; 29 | 30 | { 31 | let wrongWorker = new WebWorker((self, send, check) => { 32 | send('start'); 33 | while (true) { 34 | // Do nothing 35 | if (check()) break; 36 | } 37 | send('end'); 38 | }, { 39 | defines: [ 40 | function postMessage2worker(msg) { 41 | worker.postMessage(`from wrong worker: ${msg}`); 42 | if (msg === 'end') { 43 | worker.terminate(); 44 | } 45 | }, 46 | function check() { 47 | return shouldStopWorker2; 48 | } 49 | ] 50 | }); 51 | } -------------------------------------------------------------------------------- /src/WebWorkerWrap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace v8; 11 | using namespace std; 12 | 13 | class WebWorkerWrap : public Nan::ObjectWrap { 14 | public: 15 | static NAN_MODULE_INIT(Init); 16 | 17 | private: 18 | explicit WebWorkerWrap(const char*); 19 | ~WebWorkerWrap(); 20 | void InitThread(Isolate*); 21 | void Deinit(); 22 | 23 | const char* source; 24 | const char* root; 25 | uv_thread_t thread; 26 | uv_async_t master_handle; 27 | uv_sem_t worker_locker; 28 | uv_sem_t request_locker; 29 | bool destroyed_ = false; 30 | 31 | Isolate* worker_isolate; 32 | int should_terminate = 0; 33 | int worker_isolate_exited = 0; 34 | Local worker_context; 35 | std::map> callbacks_; 36 | char* callback_id = nullptr; 37 | SharedArrayBuffer::Contents callback_data; 38 | SharedArrayBuffer::Contents script_args; 39 | 40 | char* request_name; 41 | char* request_args; 42 | SharedArrayBuffer::Contents request_returns; 43 | Persistent onrequest_; 44 | 45 | Local Compile(const char* name, const char* source); 46 | Local GetBootstrapScript(); 47 | void Execute(MaybeLocal