
Security News
Crates.io Users Targeted by Phishing Emails
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
@brianmcallister/api-poller-worker
Advanced tools
Efficient polling with WebWorkers. Make existing APIs feel real time
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.
Hosted demo: https://api-poller-worker.netlify.com/
You can also run the demo locally. To get started:
git clone git@github.com:brianmcallister/api-poller-worker.git
cd api-poller-worker/demo
npm i
npm start
npm install @brianmcallister/api-poller-worker
There are two ways to use this library:
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...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.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));
There are two distinct steps to getting this working:
ApiPollerWorker
instance in your application, and subscribe to updates.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.
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"
}
]
ApiPollerWorker
import { ApiPollerWorker } from '@brianmcallister/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);
});
WorkerCore
import { WorkerCore } from '@brianmcallister/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 '@brianmcallister/api-poller-worker';
import { Resource } from '../src/types';
new WorkerCore<Resource>({ url: '<some endpoint>' });
createEmptyMsg
Create the Msg<T>
structure, but empty. Useful for building default state for a slice of Redux state.
import { createEmptyMsg } from '@brianmcallister/api-poller-worker';
createEmptyMsg<T>(): Msg<T>
Records<T>
Keep track of a normalized set of records.
import { Records } from '@brianmcallister/api-poller-worker';
interface Records<T> {
ids: string[];
byId: { [id: string]: T };
}
Msg<T>
Represents the contents of the message emitted by the WorkerCore
.
import { Msg } from '@brianmcallister/api-poller-worker';
interface Msg<T> {
newItems: Records<T>;
updatedItems: Records<T>;
removedItems: string[];
}
ApiPollerWorkerOptions
Options object accepted by ApiPollerWorker
.
import { ApiPollerWorkerOptions } from '@brianmcallister/api-poller-worker';
interface ApiPollerWorkerOptions {
apiUrl?: string;
autoStart?: boolean;
inline?: boolean;
workerUrl?: string;
}
FAQs
Efficient polling with WebWorkers. Make existing APIs feel real time
We found that @brianmcallister/api-poller-worker demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
Product
Socket now lets you customize pull request alert headers, helping security teams share clear guidance right in PRs to speed reviews and reduce back-and-forth.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.