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

@oatscenter/trellis-testkit

v0.100.0-rc.40

Published

Node integration test host using ordinary Trellis runtime binaries and public SDK clients.

Readme

@oatscenter/trellis-testkit

Node helpers that own a real Trellis/NATS runtime for service-repository tests. Use ordinary node --test; there is no runner, matrix, or case registration.

Generated Participants

List the fixture source and dependencies in trellis.toml, author participants in contract.trellis, run trellis install, and import their generated participant exports. Never construct test contracts, subjects, or authorization evidence by hand.

import { TrellisTestRuntime } from "@oatscenter/trellis-testkit";
import { TrellisService } from "@oatscenter/trellis/service";
import { apps, participants } from "test-trellis";

await using runtime = await TrellisTestRuntime.start();
const identity = await runtime.registerService({
  name: "provider",
  contract: participants.provider.participant,
});
const service = await TrellisService.connect({
  trellisUrl: runtime.trellisUrl,
  participant: participants.provider.participant,
  name: "provider",
  seed: identity.seed,
}).orThrow();
const client = await runtime.connectClient({
  name: "caller",
  contract: apps.caller.request,
});

Each registerService call returns a new instance key. Without deployment, a service uses the runtime's default deployment unless a different participant already runs there; then it gets a deployment of its own. Registering the same participant again adds an instance (a replica) to its deployment.

Register generated handlers before starting the service. Exercise generated caller methods and inspect their Result values with ordinary assertions. Stop the service in finally, await its run task, and let await using stop the test runtime. Node native OAuth defaults to process-local custody; applications that need persistent login provide their own explicit custody adapter.

For events, subscribe through a generated surface before publishing, then await the actual typed payload. For operations and jobs, await their public terminal result. No helper should replace a real boundary with a fabricated result.

Ownership and Waiting

Ordinary users sharing one app

const alice = await runtime.createUser({ name: "Alice" });
const bob = await runtime.createUser({ name: "Bob" });
for (const user of [alice, bob]) {
  await runtime.grantUserCapabilities({
    user,
    capabilityIds: apps.caller.request.requiredCapabilities,
  });
}
const a1 = await runtime.connectClient({
  name: "Alice 1",
  contract: apps.caller.request,
  user: alice,
});
const a2 = await runtime.connectClient({
  name: "Alice 2",
  contract: apps.caller.request,
  user: alice,
});
const b1 = await runtime.connectClient({
  name: "Bob 1",
  contract: apps.caller.request,
  user: bob,
});

The app registration is reused; every login has independent OAuth/DPoP custody. Alice's sessions retain one principal, distinct from Bob's. Runtime-owned user handles expose name, username, and principalId, never passwords. Explicit user login uses real consent and never grants or restores capabilities. This also applies to registerClient and authorizeNativeUserCode with user. Omitting user retains the seeded-admin convenience; service seeds are unchanged.

Runtime lifecycle

The package downloads the latest production CLI and server release (the newest stable release, or the newest prerelease before the first stable one), verified against the checksum published with it; TRELLIS_TEST_VERSION selects another release, and TRELLIS_TEST_SERVER_BIN selects local binaries. It reports the trellis-server version it tests against. Automatic acquisition currently supports Linux x86-64 only; other native targets are not staged for release. Each runtime is built the way an operator builds one: trellis-server nats new makes the broker's operator and config, the testkit writes config.toml, and the first start creates the keys and NATS accounts. trellis-server --dev runs the real broker. There is no nsc dependency. TRELLIS_TEST_CACHE_DIR shares only verified native binaries; each runtime has private configuration, credentials, SQLite data, broker state, process files, and logs.

start() seeds an administrator by default. Use firstAdmin: "browser-flow" only when exercising first-admin browser setup. To use producer-built binaries without downloading, pass trellis: { source: { kind: "path", server } }; both files must match the package version. There is no fallback for invalid paths.

Startup accepts /readyz only when its processId identifies the spawned native host, so another runtime at the selected port cannot satisfy readiness.

restart() restarts the entire production host and its managed broker while retaining data and identity. stop() waits for child cleanup before removing the sandbox. The host receives SIGTERM first; if it exceeds the shutdown bound, the testkit force-closes its isolated Unix process group, including the managed broker. Descendants are also reclaimed if the host crashes. await using shares that cleanup path. The package does not attach tests to a shared NATS URL or assign infrastructure by test name.

Real broker adapter tests can use connectNats() for a privileged isolated connection. It does not own the broker and closes on stop or restart; acquire a new connection after restart. Ordinary service tests use generated clients and registerService/connectClient instead.

With interruptibleNativeProxy, nativeProxyUrl() returns the advertised endpoint for raw clients exercising nativeTransportGate(). Runtime internals and connectNats() stay on the direct broker endpoint. The advertised override is a server launch option, not a change to the generated config file.

runtime.waitFor provides bounded polling for public transitions. Prefer an observable completion signal when available. tempSqlitePath and sqliteMemoryUrl support deterministic real SQLite tests without a control plane.

Repository Live Suite

See integration setup for generation, binary builds, and TRELLIS_TEST_SERVER_BIN environment variables. Run all or a native filter:

npm run test:integration
npm run test:integration -- --test-name-pattern='generated runtime workflows' ts/integration/runtime_test.ts