Stargazers
Issues


Logo

use-worker-timer

Accurate timers for React!
View Demo »

Report Bug · Request Feature

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. License
  5. Contact

About The Project

Scheduling events in the browser can be challenging. Timeouts you set may be delayed by other tasks running on the main thread. Switching tabs or resizing the window can further impact accuracy, as the main thread gets throttled by the browser. This becomes especially noticeable when events are scheduled to fire in sequence, as the delay will accumulate.

In contrast, web workers run on a separate thread in the background, independent of intensive computations on the main thread, and are not throttled by the browser. However, they are notoriously challenging to use since the only way to communicate with them is through messages sent between the threads.

This package aims to address this issue by providing a convenient React hook for scheduling events in a web worker, while abstracting away some of the complexities of working with them directly.

To use the hook, you define a list of checkpoints and a callback that is called whenever a checkpoint is reached. It returns a set of functions to control the playback of these checkpoints, including playing, pausing, navigating to a specific point in the playback, and looping. Additionally, it provides the current state of the playback and an estimated progress based on the elapsed time since the last reported checkpoint.

Built With

Deno React

(back to top)

Getting Started

Prerequisites

  • React
  • npm or deno

Installation

Deno

import { usePlayback } from "https://deno.land/x/use_worker_timer/index.ts"

NPM

npm install use-worker-timer
import { usePlayback } from "use-worker-timer"

(back to top)

Usage

To use this hook, you pass in a list of checkpoints, as ms values, and a callback that is called whenever a checkpoint is reached. The hook will return a bunch of functions to control the playback, as well as the current state of the playback.

// Creates a list of 64 events, with a spacing of 60 bpm
const BPM = 60
const checkpoints = Array.from({ length: 4 * 16 }).map((_, i) => (i * (60 * 1000)) / BPM)

const callbackForTime = (ms: number) => {
  console.log(`Reached checkpoint ${reportedTime}`)
  if(i === events.length - 1){
    console.log("Reached the end!")
  }
}

... 

const {
  isReady, // Wether the worker is ready to start playing
  playState, // The state of the playback as reported by the worker
  estimatedProgress, // The estimated progress, based on the last reported checkpoint
  lagLog, // A log of the inaccuracy of the timer
  play,
  pause,
  stop,
  setLooping,
  setPlaybackProgress,
} = usePlayback({
  reportCheckpoint: callbackForTime,
  checkpoints: checkpoints,
  estimationUpdateInterval: 100, // How often to update the estimated progress
})
Arguments
  • reportCheckpoint is called whenever a checkpoint is reached.
  • checkpoints is a list of ms values, at which the worker will fire the reportCheckpoint callback.
  • estimationUpdateInterval is how often the estimated progress will be updated. Defaults to never (always same as playState.progress). If omitted, the estimated progress will be the same as in playState.
Return values
  • isReady is a boolean that is true when the worker is ready to start playing.
  • playState will update whenever a checkpoint is reached or a playback function is called. It is an object with the following properties:
    • playing is a boolean that is true when the worker is playing.
    • progress is the progress of the playback, in ms.
    • looping is a boolean that is true when the worker is looping.
  • estimatedProgress will update every estimationUpdateInterval milliseconds, and is based on the last reported checkpoint. As this is calculated on the main thread, it might be slightly off. I recommend using it for UI, but use the reported checkpoints for logic.
  • lagLog is an array of numbers, that represent the inaccuracy of the timer. It will be filled with the inaccuracy per checkpoint, in ms, whenever a checkpoint is reached.
  • play, pause, stop, setLooping and setPlaybackProgress are functions that control the playback. Self explanatory.

Take a look at the full example (source).

(back to top)

License

Licensed under no license, do whatever you want with this, why would I care.

(back to top)

Contact

PetrosiliusPatter - PetrosiliusPatter@proton.me

Project Link: https://github.com/PetrosiliusPatter/use-worker-timer

(back to top)