• Stars
    star
    465
  • Rank 94,287 (Top 2 %)
  • Language
    JavaScript
  • License
    Apache License 2.0
  • Created almost 9 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Promise-based messaging for Web Workers and Service Workers

promise-worker Build Status Coverage Status

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:

Usage

Install:

npm install promise-worker

Inside your main bundle:

// 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:

// 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:

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

And inside the worker, you can get registerPromiseWorker via:

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

See demo/ for a simple calculator example.

Message format

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

// main.js
promiseWorker.postMessage({
  hello: 'world',
  answer: 42,
  "this is fun": true
}).then(/* ... */);
// worker.js
registerPromiseWorker(function (message) {
  console.log(message); // { hello: 'world', answer: 42, 'this is fun': true }
});

Note that the message will be JSON.stringifyd, so you can't send functions, Dates, custom classes, etc.

Promises

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

// worker.js
registerPromiseWorker(function () {
  return Promise.resolve().then(function () {
    return 'much async, very promise';
  });
});
// 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 stringifyd, 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:

// worker.js
registerPromiseWorker(function (message) {
  throw new Error('naughty!');
});
// 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:

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

promiseWorker.postMessage({
  type: 'fr'
}).then(/* ... */);
// 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:

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:

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 if you need to support browsers that don't support Promises.

See .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 but you still want to use this library, then you can use pseudo-worker.

For Service Worker support, Chrome 40 and 41 are known to be buggy (see #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.

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

More Repositories

1

optimize-js

Optimize a JS file for faster parsing (UNMAINTAINED)
JavaScript
3,754
star
2

fuite

A tool for finding memory leaks in web apps
JavaScript
3,488
star
3

pokedex.org

Offline-capable PokΓ©dex web site (unmaintained)
JavaScript
2,269
star
4

marky

High-resolution JavaScript timer based on performance.mark/measure (491 bytes min+gz)
JavaScript
1,097
star
5

pinafore

Alternative web client for Mastodon (UNMAINTAINED)
JavaScript
1,020
star
6

emoji-picker-element

A lightweight emoji picker for the modern web
JavaScript
956
star
7

slow-deps

🐌 Measure which dependencies in a project are slowest to npm install (UNMAINTAINED)
JavaScript
513
star
8

blob-util

Cross-browser utils for working with binary Blobs
TypeScript
489
star
9

Catlog

Logcat-reading app for Android (UNMAINTAINED)
Java
471
star
10

pouchdb-find

Easy-to-use query language for PouchDB. ⚠️ NOTICE ⚠️: moved to the PouchDB repo
JavaScript
433
star
11

rollupify

Browserify transform to apply Rollup (UNMAINTAINED)
JavaScript
386
star
12

cjs-to-es6

CLI to convert CommonJS to ES6 modules (UNMAINTAINED)
JavaScript
262
star
13

pseudo-worker

A tiny and mostly spec-compliant WebWorker polyfill
JavaScript
243
star
14

cordova-plugin-sqlite-2

Native SQLite database API for Cordova/PhoneGap/Ionic, modeled after WebSQL (UNMAINTAINED)
JavaScript
169
star
15

CustomFastScrollViewDemo

Demo of an Android app using a FastScrollView with non-alphabetic overlays.
Java
130
star
16

pouchdb-electron

PouchDB for Electron (formerly Atom Shell)
126
star
17

hello-javascript

Demo of a JavaScript module that supports many publishing options
JavaScript
121
star
18

jison-debugger

UI for debugging Jison grammars (UNMAINTAINED)
JavaScript
117
star
19

pretty-s3-index-html

A prettier index.html for listing public files and folders in Amazon S3 buckets. (UNMAINTAINED)
HTML
112
star
20

node-websql

The WebSQL Database API, implemented for Node.js
JavaScript
87
star
21

SuperSaiyanScrollView

Super-fast, super-lightweight sectioned lists for Android
Java
81
star
22

state-of-binary-data-in-the-browser

The state of binary data in the browser (2015)
79
star
23

KeepScore

Score keeping app for Android (unmaintained)
Java
68
star
24

rollup-comparison

compare rollup to browserify/webpack
JavaScript
67
star
25

vdom-as-json

Convert virtual-dom objects to and from JSON (UNMAINTAINED)
JavaScript
64
star
26

database-comparison

Compare DOM-blocking in browser databases
JavaScript
58
star
27

vdom-serialized-patch

Serialize virtual-dom patches as a minimal JSON object (UNMAINTAINED)
JavaScript
56
star
28

pouchdb-phonegap-cordova

PouchDB for PhoneGap/Cordova
55
star
29

chord-magic

Musical chord parser, transposer, and disambiguator in JavaScript
JavaScript
54
star
30

html5workertest

Show which APIs are supported in Web Workers and Service Workers (UNMAINTAINED)
JavaScript
53
star
31

resources-for-mastodon-newbies

Links and tips for Mastodon newbies
53
star
32

fruitdown

Browser-based LevelDOWN adapter that works over Apple IndexedDB (UNMAINTAINED)
JavaScript
50
star
33

vuvuzela

Simple and non-recursive JSON parse/stringify library
JavaScript
45
star
34

AppTracker

Android app that logs app usage statistics in a background Service and displays app information (most frequently used, most recently used, etc.) in a widget or in the main activity.
Java
42
star
35

cost-of-small-modules

Benchmark showing the cost of various bundlers (repo locked πŸ”’)
Shell
38
star
36

pouchdb-async-storage

PouchDB adapter for AsyncStorageDOWN for use in React Native (INCOMPLETE)
JavaScript
37
star
37

ChordReaderRoot

Android app for reading and transposing downloaded guitar chord charts. (unmaintained)
Java
29
star
38

PouchDroid

PouchDB + Android = deliciously synchronous (DEPRECATED! DO NOT USE!)
JavaScript
29
star
39

async-functions-in-pouchdb

Demo of ES7 async functions in PouchDB
JavaScript
28
star
40

pouchdb-ionic

PouchDB for Ionic Framework
27
star
41

arrow-key-navigation

Add left/right focus navigation to a web app or KaiOS app
JavaScript
23
star
42

base64-encode-string

Simple module that converts a string to base64 (for educational purposes)
JavaScript
23
star
43

pouchdb-with-service-workers

Repo for brainstorming on PouchDB replication with service workers
22
star
44

tiny-queue

Simple JavaScript FIFO queue implementation to avoid having to do shift()
JavaScript
21
star
45

css-talk-2022

Talk given in October 2022 for perf.now about CSS runtime performance
JavaScript
21
star
46

pouchdb-nw

PouchDB for NW.js (aka Node-Webkit)
20
star
47

OfflineBrowser

Android app to view HTML pages offline.
Java
19
star
48

test-optimize-js

Web page to test optimize-js against any JavaScript file
JavaScript
19
star
49

serviceworker-update-demo

Effort to write a ServiceWorker demo app that properly manages updates
JavaScript
16
star
50

JapaneseNameConverterRoot

Android app to convert English names into Japanese characters.
Java
16
star
51

SimpleTalker

Simple Android app to speak some text passed in as a parameter. Intended to be used from the command line.
Java
16
star
52

pouchdb-ionic-hello-world

PouchDB Ionic "hello world" app (using Ionic v1)
JavaScript
15
star
53

pouchdb-cordova-hello-world-with-sqlite-plugin

"Hello world" Cordova app with PouchDB, using the SQLite Plugin
CSS
15
star
54

mingz

Check the browserified+min+gz size of any npm module (bash script)
14
star
55

braziljs-2016

Nolan's BrazilJS talk: "We can work it out: from Web Workers to Service Workers"
JavaScript
14
star
56

PopupDemo

Demo of a Quick Action-like popup in Android
Java
14
star
57

open-stylable

Web component where styles leak in, but they don't leak out
JavaScript
13
star
58

substring-trie

Minimalistic trie implementation for prefix searches
JavaScript
13
star
59

cordova-prepopulated-database-demo

Demo of prepopulated databases in Cordova SQLite Plugin 2
JavaScript
12
star
60

pouchdb-nw-hello-world

Demo of using PouchDB in NW.js (aka Node-WebKit)
JavaScript
12
star
61

package-json-versionify

Browserify transform to strip everything from package.json except for the "version" field.
JavaScript
12
star
62

measure-style-and-layout

Demo of measuring style and layout in a webapp
HTML
10
star
63

pouchdb-ionic-2-typescript-demo

Demo of PouchDB with Ionic 2 and TypeScript
JavaScript
10
star
64

browserify-count-modules

Count the total number of modules in a Browserify bundle.
JavaScript
10
star
65

web-starter-kit-rollupify

web starter kit, but with browserify+watchify+rollupify
HTML
10
star
66

webworker-postmessage-perf-test

Web Worker postMessage() benchmark
HTML
9
star
67

pouchdb-chrome-app

PouchDB for Chrome packaged apps
9
star
68

lodash-bundle-size-test

Test repo for experimenting with babel-plugin-lodash and lodash-webpack-plugin
JavaScript
8
star
69

emoji-mart-outside-react

Demo of how to use emoji-mart outside of React
JavaScript
8
star
70

throw-max-listeners-error

Throw an error if the max number of EventEmitter listeners is exceeded
JavaScript
7
star
71

pouchdb-getting-started-todo

Complete PouchDB "Getting Started" Todo app
CSS
7
star
72

memory-leaks-2020

Slides for a talk given at QueensJS in August 2020
HTML
7
star
73

database-comparison-worker-pouch

Fork of https://github.com/nolanlawson/database-comparison to demo worker-pouch
JavaScript
7
star
74

pouchdb-adapter-cordova-sqlite-demo

Demo of using pouchdb-adapter-cordova-sqlite in an Ionic 1 project (note: PouchDB v6, Ionic v1)
JavaScript
7
star
75

pouchdb-chrome-app-hello-world

"Hello world" Chrome app with PouchDB
JavaScript
6
star
76

shadow-selector-benchmark

Benchmark of shadow DOM with various CSS selectors
JavaScript
6
star
77

debug-websql

Simple script to console.log every SQL query received by Web SQL
JavaScript
6
star
78

sqlite-plugin-fork

Fork of the SQLite plugin from 2014, back when it was compatible with PouchDB
JavaScript
6
star
79

pouchdb-cordova-hello-world

"Hello world" Cordova app with PouchDB
CSS
6
star
80

fabric-calculator

Web app to calculate how much fabric you need for a sewing project
Svelte
6
star
81

RelatednessCalculator

Java library for parsing English relative names ("mom," "dad," "grandma," etc.) and calculating relatedness coefficients.
Java
6
star
82

sugar-pouch

A sweeter, simpler interface for PouchDB (work in progress)
6
star
83

pouchdb-perf-report-3.10

PouchDB Performance Report for v3.1.0, November 2014
5
star
84

pouchdb-prebuilt-demo

Demo of a prebult PouchDB database, used in a Cordova app.
JavaScript
5
star
85

async-functions-with-regenerator

A "hello world" for async/await with Babel and Regenerator
JavaScript
5
star
86

CatLogDonate

Java
5
star
87

ultimate-crossword-app

The Ultimate Crossword - an online crossword puzzle (UNMAINTAINED)
JavaScript
5
star
88

react-wheel-jank-demo

Demo of a React app that causes janky scrolling by attaching a wheel event to the entire document
JavaScript
5
star
89

webperf-2016-03

Nolan's 30-minute talk on Web Workers for the NYC Web Performance meetup in March 2016.
JavaScript
5
star
90

couch-community-compat-table

The state of sync pairs in the Couch community
4
star
91

offlinefirst-2016-03

Nolan's presentation for Offline First meetup, Boston March 2016
JavaScript
4
star
92

cascadia-2016

Nolan's talk on Web Workers and Service Workers for Cascadia Fest 2016
JavaScript
4
star
93

pouchdb-ionic-2-hello-world-with-sqlite

PouchDB "Hello world" app using Ionic v2, with native SQLite
TypeScript
4
star
94

async-rect

DEPRECATED - do not use
JavaScript
4
star
95

RelatednessCalculatorInterface

Grails frontend interface for the RelatednessCalculator
JavaScript
4
star
96

jnameconverter-server

JapaneseNameConverter simple RESTful web server
Java
4
star
97

starwars-data

generate data for the starwars-offline app
Python
4
star
98

pwa-deploy

Deploy a Progressive Web App to a connected Android device or emulator (EXPERIMENTAL - DON'T USE THIS)
Java
4
star
99

async-functions-with-kneden

A "hello world" for async/await with Babel and Kneden
JavaScript
3
star
100

independent-rendering-test

Independent Rendering test demo
JavaScript
3
star