ajanuw-context
v1.0.0
Published
A lightweight and robust Go-style Context implementation in TypeScript to propagate deadlines, cancellation signals, and request-scoped values.
Maintainers
Readme
ajanuw-context
A modern, lightweight TypeScript implementation of Go's context pattern, designed to manage propagation of deadlines, cancellation signals, and request-scoped values across asynchronous operations.
Features
- 🚀 Go-Style Context API: Fully models Go's structured concurrency control.
- 📦 Modern Bundle: Offers built-in ESM (with tree-shaking support) and UMD targets.
- ⏱️ Automatic Cleanups: Clean propagation of timeouts and manual cancellations down the context tree.
- 🔒 Type-Safe: Written in TypeScript with complete auto-generated type definitions.
Installation
# Using pnpm
pnpm add ajanuw-context
# Using npm
npm install ajanuw-context
# Using yarn
yarn add ajanuw-contextQuick Start & Examples
1. Basic Cancellation (WithCancel)
Perfect for stopping pending tasks when an operation is cancelled or no longer needed.
import { Background, WithCancel } from "ajanuw-context";
// Create a cancellable context from the root Background context
const [ctx, cancel] = WithCancel(Background);
async function performTask(ctx) {
// Simulating an async loop
for (let i = 0; i < 10; i++) {
if (ctx.err()) {
console.log("Task aborted:", ctx.err().message); // "context canceled"
return;
}
console.log(`Processing step ${i}...`);
await new Promise((resolve) => setTimeout(resolve, 500));
}
}
performTask(ctx);
// Trigger cancellation after 1.2 seconds
setTimeout(() => {
cancel();
}, 1200);2. Time-Bound Execution (WithTimeout / WithDeadline)
Useful for preventing tasks from hanging indefinitely (e.g. HTTP requests, DB queries).
import { Background, WithTimeout } from "ajanuw-context";
const [ctx, cancel] = WithTimeout(Background, 2000); // 2-second timeout
async function fetchWithContext(ctx, url) {
const controller = new AbortController();
// Abort the fetch request if context gets cancelled/timed out
ctx.done().then(() => {
controller.abort();
});
try {
const response = await fetch(url, { signal: controller.signal });
return await response.json();
} catch (error) {
if (ctx.err()) {
throw new Error(`Request timed out: ${ctx.err().message}`); // "context deadline exceeded"
}
throw error;
} finally {
// Release resources
cancel();
}
}3. Request-Scoped Value Propagation (WithValue)
Pass request-specific values (like Trace ID, Auth Tokens) down the call stack.
import { Background, WithValue } from "ajanuw-context";
const TRACE_ID_KEY = Symbol("TraceID");
// Attach value to the context tree
const rootCtx = WithValue(Background, TRACE_ID_KEY, "req-123456");
function handleRequest(ctx) {
// Retrieve value from context anywhere in the call hierarchy
const traceId = ctx.value(TRACE_ID_KEY);
console.log("Current Trace ID:", traceId); // "req-123456"
}
handleRequest(rootCtx);API Reference
Interfaces
Context
The core interface that passes deadlines, cancellation signals, and key-value attributes.
deadline(): [Date, boolean]: Returns the time when work done on behalf of this context should be cancelled.done(): Promise<void>: Returns a promise that resolves when work done on behalf of this context is cancelled.err(): Error | null: ReturnsCanceledorDeadlineExceededif the context has been cancelled. Returnsnullif the context is still active.value<T>(key: unknown): T | null: Looks up a key-value pair associated with the context tree.
Core Helpers
Background: Context
Returns a non-null, empty Context. It is never cancelled, has no values, and has no deadline. Usually used as the root context.
WithCancel(parent: Context): [Context, CancelFunc]
Returns a copy of parent with a new done promise. The returned context's done promise is resolved when the returned CancelFunc is called or when the parent context's done promise is resolved, whichever happens first.
WithValue(parent: Context, key: unknown, val: unknown): Context
Returns a copy of parent in which the association of key with val is stored.
WithDeadline(parent: Context, deadline: Date): [Context, CancelFunc]
Returns a copy of parent with the deadline adjusted to be no later than deadline.
WithTimeout(parent: Context, timeoutMs: number): [Context, CancelFunc]
Returns WithDeadline(parent, new Date(Date.now() + timeoutMs)).
Error Instances
Canceled: AnErrorindicating the context was cancelled manually (new Error("context canceled")).DeadlineExceeded: AnErrorindicating the context timed out (new Error("context deadline exceeded")).
License
This project is licensed under the MIT License. See LICENSE for details.
