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

@background-tasks/core

v0.1.1

Published

Framework-agnostic durable background task runtime for browser applications.

Downloads

193

Readme

@background-tasks/core

Framework-agnostic durable background task runtime for browser applications.

This package contains the task model, manager lifecycle, scheduler, runner, storage contracts, retry handling, pause/resume/cancel controls, and browser coordination primitives used by Background Tasks.

The package is in early development. Public APIs may change before the first stable release.

Install

npm install @background-tasks/core

Quick Start

import {
  BackgroundTaskManager,
  IndexedDbTaskStorage,
  type BackgroundTaskDefinitions,
} from '@background-tasks/core';

enum TaskType {
  GenerateReport = 'generateReport',
}

type Tasks = {
  [TaskType.GenerateReport]: {
    payload: {
      reportId: string;
    };
    state?: {
      checks: number;
    };
    result: {
      reportId: string;
      url: string;
    };
  };
};

const definitions: BackgroundTaskDefinitions<Tasks> = {
  [TaskType.GenerateReport]: {
    executionTimeout: 10_000,
    pollingInterval: 2_000,
    maxRetries: 3,
    initialState: () => ({ checks: 0 }),
    execute: async ({ task, signal, complete, scheduleNext }) => {
      const response = await fetch(`/api/reports/${task.payload.reportId}`, {
        signal,
      });
      const report = await response.json();

      if (report.ready) {
        return complete({
          result: {
            reportId: task.payload.reportId,
            url: report.url,
          },
        });
      }

      return scheduleNext({
        state: {
          checks: task.state.checks + 1,
        },
      });
    },
  },
};

const manager = new BackgroundTaskManager<Tasks>({
  ownerKey: 'user-123',
  namespace: 'my-app',
  definitions,
  storage: new IndexedDbTaskStorage<Tasks>({
    databaseName: 'my-app-background-tasks',
  }),
  maxConcurrentExecutions: 3,
});

manager.subscribe((event) => {
  console.log(event.type);
});

await manager.start();

await manager.enqueue({
  type: TaskType.GenerateReport,
  payload: {
    reportId: 'report-42',
  },
});

Runtime Behavior

  • enqueue stores a task and wakes the scheduler when the manager is running.
  • Active duplicates are deduplicated by ownerKey, task type, and payload.
  • execute returns complete(...) for terminal success or scheduleNext(...) for polling.
  • Throwing from execute uses maxRetries and the optional retry policy.
  • pause, resume, and cancel are external manager controls.
  • stop aborts current executions and stores unfinished running tasks as queued.
  • clearStorage performs a hard reset of the configured storage and stops first when active tasks exist.
  • Terminal tasks are emitted and removed from durable storage.

API

BackgroundTaskManager

await manager.start();
await manager.stop();

const task = await manager.enqueue({ type, payload });

manager.getTasks();
manager.getTask(task.id);
manager.getTaskAs(task.id, type);
manager.getSnapshot();

await manager.pause(task.id);
await manager.resume(task.id);
await manager.cancel(task.id);
await manager.clearStorage();

const unsubscribe = manager.subscribe((event) => {});

Manager Options

| Option | Required | Default | Description | | --- | --- | --- | --- | | ownerKey | Yes | - | Separates persisted tasks between users, tenants, or accounts. | | definitions | Yes | - | Complete map of task definitions. | | storage | Yes | - | Durable or in-memory task storage. | | namespace | No | - | Enables browser tab coordination and is scoped with ownerKey. | | maxConcurrentExecutions | No | 3 | Global number of tasks that can execute at once. | | tabId | No | UUID | Current tab id for browser coordination. | | heartbeatInterval | No | 2000 | Leader lease renewal interval in milliseconds. | | leaseDuration | No | 6000 | Leader lease lifetime. Must be greater than heartbeatInterval. | | indexedDB | No | globalThis.indexedDB | Custom IndexedDB factory. | | broadcastChannelFactory | No | BroadcastChannel | Custom BroadcastChannel factory. | | coordinator | No | - | Custom coordinator. Use either this or namespace. |

Task Definition Options

| Option | Required | Description | | --- | --- | --- | | executionTimeout | Yes | Maximum time for one executor run before it is aborted. | | execute | Yes | Task executor. Returns complete(...) or scheduleNext(...). | | initialState | Required only for stateful tasks | Creates the first state from the immutable payload. | | pollingInterval | Required when using scheduleNext | Delay before the next polling iteration. | | maxConcurrentExecutions | No | Maximum number of tasks of this type that can execute at the same time. | | maxRetries | No | Number of retry attempts after executor errors. Defaults to 0. | | retryPolicy | No | Optional error classification and retry delay hooks. | | priority | No | Higher priority tasks are selected first. Defaults to 0. |

The manager-level maxConcurrentExecutions is the global execution pool. Definition-level maxConcurrentExecutions is an additional per-task-type cap.

Storage

Use MemoryTaskStorage for tests, demos, or custom in-memory scenarios.

import { MemoryTaskStorage } from '@background-tasks/core';

const storage = new MemoryTaskStorage<Tasks>();

Use IndexedDbTaskStorage for durable browser storage.

import { IndexedDbTaskStorage } from '@background-tasks/core';

const storage = new IndexedDbTaskStorage<Tasks>({
  databaseName: 'my-app-background-tasks',
  storeName: 'tasks',
  version: 2,
});

Browser Coordination

Pass namespace to enable multi-tab coordination. The manager scopes the coordination namespace with ownerKey, so different users do not share leader leases or events.

Only the leader tab executes tasks. Other tabs receive events and can forward task controls to the leader.

Development

npx nx build core
npx nx test core --run
npm run test:browser

License

MIT