@alienfishconsulting/core-context
v1.1.0
Published
Strongly typed, functional AsyncLocalStorage wrapper with context propagation for Node.js and Express apps
Maintainers
Readme
@alienfishconsulting/core-context
Strongly typed, functional AsyncLocalStorage wrapper for managing request-scoped context in Node.js applications.
✨ Features
- 🔒 Immutable
RequestContextmodel for tracing and auditing - 🧠 Type-safe accessors for contextual fields (e.g.,
requestId,userId) - 🔁 Async context propagation across call stacks
- 📥 Header integration for tracing across services
- 🧪 CI-enforced test coverage with Vitest & Nx
- ⚙️ Framework-agnostic (no Express dependency)
📦 Installation
pnpm add @alienfishconsulting/core-contextRequires Node.js ≥18.
🧱 Context Model
The RequestContext defines a consistent schema across async boundaries:
interface RequestContext {
requestId: string;
correlationId: string;
userId?: string;
accountId?: string;
transactionId?: string;
}All fields are immutable and meant to persist across the request lifecycle.
🚀 Quick Start
import {
initWithDefaultContext,
getContext,
getContextField,
runWithContext
} from '@alienfishconsulting/core-context';
initWithDefaultContext(() => {
const ctx = getContext();
console.log('Request ID:', ctx?.requestId);
});Or use a custom context:
const context = {
requestId: 'abc123',
correlationId: 'xyz456',
};
runWithContext(context, () => {
// context is now available inside this function
});📥 Working with HTTP Headers
import { extractContextFromHeaders, updateContextFromHeaders } from '@alienfishconsulting/core-context';
const headers = {
'x-request-id': 'abc123',
'x-user-id': 'user789',
};
updateContextFromHeaders(headers);
// Later...
const userId = getContextField('userId');🔧 API Overview
| Function |Description |
|--|--|
| runWithContext(ctx, fn) | Runs fn with the given context |
| initWithDefaultContext(fn) | Auto-generates requestId/correlationId |
| getContext(fallback?: boolean) | Retrieves the current context |
| assertContext() | Returns context or throws if missing |
| bind(fn) | Returns a function bound to the current context |
| extractContextFromHeaders(headers) | Builds a context from header values |
| updateContextFromHeaders(headers) | Extracts + applies context to storage |
| getContextField(key) | Retrieves a specific field from the context |
✅ Best Practices
Always call runWithContext() at the top level of async workflows
Use bind() when passing callbacks to preserve context
Avoid mutating context values — treat them as read-only
Integrate context extraction in your HTTP layer (e.g., middleware or handlers)
🧪 Testing
This package is managed with Nx and uses Vitest for testing.
pnpm nx test core-context✅ 80% coverage required
🎯 100% coverage target
CI will fail if coverage is insufficient
🛠 Project Structure
core-context/
├── src/
│ ├── accessors.ts # Context getters and safety checks
│ ├── headers.ts # HTTP header integration
│ ├── lifecycle.ts # runWithContext(), bind(), initWithDefaultContext()
│ ├── storage.ts # Shared AsyncLocalStorage instance
│ └── types.ts # RequestContext schema🧩 Related Projects
This package is part of the @alienfishconsulting/core monorepo — a collection of modular, enterprise-grade TypeScript utilities.
📄 License
MIT
© Terry "Lee" Allen, Jr
