@b9g/async-context

TC39 AsyncContext proposal implementation for request-scoped state.


AsyncContext.Variable<T>

Stores a value that propagates through async operations.

Constructor

new AsyncContext.Variable<T>(options?: {
  defaultValue?: T;
  name?: string;
})

run<R>(value: T, fn: () => R): R

Executes a function with the variable set.

const user = new AsyncContext.Variable<User>();

user.run({ id: 1 }, () => {
  console.log(user.get()); // { id: 1 }
});

get(): T | undefined

Gets the current value.

const current = user.get();

AsyncContext.Snapshot

Captures and restores all variable values.

Constructor

const snapshot = new AsyncContext.Snapshot();

run<R>(fn: () => R): R

Executes with captured values restored.

let snapshot: AsyncContext.Snapshot;

requestId.run("req-123", () => {
  snapshot = new AsyncContext.Snapshot();
});

snapshot.run(() => {
  console.log(requestId.get()); // "req-123"
});

static wrap<T>(fn: T): T

Wraps a function to run with current context.

requestId.run("req-123", () => {
  const wrapped = AsyncContext.Snapshot.wrap(() => {
    console.log(requestId.get());
  });
  setTimeout(wrapped, 100); // Logs "req-123"
});

Nesting

Inner run() calls shadow outer values:

level.run(1, () => {
  console.log(level.get()); // 1
  level.run(2, () => {
    console.log(level.get()); // 2
  });
  console.log(level.get()); // 1
});

Shovel Built-in Contexts

Global Description
cookieStore Request-scoped cookie access

See Also