npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

interphone

v1.3.0

Published

A library that manages communication with web workers, hiding it behind a simple asynchronous interface.

Downloads

10

Readme

$ npm i interphone

Interphone provides a realiable and predictable wrapper for effortless communication with web workers.

Introduction

Web workers are incredibly useful for offloading work from the main thread. Their message-based API, however, can be very unpredictable (besides being quite tedious to master). Consider this code:

// [index.js]
const worker = new Worker('worker.js');
worker.onmessage = (result) => console.log(`The result is: ${result}`)
worker.postMessage([/* ... */]);


// [worker.js]
self.onmessage = ({ data }) => {
  // Very compute-intensive operations
  postMessage(result);
};

Seems fine. But what if we posted two messages? Three? Twenty? We would (hopefully :man_shrugging:) receive two/three/twenty messages back, but the order might be incorrect, and we would not be able to tell which one corresponds to which of ours.

Interphone solves this by wrapping the worker in an asynchronous function, eliminating all the hassle of using postMessage. With Interphone, the code above would become:

// [index.js]
import { loadWorker } from 'interphone/main';

const worker = loadWorker('worker.js');
worker([/* ... */]).then((result) => console.log(`The result is: ${result}`));


// [worker.js]
import { wrapHandler } from 'interphone/worker';

self.onmessage = wrapHandler(({ data }) => {
  // Very compute-intensive operations
  return result; // This can also be a promise
});

As you can see, by invoking the worker with Interphone, we can be sure that every call to the worker will give the correct result, no matter the order of calls or how long the computation takes.

Usage

On the main thread

import from interphone/main or just interphone

Importing and using a worker is incredibly easy. Just load it with loadWorker and you will have access to an asynchronous function that invokes your worker and returns as soon as the worker has finished. Let's see an example:

import { loadWorker } from 'interphone/main';

const concatenateWorker = loadWorker('concatenate-worker.js');

// You can now call `worker` just like any async function
concatenateWorker(['This', 'is', 'so', 'cool!'])
  .then((concatenatedString) => console.log(concatenatedString));

In the worker

import from interphone/worker or just interphone

In your worker, it's even easier: just create a synchronous or asynchronous function that takes in the data as its only argument and returns the result. Then, wrap it with wrapHandler and assign the wrapped function to self.onmessage. Again, an example (the concatenate-worker.js from before):

import { wrapHandler } from 'interphone/worker';

const concatenateStrings = (strings) => strings.join(' '); // This could also be async

self.onmessage = wrapHandler(concatenateStrings);

Error handling

If your worker happened to throw an error upon being called, it's no problem. The promise will be rejected, so you can handle the error as if it were just any asynchronous function throwing.

When not to use it

While Interphone is great when your web workers are just like functions (that is, you invoke them with some data/arguments and they return a single result), it's not that great when they are not function-like. For example, if your worker stayed in the background and emitted events every now and then, Interphone wouldn't come in very useful.

License

This work is licensed under a Creative Commons Attribution 4.0 International License.