2gis/prorab

Name: prorab

Owner: 2GIS

Description: Web worker abstraction library

Created: 2017-06-19 14:17:38.0

Updated: 2017-07-07 14:12:51.0

Pushed: 2017-07-10 09:13:44.0

Homepage: null

Size: 30

Language: TypeScript

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Prorab: web worker abstraction library

Build Status

Prorab is a small library providing thin abstraction layer on web worker interface to make easier creation of and interaction with web workers. It's written in typescript entirely, but compiled javascript version is also included.

Workflow

First, create some function, that will be executed inside web worker global scope, like this:

workerFunc = function () {
 This is a web worker global scope!

nsole.log('Hello from worker!');

is.registerMsgHandler('ping', (payload: any) => {

console.log('received ping with ', payload);

this.send({
  type: 'pong',
  payload: { some: 'data' }
});

;

Second, import worker creator function:

rt { createWorker } from 'prorab';

Third, create your worker and add some message handling to it:

control = createWorker(workerFunc, {})
egisterMsgHandler('pong', (pl: any) => {
console.log('Received PONG!', pl);
;

Here you go, the worker is already up and running. Push some messages to it and see if it responses well:

rol.send({
pe: 'ping',
yload: {
some: 'input'


send function on both ends is a function that initiates a message to another end. It has an only object parameter with fields type and payload:

Likewise, registerMsgHandler function on both ends is a receiver function, its second parameter is a callback function, which receives payload as its only parameter.

Passing options into worker

Second parameter in createWorker is a hash map of some values to be transferred into worker global scope. See example below:

workerFunc = function () {
tTimeout(() => console.log('Hey, we\'ve got some options!', this.options), 0);


control = createWorker(workerFunc, {
t1: 'value1'

Options are located in this.options, but only in next tick. You should not rely on any option in worker function itself, but you can use the setTimeout(() => {}, 0) trick if you really need. Previous example will output something like:

 we've got some options! Object { "opt1": "value1" }

Options can be any serializable object. This means it should not contain things like:

Also, it has basic support of passing functions inside a worker, with some limitations:

More advanced example:

workerFunc = function () {
tTimeout(() => {
console.log('Hey, we\'ve got some functional options! They output: ', this.options.double(5)); // Will output "10"
 0);


control = createWorker(workerFunc, {
uble: (i) => i * 2,
sted: {
triple: (i) => i * 3 // Warning! This will throw an exception!


Sharing webpack modules to worker

When used within webpack, Prorab uses third parameter in createWorker to pass hash map of raw webpack module ids to pass into worker. Not every module may be successfully shared with worker, in particular:

Module IDs should be resolved with require.resolve. Hash map keys are names to place module into when passsing to global worker scope, values are modules IDs. See an example of passing axios library into worker:

 Axios should be aliased in webpack config, or it won't work:
.
solve: {
alias: {
  'axios': path.resolve(__dirname, '..', 'node_modules/axios/dist/axios.min.js')
}

.

workerFunc = function () {
tTimeout(() => {
this.imports.axiosInWorker('http://localhost:3000')
  .then((e: any) => { console.log('Axios got reply: ', e); })
  .catch((_e: any) => { debugger; });
 0);


control = createWorker(workerFunc, {}, {
xiosInWorker': require.resolve('axios')

Webpack module will be accessible with this.imports in global worker scope. Like options, imported modules should not be used in current tick.

If a module depends on some other modules, which match all the conditions listed above, you still can pass this module into worker, but you should explicitly provide all its dependencies. For example, any typescript module implicitly needs tslib module, so it should be listed first in imports parameter like this:

ib': require.resolve('tslib')

This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.