async-tracer-ts
v1.0.0
Published
A lightweight, framework-agnostic TypeScript utility to trace async function lifecycle and performance.
Maintainers
Readme
async-tracer-ts
A lightweight, framework-agnostic TypeScript utility that wraps any async function to trace its lifecycle and measure performance — with production-grade retry, timeout, and abort support.
Zero dependencies · Dual ESM/CJS · Strict TypeScript · 100% tested
Features
| Feature | Description |
|---|---|
| Generic typing | Preserves the wrapped function's argument & return types exactly |
| Lifecycle tracking | idle → pending → success \| error with timestamps |
| Performance | Sub-millisecond duration via performance.now() |
| Retries | Configurable count, exponential back-off with jitter, retryWhen predicate |
| Timeout | Rejects with TimeoutError after the configured threshold |
| Abort | Cancel via .abort() or an external AbortSignal |
| Concurrency guard | Prevents overlapping .execute() calls |
| Execution history | Optional ring-buffer of past runs |
| Lifecycle callbacks | onStateChange, onSuccess, onError, onSettled |
| Custom errors | TimeoutError, AbortError, ConcurrencyError — all instanceof-safe |
Installation
npm install async-tracer-tsOr copy src/ into your project — there are zero runtime dependencies.
Quick Start
import { AsyncTracer } from 'async-tracer-ts';
const tracer = new AsyncTracer(fetchUser, {
retries: 3,
timeoutMs: 5000,
onSuccess: (user) => console.log('Got user:', user),
});
const user = await tracer.execute(42);
console.log(tracer.state);
// {
// status: 'success',
// result: { id: 42, … },
// error: null,
// duration: 123.45,
// retryCount: 0,
// startedAt: '2026-02-10T…',
// finishedAt: '2026-02-10T…'
// }API Reference
new AsyncTracer(fn, options?)
| Param | Type | Description |
|---|---|---|
| fn | (...args: TArgs) => Promise<TReturn> | The async function to wrap |
| options | AsyncTracerOptions<TReturn> | Optional configuration (see below) |
Options
| Option | Type | Default | Description |
|---|---|---|---|
| retries | number | 0 | Max retry attempts (original call doesn't count) |
| retryBackoff | RetryBackoffConfig | { baseMs: 200, maxMs: 5000, factor: 2, jitter: true } | Back-off delays between retries |
| retryWhen | (err: Error) => boolean | () => true | Predicate — return false to fail immediately |
| timeoutMs | number | undefined | Per-execution timeout in ms |
| signal | AbortSignal | undefined | External abort signal |
| historyLimit | number | 0 | Ring-buffer size for execution history |
| onStateChange | (state) => void | — | Called on every state transition |
| onSuccess | (result, state) => void | — | Called after success |
| onError | (error, state) => void | — | Called after failure |
| onSettled | (state) => void | — | Called after success or failure |
Instance Properties
| Property | Type | Description |
|---|---|---|
| .state | Readonly<TracerState<T>> | Frozen snapshot of the current state |
| .status | AsyncStatus | 'idle' \| 'pending' \| 'success' \| 'error' |
| .result | T \| null | Last successful value |
| .error | Error \| null | Last error |
| .duration | number \| null | Last execution time (ms) |
| .isPending | boolean | Convenience flag |
| .isIdle | boolean | Convenience flag |
| .history | readonly ExecutionRecord<T>[] | Past execution records |
Instance Methods
| Method | Description |
|---|---|
| .execute(...args) | Run the wrapped function — returns the resolved value or throws |
| .abort(reason?) | Cancel an in-flight execution |
| .reset() | Return to idle and clear history (throws if pending) |
Error Classes
| Error | When |
|---|---|
| TimeoutError | Execution exceeded timeoutMs |
| AbortError | Execution was cancelled via signal or .abort() |
| ConcurrencyError | .execute() called while already pending |
| AsyncTracerError | Base class for all the above |
Development
# Install dependencies
npm install
# Type-check
npm run lint
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run the example
npm run example
# Build ESM + CJS
npm run buildProject Structure
async-tracer/
├── src/
│ ├── index.ts # Barrel export
│ ├── async-tracer.ts # Core class
│ ├── types.ts # Type definitions
│ └── errors.ts # Custom error classes
├── tests/
│ └── async-tracer.test.ts
├── example.ts # Runnable demo
├── package.json
├── tsconfig.json # Dev config (strict)
├── tsconfig.build.json # ESM build
├── tsconfig.cjs.json # CJS build
└── README.mdLicense
MIT
