@background-tasks/core
v0.1.1
Published
Framework-agnostic durable background task runtime for browser applications.
Downloads
193
Maintainers
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/coreQuick 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
enqueuestores a task and wakes the scheduler when the manager is running.- Active duplicates are deduplicated by
ownerKey, task type, and payload. executereturnscomplete(...)for terminal success orscheduleNext(...)for polling.- Throwing from
executeusesmaxRetriesand the optional retry policy. pause,resume, andcancelare external manager controls.stopaborts current executions and stores unfinished running tasks asqueued.clearStorageperforms 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:browserLicense
MIT
