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

@aauth/call-log

v0.1.3

Published

The aauth.call record: one log record per HTTP call between AAuth roles, at each end. A pure builder, a Hono-shaped middleware for the callee side, and logged fetch wrappers for the caller side.

Readme

@aauth/call-log

One log record per HTTP call between AAuth roles, written at each end. The AAuth call log (monitor.aauth.dev) joins the caller's and the callee's record on call_id and shows one row: who called whom, the request, the response.

The record is aauth.call, specified in aauth-dev/monitor plan/CALL_RECORD.md. No dependencies. Runs in Cloudflare Workers (nodejs_compat) and Node.

What it does

  • Tokens are logged as { type, payload } — the JWT's typ header and its claims — wherever they appear: in signed and in place of the JWT string in a body, at any depth. Never the JWT, so no log holds a presentable token.
  • Bodies are logged if small. A JSON body up to 8 KB (MAX_BODY_BYTES) as a value. A larger body, or one that is not JSON, as its content_type and size in bytes — so a reader tells "no body" (neither field) from "body not logged" (size). A record still over 30 KB has its larger body cut to text and truncated: true.
  • call_id is base64url SHA-256 of the Signature header. Both ends hold it, so their records join with no new header on the wire.
  • parent is the call being handled when an outbound call is made. It is carried in AsyncLocalStorage from the middleware to any logged fetch in its async continuation, so call sites pass nothing. Where the chain is broken on purpose — a queue consumer, an alarm — pass parent yourself.
  • Levels: 30; 40 for a 4xx that is not a challenge, a peer's 5xx, or a fetch that threw; 50 only for a 5xx the logging party answered itself.

The host

import { callLogMiddleware, loggedFetch, nameAgent, type CallLogHost } from '@aauth/call-log'

const host = (c: Context): CallLogHost => ({
  origin: c.env.ORIGIN,           // this party's server identifier
  role: 'resource',               // agent | resource | ps | as
  log: (record) => emit(c, record), // your event sink: adds service, timestamp, event_id
  defer: (p) => c.executionCtx.waitUntil(p),
})

log is called once per record, never awaited, wrapped in try/catch. Bodies are read from clones inside defer, after the response has gone.

The callee side

app.use('*', async (c, next) => callLogMiddleware(host(c))(c, next))

One record per request, skipping OPTIONS, HEAD, /.well-known/*, /health and /openapi.json (skip overrides). An unsigned request — no Signature and no Signature-Key — is logged only when the response carries AAuth-Requirement: that challenge is the first step of a call, and anything else unsigned is a browser or a scanner. This holds under a host's own skip too. The caller is named from Signature-Key without verification, so a refused call still says who called. A person token names no agent; when your verifier resolves one, say so:

nameAgent(verified.agent_id)

The caller side

With @aauth/agent's createSignedFetch, which reports the on-wire request through onSigned:

const psFetch = loggedFetch(
  (onSigned) => createSignedFetch(keyMaterial, { signBody: true, onSigned }),
  host(c),
  { to_role: 'ps' },
)

makeFetch is called once per call, so concurrent calls never swap reports. With @hellocoop/httpsig's fetch:

const send = loggedHttpsigFetch(httpsigFetch, host(c), { to_role: 'as' })
const res = await send(url, { method: 'POST', body, signingKey, signatureKey })

For a fetch you cannot wrap, failedFetch(host, { url, status | error }) records a failure.

Two things a host should know

  • The callee record waits on the client reading the response. The record reads a clone of the response, and in workerd a clone is a tee that completes when the original body is consumed. Every real caller reads the body; a test that checks only res.status never gets the record — read the body.
  • Where a Signature header is fake and constant (a test harness that trusts Signature-Key), every call gets the same call_id. Make it distinct per request.

Pieces

callIdOf, tokenOf, tokenize, signerOf, paramsOf, errorOf, levelOf, partOf, cap, buildRecord, targetOf are exported for a host that builds records its own way (Wallet's Fastify hooks do).