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

api-poller-worker

v1.3.4

Published

Efficient polling with WebWorkers. Make existing APIs feel real time

Downloads

31

Readme

api-poller-worker

codecov CircleCI npm version

Efficient polling with WebWorkers. Make existing APIs feel real time

api-poller-worker turns regular 'ol RESTful JSON APIs into realtime streaming connections (not really), using polling with web workers.

Table of contents

Demo

Hosted demo: https://api-poller-worker.netlify.com/

You can also run the demo locally. To get started:

git clone [email protected]:brianmcallister/api-poller-worker.git
cd api-poller-worker/demo
npm i
npm start
⇡ Top

Installation

npm install api-poller-worker
⇡ Top

Usage

How to get started

There are two ways to use this library:

  1. Set inline to true when creating an ApiPollerWorker. Doing this will create an inline worker. Although this is much easier than option 2, if you need fine grained control over what's going on inside the worker (such as making other XHR requests, doing expensive calculations based on the data returned by the API that you're polling, etc.), you'll want to try...
  2. Provide a URL to a worker file. Within that worker file, you need to create an instance of WorkerCore. If you do this, you now have the ability to manipulate the data from the API endpoint before you pass it back to your application. You also have the ability to pass more fine grained options to the WorkerCore class.

Option 1: Inline worker

Here's an example of how to create an inline worker:

const worker = ApiPollerWorker({ inline: true, apiUrl: '<my api url>' });

worker.onMessage(data => console.log(data));

Option 2: Create your own Worker.

There are two distinct steps to getting this working:

  1. Create an ApiPollerWorker instance in your application, and subscribe to updates.
  2. Create a web worker, and create a WorkerCore instance inside of it.

What this library does not help with is creating the worker files themselves. You'll have to set this up in your application's build pipeline, but there are many resources available online to guide you. You can also check out the demo application source to see how I like to set it up.

In short, you need to tell your ApiPollerWorker where your worker is, and then in your worker, you need to tell WorkerCore where the API endpoint you'd like to poll is.

The reason for structuring the code this way is so that you can do other operations on the data from your polled API endpoint in your worker, before passing the data back to your application.

Assumptions

Internally, there are some assumptions being made about the API that is being polled. Specifically that the API endpoint responds with JSON, as a list of objects with a unique identifier.

Which key is used as the unique identifier is configurable (see WorkerCore), but there does need to be one. As long as your endpoint responds with something like this, everything should work just fine:

[
  {
    "id": 1,
    "some": "value"
  },
  {
    "id": 2,
    "some": "other value"
  }
]
⇡ Top

API

Classes

ApiPollerWorker

import { ApiPollerWorker } from 'api-poller-worker';

The ApiPollerWorker class is what coordinates the communcation between your app and your worker. The constructor accepts the following:

interface ApiPollerWorkerOptions {
  // URL of the API endpoint to poll. This is only required
  // if inline is true.
  apiUrl?: string;
  // Tell the worker to start polling immediately.
  // Defaults to true.
  autoStart?: boolean;
  // Create an inline worker.
  // Defaults to false.
  inline?: boolean;
  // URL of the Worker to be created.
  // This option is required if inline is false.
  workerUrl?: string;
}
ApiPollerWorker#start

Send a message (via postMessage) to the worker, telling it to start polling.

start(): this;
const pollerWorker = new ApiPollerWorker<Resource>({
  workerUrl: '/my-worker-file.js',
});

pollerWorker.start();
ApiPollerWorker#stop

Send a message (via postMessage) to the worker, telling it to stop polling.

stop(): this;
const pollerWorker = new ApiPollerWorker<Resource>({
  workerUrl: '/my-worker-file.js',
});

pollerWorker.stop();
ApiPollerWorker#onMessage

Subscribe to updates from the ApiPollerWorker instance. The response is a Msg<T>, which is structured so that your application will know exactly which resources in your polled endpoint are new, updated, or removed.

onMessage(callback: (data: Msg<T>) => void): this;
const pollerWorker = new ApiPollerWorker<Resource>({
  workerUrl: '/my-worker-file.js',
});

pollerWorker.onMessage(data => {
  // `data` will be of type Msg<Resource>
  console.log('got data', data);
});
⇡ Top

WorkerCore

import { WorkerCore } from 'api-poller-worker';

The WorkerCore class is the what you need to create an instance of in your Worker. The constructor accepts the following options:

interface WorkerCoreOptions {
  // Options to pass to `fetch`.
  fetchOptions?: RequestInit;
  // URL to poll.
  url: string;
  // Unique key for the resources returned by the API.
  // Defaults to 'id'.
  uniqueKey?: string;
  // How often the API endpoint should be polled,
  // in milliseconds.
  // Defaults to 2000.
  interval?: number;
}

Here's an example of the simplest possible Worker file (with type safety).

worker.ts

import { WorkerCore } from 'api-poller-worker';

import { Resource } from '../src/types';

new WorkerCore<Resource>({ url: '<some endpoint>' });
⇡ Top

Utils

createEmptyMsg

Create the Msg<T> structure, but empty. Useful for building default state for a slice of Redux state.

import { createEmptyMsg } from 'api-poller-worker';
createEmptyMsg<T>(): Msg<T>
⇡ Top

Types

Records<T>

Keep track of a normalized set of records.

import { Records } from 'api-poller-worker';
interface Records<T> {
  ids: string[];
  byId: { [id: string]: T };
}
⇡ Top

Msg<T>

Represents the contents of the message emitted by the WorkerCore.

import { Msg } from 'api-poller-worker';
interface Msg<T> {
  newItems: Records<T>;
  updatedItems: Records<T>;
  removedItems: string[];
}
⇡ Top

ApiPollerWorkerOptions

Options object accepted by ApiPollerWorker.

import { ApiPollerWorkerOptions } from 'api-poller-worker';
interface ApiPollerWorkerOptions {
  apiUrl?: string;
  autoStart?: boolean;
  inline?: boolean;
  workerUrl?: string;
}
⇡ Top