1.1.5 • Published 6 months ago

@apiratorjs/async-context v1.1.5

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

@apiratorjs/async-context

NPM version License: MIT

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: AsyncContextStore extends the native Map class, so all Map methods (such as set, 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-context

Or using yarn:

yarn add @apiratorjs/async-context

Usage

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.

1.1.5

6 months ago

1.1.4

6 months ago

1.1.3

8 months ago

1.1.2

8 months ago

1.1.1

8 months ago

1.1.0

8 months ago

1.0.5

8 months ago

1.0.3

8 months ago

1.0.2

8 months ago

1.0.1

8 months ago

1.0.0

8 months ago