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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@reactodia/worker-proxy

v0.1.0

Published

Transparently mapped Web Worker proxy objects for easy background tasks

Readme

Reactodia Worker Proxy npm version

@reactodia/worker-proxy is a TypeScript/JavaScript library for the browser that makes it easy to run background tasks with dedicated Web Workers with automatic connection lifecycle and transparently mapped worker logic via Proxy objects.

Installation

Install with:

npm install --save @reactodia/worker-proxy

Quick example

calc.worker.ts module:

import { connectWorker } from '@reactodia/worker-proxy/protocol';

// Define a class with methods which return Promise
// with results to the worker caller side:
class Calculator {
    constructor(options: {
        precision: number;
    }) { ... }

    add(a: number, b: number): Promise<number> {
        ...
    }
}

// Setup communication protocol with the worker caller 
connectWorker(Calculator);

using-calc.ts module:

import { refCountedWorker } from '@reactodia/worker-proxy';
import type { Calculator } from './calc.worker.ts';

// Create a ref-counted worker definition
const calcWorker = refCountedWorker<typeof Calculator>(
  () => new Worker(
    new URL('./calc.worker.js', import.meta.url)
  ),
  [{ calcPrecision: 2 }]
);

// Get a proxy and connect to the worker
const calculator = calcWorker.acquire();
// Call a worker method
const sum1 = await calculator.add(2, 3);
const sum2 = await calculator.add(10, 20);
// Release the worker when its no longer needed
calcWorker.release();

Using Web Workers from a React component

Although the library does not expose a built-in hook to use workers from a React component to avoid dependencies, it should be trivial to define a simple hook like this:

import type { RefCountedWorker } from '@reactodia/worker-proxy';

function useWorker<T>(worker: RefCountedWorker<T>): T {
    React.useEffect(() => {
        worker.acquire();
        return () => worker.release();
    }, [worker]);
    return worker.getProxy();
}

Then it can be used in a component this way:

import { refCountedWorker } from '@reactodia/worker-proxy';
import type { Calculator } from './calc.worker.ts';

const CalcWorker = refCountedWorker<typeof Calculator>(
  () => new Worker(
    new URL('./calc.worker.js', import.meta.url)
  ),
  [{ calcPrecision: 2 }]
);

function MyComponent() {
    const calculator = useWorker(CalcWorker);
    ...
}

API

The library has the following exports:

@reactodia/worker-proxy entry point

refCountedWorker<T>(factory, constructorArgs) function

Creates a ref-counted Web Worker definition which automatically manages the lifecycle of a worker (create, connect, disconnect) and exposes it behind a Proxy object implementing the same interface as the mapped worker.

Parameters:

  • factory: () => Worker - callback to construct a Worker instance on demand
  • constructorArgs: ConstructorParameters<T> - constructor arguments to initialize the worker with its connected class constructor before any other calls

Returns: RefCountedWorker<WorkerObject<InstanceType<T>>>

RefCountedWorker<T> interface

export interface RefCountedWorker<T> {
    /**
     * Returns an lifecycle state of the connected Worker instance.
     */
    getState(): 'disconnected' | 'blocked' | 'ready' | 'connecting' | 'connected';
    /**
     * Returns a cached Proxy instance to transparently call the worker logic.
     *
     * Important: calls to the proxy will be resolved only after `acquire()`
     * method have been called at least once.
     */
    getProxy(): T;
    /**
     * Increments a ref-count and connects to the worker if needed.
     */
    acquire(): T;
    /**
     * Decrements a ref-count and disconnects from the worker if ref-count is zero.
     */
    release(): void;
}

@reactodia/worker-proxy/protocol entry point

connectWorker(factory: WorkerConstructor) function

Establishes a specific connection protocol between the callee (worker) and external caller (which created a worker via new Worker(...) constructor).

The protocol assumes the worker exposes an RPC-like interface via a class where every public method returns a Promise. This interface is transparently mapped from the caller to the worker via messages.

The communication protocol is defined in terms of messages to be sent with postMessage() and received with onmessage from withing the worker. The worker expect the first message to be a WorkerCall with method === "constructor" to create an instance of the connected class.

Here are the exported definitions for the message types:

export interface WorkerCall {
    readonly type: 'call';
    readonly id: number;
    readonly method: string;
    readonly args: readonly unknown[];
}

export interface WorkerCallSuccess {
    readonly type: 'success';
    readonly id: number;
    readonly result: unknown;
}

export interface WorkerCallError {
    readonly type: 'error';
    readonly id: number;
    readonly error: unknown;
}

License

The library is distributed under MIT license, see LICENSE.