# promise-worker

> Communicate with a Web Worker using Promises

Latest version **2.0.1** (published 2019-03-02) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install promise-worker
pnpm add promise-worker
yarn add promise-worker
bun add promise-worker
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.0.1 |
| Published | 2019-03-02 |
| First published | 2016-02-29 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 34.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 482 |
| Author | Nolan Lawson |
| Maintainers | nolanlawson |
| Keywords | web worker, promise, webworker, worker |

## Links

- npm: https://www.npmjs.com/package/promise-worker
- Repository: https://github.com/nolanlawson/promise-worker
- Homepage: https://github.com/nolanlawson/promise-worker#readme
- Issues: https://github.com/nolanlawson/promise-worker/issues
- npm.io page: https://npm.io/package/promise-worker

## Alternatives

- [cron](https://npm.io/package/cron.md) — 4.9M weekly downloads
- [@vercel/queue](https://npm.io/package/@vercel/queue.md) — 731.6K weekly downloads
- [create-sonicjs](https://npm.io/package/create-sonicjs.md) — 1.6K weekly downloads
- [@exellix/jobs-api](https://npm.io/package/@exellix/jobs-api.md) — 941 weekly downloads
- [@forwardimpact/libskill](https://npm.io/package/@forwardimpact/libskill.md) — 575 weekly downloads

## Recent versions

- 2.0.1 (latest) — 2019-03-02
- 2.0.0 — 2018-09-06
- 1.1.1 — 2016-07-20
- 1.1.0 — 2016-07-18
- 1.0.2 — 2016-07-18
- 1.0.1 — 2016-07-17
- 1.0.0 — 2016-02-29

## README

promise-worker [![Build Status](https://travis-ci.org/nolanlawson/promise-worker.svg?branch=master)](https://travis-ci.org/nolanlawson/promise-worker) [![Coverage Status](https://coveralls.io/repos/github/nolanlawson/promise-worker/badge.svg?branch=master)](https://coveralls.io/github/nolanlawson/promise-worker?branch=master)
====

A small and performant library for communicating with Web Workers or Service Workers, using Promises. Post a message to the worker, get a message back.

**Goals:**

 * Tiny footprint (~700 bytes min+gz)
 * Assumes you have a separate `worker.js` file (easier to debug, better browser support)

**Live examples:**

* [Web Workers](https://bl.ocks.org/nolanlawson/05e74a8408a099635c9a38f839b5ae9f)
* [Service Workers](https://bl.ocks.org/nolanlawson/91a7f5809f2e17a2e6a753a3cb8d2eec)

Usage
---

Install:

    npm install promise-worker

Inside your main bundle:

```js
// main.js
var PromiseWorker = require('promise-worker');
var worker = new Worker('worker.js');
var promiseWorker = new PromiseWorker(worker);

promiseWorker.postMessage('ping').then(function (response) {
  // handle response
}).catch(function (error) {
  // handle error
});
```

Inside your `worker.js` bundle:

```js
// worker.js
var registerPromiseWorker = require('promise-worker/register');

registerPromiseWorker(function (message) {
  return 'pong';
});
```

Note that you `require()` two separate APIs, so the library is split
between the `worker.js` and main file. This keeps the total bundle size smaller.

If you prefer `script` tags, you can get `PromiseWorker` via:

```html
<script src="https://unpkg.com/promise-worker/dist/promise-worker.js"></script>
```

And inside the worker, you can get `registerPromiseWorker` via:

```js
importScripts('https://unpkg.com/promise-worker/dist/promise-worker.register.js');
```

### Message format

The message you send can be any object, array, string, number, etc.:

```js
// main.js
promiseWorker.postMessage({
  hello: 'world',
  answer: 42,
  "this is fun": true
}).then(/* ... */);
```

```js
// worker.js
registerPromiseWorker(function (message) {
  console.log(message); // { hello: 'world', answer: 42, 'this is fun': true }
});
```

Note that the message will be `JSON.stringify`d, so you
can't send functions, `Date`s, custom classes, etc.

### Promises

Inside of the worker, the registered handler can return either a Promise or a normal value:

```js
// worker.js
registerPromiseWorker(function () {
  return Promise.resolve().then(function () {
    return 'much async, very promise';
  });
});
```

```js
// main.js
promiseWorker.postMessage(null).then(function (message) {
  console.log(message): // 'much async, very promise'
});
```

Ultimately, the value that is sent from the worker to the main thread is also
`stringify`d, so the same format rules apply.

### Error handling

Any thrown errors or asynchronous rejections from the worker will
be propagated to the main thread as a rejected Promise. For instance:

```js
// worker.js
registerPromiseWorker(function (message) {
  throw new Error('naughty!');
});
```

```js
// main.js
promiseWorker.postMessage('whoops').catch(function (err) {
  console.log(err.message); // 'naughty!'
});
```

Note that stacktraces cannot be sent from the worker to the main thread, so you
will have to debug those errors yourself. This library does however, print
messages to `console.error()`, so you should see them there.

### Multi-type messages

If you need to send messages of multiple types to the worker, just add
some type information to the message you send:

```js
// main.js
promiseWorker.postMessage({
  type: 'en'
}).then(/* ... */);

promiseWorker.postMessage({
  type: 'fr'
}).then(/* ... */);
```

```js
// worker.js
registerPromiseWorker(function (message) {
  if (message.type === 'en') {
    return 'Hello!';
  } else if (message.type === 'fr') {
    return 'Bonjour!';
  }
});
```

### Service Workers

Communicating with a Service Worker is the same as with a Web Worker.
However, you have to wait for the Service Worker to install and start controlling the page. Here's an example:

```js
navigator.serviceWorker.register('sw.js', {
  scope: './'
}).then(function () {
  if (navigator.serviceWorker.controller) {
    // already active and controlling this page
    return navigator.serviceWorker;
  }
  // wait for a new service worker to control this page
  return new Promise(function (resolve) {
    function onControllerChange() {
      navigator.serviceWorker.removeEventListener('controllerchange', onControllerChange);
      resolve(navigator.serviceWorker);
    }
    navigator.serviceWorker.addEventListener('controllerchange', onControllerChange);
  });
}).then(function (worker) { // the worker is ready
  var promiseWorker = new PromiseWorker(worker);
  return promiseWorker.postMessage('hello worker!');
}).catch(console.log.bind(console));
```

Then inside your Service Worker:

```js
var registerPromiseWorker = require('../register');

registerPromiseWorker(function (msg) {
  return 'hello main thread!';
});

self.addEventListener('activate', function(event) {
  event.waitUntil(self.clients.claim()); // activate right now
});
```

Browser support
----

Note that as of v2.0.0, `promise-worker` does not contain a built-in Promise 
polyfill. Use something like [es6-promise](https://github.com/stefanpenner/es6-promise) 
if you need to support [browsers that don't support Promises](https://caniuse.com/#feat=promises).

See [.zuul.yml](https://github.com/nolanlawson/promise-worker/blob/master/.zuul.yml) for the full list
of tested browsers. Assuming you have a Promise polyfill, the supported browsers should be:

* Chrome
* Firefox
* Safari 8+
* IE 10+
* Edge
* iOS 8+
* Android 4.4+

If a browser [doesn't support Web Workers](http://caniuse.com/webworker) but you still want to use this library,
then you can use [pseudo-worker](https://github.com/nolanlawson/pseudo-worker).

For Service Worker support, Chrome 40 and 41 are known to be buggy (see [#9](https://github.com/nolanlawson/promise-worker/pull/9)), but 42+ are supported.

This library is not designed to run in Node.js.

API
---

### Main bundle

#### `new PromiseWorker(worker)`

Create a new `PromiseWorker`, using the given worker.

* `worker` - the `Worker` or [PseudoWorker](https://github.com/nolanlawson/pseudo-worker) to use.

#### `PromiseWorker.postMessage(message)`

Send a message to the worker and return a Promise.

* `message` - object - required
  * The message to send.
* returns a Promise

### Worker bundle

Register a message handler inside of the worker. Your handler consumes a message
and returns a Promise or value.

#### `registerPromiseWorker(function)`

* `function`
  * Takes a message, returns a Promise or a value.


Testing the library
---

First:

    npm install

Then to test in Node (using an XHR/PseudoWorker shim):

    npm test

Or to test manually in your browser of choice:

    npm run test-local

Or to test in a browser using SauceLabs:

    npm run test-browser

Or to test with coverage reports:

    npm run coverage

---
_Source: https://npm.io/package/promise-worker · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
