npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@birtalanrobert/context

v1.1.0

Published

AsyncLocalStorage request context

Readme

@birtalanrobert/context

The ambient request context: who is asking, which tenant, which request.

What it is

An AsyncLocalStorage store carried automatically through every await in a request, so that a service five layers down can know the actor and the tenant without either being threaded through five signatures that do not otherwise care about them.

That threading is not merely tedious — it is the thing that gets skipped, and a tenant id skipped once is a query that reads another customer's rows.

Using it in a NestJS application

There is no module to import. The store is opened by @birtalanrobert/http's ContextMiddleware, which HttpModule applies for you, so an API gets this by importing HttpModule and nothing else.

import { HttpModule } from '@birtalanrobert/http/nestjs';

@Module({ imports: [HttpModule.forRoot({})] })
export class AppModule {}

Then, anywhere below it:

import { getActor, getTenantId, requireTenantId, getRequestId } from '@birtalanrobert/context';

const tenantId = requireTenantId(); // throws if unset, which is the point
const actor = getActor(); // undefined on an unauthenticated route

requireTenantId throws rather than returning undefined, because a query built with an absent tenant is a query that quietly returns nothing — or, with row-level security switched off, everything.

Outside a request

A worker, a scheduled task or a script has no middleware to open a store, so it opens one itself:

import { runWithContext } from '@birtalanrobert/context';

await runWithContext({ tenantId, actor: { id: 'worker', type: 'system' } }, async () => {
  // everything in here sees the same ambient context an HTTP request would
});

This is how a job that acts on behalf of a tenant gets the same row-level security behaviour as the request that enqueued it.

What it does not do

It does not bind the tenant to a database connection. That is runInTenantTransaction in @birtalanrobert/tenancy, and the distinction matters: resolving a tenant into ambient context tells the application who is asking, while binding tells Postgres — and an unbound read on a table with row-level security returns nothing at all.

No dependencies

Nothing here imports a framework or a driver. It is used by the API, the worker and the shared packages alike, and anything framework-shaped would break at least one of them.