/react-suspense-worker

[NOT MAINTAINED] React Suspense for Web Worker with Comlink

Primary LanguageTypeScriptMIT LicenseMIT

react-suspense-worker

CI npm size discord

React Suspense for Web Worker with Comlink

Introduction

This is an experimental library to support Web Workers with React Suspense. Currently, it's implemented with Comlink. Comlink is promise based, but a value wrapped by this library can be treated as a normal value without async/await.

Known issues:

  • No way to clear cache
  • Class not supported (yet)
  • (...and maybe more)

Install

npm install react-suspense-worker

Usage

slow_fib.worker.js:

import { expose } from 'react-suspense-worker';

const fib = i => (i <= 1 ? i : fib(i - 1) + fib(i - 2));

expose(fib);

App.jsx:

import { wrap } from 'react-suspense-worker';

const fib = wrap(new Worker(new URL('./slow_fib.worker', import.meta.url)));

const DisplayFib = ({ number }) => {
  const result = fib(number);
  return <div>result: {result}</div>;
};

const Main = () => {
  const [number, setNumber] = useState(1);
  const [isPending, startTransition] = useTransition();
  const onClick = () => {
    startTransition(() => {
      setNumber((c) => c + 1);
    });
  };
  return (
    <div>
      <span>number: {number}</span>
      <button type="button" onClick={onClick}>+1</button>
      {isPending && 'Pending...'}
      <DisplayFib number={number} />
    </div>
  );
};

const App = () => (
  <Suspense fallback={<span>Loading...</span>}>
    <Main />
  </Suspense>
);

API

expose

Expose a value in worker thread to be wrapped in main thread

Examples

import { expose } from 'react-suspense-worker';

const fib = (i) => (i <= 1 ? i : fib(i - 1) + fib(i - 2));

expose(fib);

wrap

Wrap a worker to be used with React Suspense

Parameters

  • ep Endpoint

Examples

import { wrap } from 'react-suspense-worker';

const fib = wrap(new Worker(new URL('./slow_fib.worker', import.meta.url)));

const DisplayFib = ({ number }) => {
  const result = fib(number);
  return <div>result: {result}</div>;
};

Returns T

Examples

The examples folder contains working examples. You can run one of them with

PORT=8080 npm run examples:01_minimal

and open http://localhost:8080 in your web browser.