A lightweight, type-safe async context management system for JavaScript applications. Perfect for server-side applications where you need to share request-scoped values across components and functions.
- π Type-safe: Full TypeScript support with generic type safety
- π Simple API: Just three functions -
createContext,provide, andpull - π― Isolated Values: Values are isolated to specific async contexts - like a request
- π Single provider: No need to nest multiple providers - pass all contexts in a single Map
- β©οΈ Return values: Unlike raw AsyncLocalStorage, easily get return values from your callbacks
- π¨ Zero dependencies: Uses Node's built-in AsyncLocalStorage
npm install @ryanflorence/async-providerimport { createContext, provide, pull } from "@ryanflorence/async-provider";
// 1. β
Create your contexts
let userContext = createContext<User>();
let dbContext = createContext<Database>();
async function myHandleRequest(req: Request) {
// setup context values
let user = await myAuthenticateUser(req);
let db = myCreateDatabaseConnection(user);
// 2. β
Provide contexts
let html = await provide(
new Map([
[userContext, user],
[dbContext, db],
]),
async () => {
// run your app code within this context
let result = await renderApp();
// Can return values from provider callback
return result;
},
);
return new Response(html, {
headers: { "Content-Type": "text/html" },
});
}
// 3. β
Pull context from anywhere
function renderApp() {
let user = pull(userContext);
let db = pull(dbContext);
// Use user and db...
}Particularly useful in server environments (like React Router Loaders, React Server Components, GraphQL servers) where multiple components need access to request-scoped values:
- User authentication data
- Database connections
- Request-specific configuration
- Feature flags
- Logging context
-
vs. Module imports
- Module scope can't access request-specific information
- Values are properly scoped to each request
-
vs. Raw AsyncLocalStorage
- Simpler API
- No need to nest multiple providers
- Type-safe by default
- Can return values from context scope callback
Creates a new context object for values of type T.
let userContext = createContext<User>();Provides values for contexts within the scope of the callback.
await provide(
new Map([
[userCtx, currentUser],
[featureCtx, flags],
]),
async () => {
// ...
},
);
// Also accepts arrays of tuples
await provide(
[
[userCtx, currentUser],
[featureCtx, flags],
],
async () => {
// ...
},
);Retrieves the value for a context. Must be called within a provide scope.
let user = pull(userContext);MIT
Contributions welcome! Please read our contributing guidelines first.