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

@opencall/server

v0.5.0

Published

OpenCALL server tooling — registry builder, JSDoc operation discovery, dispatcher helpers, runtime payload validation

Readme

@opencall/server

Docs: https://opencall-api.com (human-readable). AI agents may prefer raw markdown at /spec — GitHub blocks most non-Copilot bots.

Server-side tooling for implementing OpenCALL APIs in TypeScript. Provides the operation registry builder, JSDoc-driven operation discovery, dispatcher helpers, runtime payload validation, and a code generator.

Built on @opencall/types — the canonical Zod schemas and types are imported from there, not redefined.

Install

npm install @opencall/server @opencall/types
# or
bun add @opencall/server @opencall/types

Core principle: operation files are the source of truth

Do not declare operation metadata in a dispatcher or registry file. Operation metadata belongs beside the handler and schemas in the operation file itself, as a JSDoc block:

/**
 * @op orders.getItem:v1
 * @execution sync
 * @timeout 5000
 * @security orders:read
 * @cache server
 * @ttl 300
 */
export const args = z.object({ orderId: z.string(), itemId: z.string() })
export const result = z.object({ id: z.string(), name: z.string(), price: z.number() })
export async function handler(input: unknown): Promise<OperationResult> { ... }

The registry is generated from these files — it's never a separate artifact you maintain. Keeping metadata with the code prevents the drift that occurs when registries are hand-authored.

Node / Bun (runtime discovery)

buildRegistry scans the directory, reads each JSDoc block, and emits a spec-aligned /.well-known/ops response:

import { buildRegistry, validateEnvelope, validateArgs, safeHandlerCall } from "@opencall/server"

const { modules } = await buildRegistry({ opsDir: "./src/operations" })

// Inside your HTTP handler:
const envResult = validateEnvelope(rawBody)
if (!envResult.ok) return envResult.error          // { status, body }

const operation = modules.get(envResult.envelope.op)
if (!operation) return { status: 400, body: { ... } }

const argsResult = validateArgs(operation, envResult.envelope.args, requestId)
if (!argsResult.ok) return argsResult.error

const result = await safeHandlerCall(operation.handler, [argsResult.data], requestId)

Handlers can throw OpenCALL-aware errors created with defineError(). safeHandlerCall uses the error class metadata to choose the response status and error code:

import { defineError, type OperationResult } from "@opencall/server"

export const ItemNotFoundError = defineError({
  code: "ITEM_NOT_FOUND",
  httpStatus: 200,
  message: "Item not found",
  retryable: false,
})

export async function handler(input: unknown): Promise<OperationResult> {
  throw new ItemNotFoundError({ input })
}

Cloudflare Workers / edge runtimes (build-time generation)

Edge runtimes lack node:fs, so scanning operation files at runtime is not possible. Use opencall-generate-server-registry to generate a pre-imported module at build time:

npx opencall-generate-server-registry --ops src/operations --out src/operations.generated.ts

The generated file (src/operations.generated.ts) imports each operation module and embeds the JSDoc-parsed metadata — it is always regenerated from source, never hand-authored:

// Auto-generated — DO NOT EDIT
import type { ModuleEntry } from "@opencall/server";
import * as ordersGetItem from "./operations/orders-get-item.js";
// ...

export const operationEntries: ModuleEntry[] = [
  { module: ordersGetItem, meta: { op: "orders.getItem:v1", execution: "sync", ... } },
  // ...
];

Pass this to buildRegistryFromModules in your Worker entry point:

import { buildRegistryFromModules } from "@opencall/server"
import { operationEntries } from "./operations.generated.js"

const { modules, json, etag } = buildRegistryFromModules(operationEntries)

Add a prebuild script to keep it in sync and a CI check to catch drift:

{
  "scripts": {
    "prebuild": "opencall-generate-server-registry --ops src/operations --out src/operations.generated.ts",
    "check:registry": "opencall-generate-server-registry --ops src/operations --out src/operations.generated.ts --check"
  }
}

--check reads operation sources, generates the expected output in memory, and exits 1 if the file on disk differs or is missing — without writing anything. Add it to your CI pipeline to catch generated files that weren't regenerated after an @op change.

Generate a static /.well-known/errors JSON catalog from the same operation modules:

npx opencall-generate-error-catalog --ops "dist/operations/*.js" --out public/.well-known/errors

At runtime, pre-imported operation modules can also be passed directly to buildErrorCatalogFromModules():

import { buildErrorCatalogFromModules } from "@opencall/server"
import * as ordersGetItem from "./operations/orders-get-item.js"

const errors = buildErrorCatalogFromModules([ordersGetItem])

Surface

  • buildRegistry — scan operation files at runtime (Node/Bun). The primary API.
  • buildRegistryFromModules — accept pre-imported modules for edge runtimes. Feed it output from opencall-generate-server-registry, not hand-authored metadata.
  • buildErrorCatalog, buildErrorCatalogFromModules — serialize OpenCALL error class metadata for /.well-known/errors.
  • parseJSDoc — extract operation metadata from JSDoc. Used internally; exposed for tooling.
  • validateEnvelope, validateArgs, safeHandlerCall, formatResponse, checkSunset — dispatcher building blocks.
  • isDbConnectionError — heuristic detection of DB connection failures, returns BACKEND_UNAVAILABLE.
  • All @opencall/types exports are re-exported (no need to install @opencall/types separately).

CLIs

| Command | Purpose | | ------- | ------- | | opencall-generate-error-catalog | Import operation modules → emit /.well-known/errors JSON | | opencall-generate-error-catalog --check | Verify generated error catalog JSON is in sync | | opencall-generate-server-registry | Scan operation JSDoc → emit operations.generated.ts for Workers | | opencall-generate-server-registry --check | Verify operations.generated.ts matches sources — exits 1 if out of sync (CI drift detection) | | opencall-generate-ops | Fetch /.well-known/ops → emit typed client call wrappers |

OpenCALL spec compatibility

This package targets OpenCALL spec callVersion: 2026-02-10. The @opencall/types peer dependency declares the same.

License

Apache-2.0