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

@suss/adapter-typescript

v0.4.0

Published

TypeScript adapter for suss — walks source files with ts-morph and emits raw extractions for the suss pipeline.

Readme

@suss/adapter-typescript

TypeScript language adapter for suss. It extracts behavioral structure from TypeScript source using ts-morph.

What this package is

@suss/adapter-typescript is the TypeScript language adapter. It walks ASTs via ts-morph, identifies code units (handlers, loaders, actions, client call sites), and emits RawCodeStructure objects that the extractor assembles into BehavioralSummary IR.

It supports both provider-side extraction (handler registration, terminal discovery, contract reading, body-shape extraction) and client-side extraction (call-site discovery, enclosing-function lifting, response field tracking via expectedInput).

Where it fits in suss

It imports @suss/behavioral-ir for type references and @suss/extractor for the RawCodeStructure contract. Framework packs and the CLI consume it. It runs one level above the extractor in the pipeline, feeding it raw structures produced from TypeScript AST analysis.

How a project is loaded

ts-morph parses every file in the tsconfig include glob when a Project is constructed, which on a monorepo is thousands of files the extraction never touches. The bootstrap avoids that in four steps:

  1. Parse the tsconfig for its file list, without any AST work.
  2. Read each file concurrently and run ts.preProcessFile, a token scan roughly ten times cheaper than a parse.
  3. Keep the files whose imports match some active pack's requiresImport gate.
  4. Add only those to the Project.

The closure pass loads the rest as symbol resolution reaches them. It will only lazy-load files the tsconfig already knew about, so a run never pulls in node_modules content nobody asked for.

Deep re-export chains

The compiler finds files by recursing. It reads a file, resolves that file's imports, then reads each of those the same way. If you hand it one file at the top of a long chain, it will descend the entire chain in a single pass, and a barrel chain a few hundred modules deep will overflow the call stack. A gated run makes that likely, because the bootstrap only loaded the entry file.

Two passes get ahead of the compiler. Both walk the graph iteratively, starting from the far end, so that by the time the compiler asks about any module, the one below it has already been resolved.

  • Loading. Before a run walks any file, we load that file's import graph bottom up, so nothing is added until everything it imports is already there. We work out the graph by scanning tokens and resolving module paths, never by building a program. We only load files the project could already reach; anything that resolves under node_modules we leave for whoever asks for it. All the roots share a single visited set, so a file that several roots reach gets read once instead of once per root. The pass runs at the start, as soon as we know which files the run will walk, because anything that touches the checker builds the program, and discovery gets there long before we ask a module what it exports. It cannot run any earlier than that: a file that showed up before we fixed the list would get walked for units too, and that would change what the run reports.
  • Alias warming. Once the graph is loaded, we resolve each file's import bindings and export specifiers from the bottom up, so export { x } from "./next" never puts a whole chain on the stack. We only do this for graphs at least WARM_DEPTH deep. That number is well below the depth the compiler manages on its own, and well above anything an ordinary barrel file reaches, so all it decides is where we spend time. Warming changes the order things resolve in, never what they resolve to.

If the warmed compiler still cannot follow a chain, we record that rather than throwing. A provider whose exports we could not read would otherwise look exactly like one that exports nothing, so we note the file in the extraction report and let the run finish with the summaries it has.

Status

Stable. Public API: createTypeScriptAdapter returns an adapter with extractFromFiles and extractAll methods. Provider-side extraction (handlers, terminals, contracts, body shapes) and client-side extraction (call sites, response field tracking) are both supported. See docs/extraction-algorithm.md for the algorithm and docs/status.md for the capability matrix.

Coverage

coverage

License

Licensed under Apache 2.0. See LICENSE.


For the canonical design, see docs/architecture.md.