@justwant/context
v0.2.0
Published
Modular context with explicit propagation. Typed slots, lazy/on-demand/eager resolution, per-instance cache. No AsyncLocalStorage. Node, Edge, Bun, Deno.
Maintainers
Readme
@justwant/context
Modular context with explicit propagation. No AsyncLocalStorage — context is instantiated and passed to children. Compatible Node, Edge, Bun, Deno.
Features
- Explicit propagation — context passed as parameter (Edge, browser compatible)
- Typed slots —
defineSlotwith lazy, on-demand, or eager resolution - Per-instance cache — each
RequestContextmemoizes slot resolution - Framework-agnostic — no runtime dependencies
Installation
bun add @justwant/contextUsage
1. Define slots
import { createContextService, defineSlot } from "@justwant/context";
const userSlot = defineSlot({
key: "user",
scope: "on-demand",
resolve: async (ctx) => {
const userId = ctx.initial.userId as string;
return userApi.findById(userId);
},
});
const orgSlot = defineSlot({
key: "org",
scope: "on-demand",
resolve: async (ctx) => {
const user = await ctx.get(userSlot);
const orgId = ctx.initial.orgId as string;
return orgApi.findById(orgId);
},
});2. Create context
const ctx = createContextService({ slots: [userSlot, orgSlot] });3. Use per request
app.get("/docs", async (req, res) => {
const requestCtx = ctx.forRequest({
userId: req.user?.id,
orgId: req.headers["x-org-id"],
requestId: req.id,
});
const docs = await getDocuments(requestCtx);
res.json(docs);
});
async function getDocuments(requestCtx) {
const user = await requestCtx.get(userSlot); // resolved once, cached
const org = await requestCtx.get(orgSlot); // depends on user, cached
return db.findMany({ orgId: org.id });
}Slot scopes
| Scope | When resolved | Use case |
| ----------- | ------------------ | --------------------------------- |
| eager | At forRequest() | Values already known |
| request | At forRequest() | Depends on initial (requestId…) |
| on-demand | At first get() | Expensive (DB, JWT, etc.) |
Integration with user, org, group
See docs/INTEGRATION_USER_ORG_GROUP.md for examples of flexible context injection with user, organisation, and group packages.
Subpath exports
import { createContextService, defineSlot } from "@justwant/context";
import type { SlotDef, RequestContext } from "@justwant/context/types";
import { SlotNotFoundError, ResolutionError } from "@justwant/context/errors";License
MIT
