@apiratorjs/async-context v1.1.5
@apiratorjs/async-context
A lightweight Node.js library for managing asynchronous contexts using the built-in node:async_hooks module. This package allows you to share, merge, and override context data throughout your asynchronous code execution. It’s especially useful for per-request or per-transaction state management, logging, and debugging.
Note: Requires Node.js version >=16.4.0
Features
- Async Context Management: Seamlessly pass context data across asynchronous calls.
- Context Merging: Automatically merge context data for common data types (plain objects, arrays, Maps, and Sets).
- Context Overriding: Override existing context data when needed.
- Typed Context Store: Built with TypeScript to provide type safety.
- Easy Integration: Works out-of-the-box with Node.js asynchronous operations.
- Extended Map Functionality:
AsyncContextStoreextends the nativeMapclass, so all Map methods (such asset,get,has,delete, etc.) are available and it supports any type as a key—including classes.
Installation
Install the package via npm:
npm install @apiratorjs/async-contextOr using yarn:
yarn add @apiratorjs/async-contextUsage
Basic Example
Use withContext to run a callback within an asynchronous context:
import { AsyncContext } from "@apiratorjs/async-context";
async function main() {
await AsyncContext.withContext("user", { id: 123 }, () => {
// Inside this callback the context is available.
const user = AsyncContext.getContext("user");
console.log("User Context:", user); // { id: 123 }
});
}
main();Merging Context
If you nest context calls using the same key, the package will merge the data if they are compatible (e.g., plain objects, arrays, Maps, or Sets):
import { AsyncContext } from "@apiratorjs/async-context";
AsyncContext.withContext("config", { theme: "dark" }, () => {
console.log(AsyncContext.getContext("config")); // { theme: "dark" }
AsyncContext.withContext("config", { language: "en" }, () => {
console.log(AsyncContext.getContext("config")); // { theme: "dark", language: "en" }
});
});Overriding Context
Use withContextOverride to completely override a value in the context rather than merging:
import { AsyncContext } from "@apiratorjs/async-context";
AsyncContext.withContext("user", { id: 123, name: "Alice" }, () => {
AsyncContext.withContextOverride("user", { id: 999 }, () => {
console.log(AsyncContext.getContext("user")); // { id: 999 }
});
});Working with Multiple Keys
You can work with multiple context keys at once by passing an AsyncContextStore. For example:
import { AsyncContext, AsyncContextStore } from "@apiratorjs/async-context";
// Create a context store from a plain object.
const contextStore = AsyncContextStore.fromObject({
user: { id: 1 },
session: { token: "abc" }
});
AsyncContext.withContext(contextStore, () => {
const user = AsyncContext.getContext("user");
const session = AsyncContext.getContext("session");
console.log("User:", user); // { id: 1 }
console.log("Session:", session); // { token: "abc" }
});Retrieving Context Data
- Entire Context: Call AsyncContext.getContext() with no arguments.
- Specific Key: Call AsyncContext.getContext("key") to get the value associated with that key.
- Partial Context: Use AsyncContext.getMultiContext("key1", "key2") to obtain a subset of the context.
// Get the entire context store.
const store = AsyncContext.getContext();
// Get a specific context value.
const user = AsyncContext.getContext("user");
// Get a partial context containing selected keys.
const partialStore = AsyncContext.getMultiContext(["user", "session"]);Running Tests
To run the tests locally:
1. Clone the repository.
2. Install the dependencies using npm install or yarn install.
3. Run the tests using npm test or yarn test.
Contributing
Contributions, issues, and feature requests are welcome! Please open an issue or submit a pull request on GitHub.