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

@unicity-astrid/build

v0.1.0

Published

Build orchestrator that turns a TS/JS Astrid capsule project into a wasm32-wasip2 component.

Downloads

168

Readme

@unicity-astrid/build

License: MIT OR Apache-2.0 Node: >=20

The compiler that turns a TypeScript class into a WASM capsule.

JavaScript counterpart of astrid-sdk-macros. Rust uses a proc macro that runs at cargo build time; JavaScript needs the same work done by external tooling that runs at astrid build time. This package is that tooling.

Do not depend on this package directly from capsule code. It is invoked by the Rust kernel's astrid-build binary when it detects a package.json + Capsule.toml project, and emits the wasm32-wasip2 component that the Rust side packs into the .capsule archive.

Pipeline

sdk-js/packages/astrid-build/src/index.mjs <project-dir> --out <wasm-path>

1. Read package.json (name, version)
2. wit-events codegen: walk project/wit/, emit project/gen/*.d.ts mirroring `wit_events!`
3. tsc: compile src/*.ts → dist/*.js, using project's tsconfig.json
4. Emit gen/_entry.src.mjs that imports the user's compiled entry,
   constructs the SDK bridge, re-exports the four WIT export names
5. esbuild bundle: gen/_entry.src.mjs + @unicity-astrid/sdk → gen/_entry.mjs
   (one self-contained ESM file, "astrid:*" specifiers marked external)
6. ComponentizeJS programmatic API: gen/_entry.mjs + wit/ → target/<name>.wasm
   (with disableFeatures: all five, so the output has zero WASI imports)
7. Print {wasmPath, bytes} as the final stdout line for the caller to parse

The Rust astrid-build then calls pack_capsule_archive on the resulting .wasm to produce a dist/<name>.capsule archive structurally identical to a Rust-built capsule.

What the bridge generates

The gen/_entry.mjs is a thin wrapper that:

  • Imports the user code (decorators fire and populate the SDK registry)
  • Builds the bridge via createBridge() from @unicity-astrid/sdk/runtime
  • Re-exports the four WIT-required guest functions: astridHookTrigger, run, astridInstall, astridUpgrade

The bridge runtime in @unicity-astrid/sdk dispatches:

  • tool_describe → lazy-built aggregated schema list ({ tools: [...], description: "..." })
  • tool_execute_<name> → optional KV __state load → user handler → optional state save → IPC publish to tool.v1.execute.<name>.result → return { action: "continue", data: undefined }
  • interceptor topic name → user handler → return result via capsule-result.data
  • command name → same as interceptor

This mirrors astrid-sdk-macros::capsule_impl exactly, including the runnable-vs-hook-driven duality from #[astrid::run].

Compile-time enforcement

Decorator violations are caught at registration time (when the class first evaluates), not deferred to runtime:

  • Two @install methods on one class → throws at module load
  • Two @upgrade methods → throws
  • Two @run methods → throws
  • Two @tool("name") with the same name → throws
  • Two @interceptor("topic") with the same topic → throws
  • @install / @upgrade / @run on a private or static method → throws

Schema input types are typechecked by tsc at build time. WIT event types are checked against generated gen/<file>.d.ts.

Configuration

The orchestrator currently accepts:

| Flag | Description | |---|---| | <project-dir> | Path to the capsule project (required) | | --out <wasm-path> | Where to write the componentized wasm (defaults to <project>/target/<name>.wasm) |

The Rust kernel locates this script via:

  1. $ASTRID_JS_BUILD environment variable (absolute path override, dev-only)
  2. <project>/node_modules/@unicity-astrid/build/src/index.mjs (walked up like Node's resolver, so npm-workspaces hoisting works)

ComponentizeJS configuration

The orchestrator pins:

  • worldName: "capsule" (the world declared in astrid-capsule.wit)
  • disableFeatures: ["stdio", "random", "clocks", "http", "fetch-event"] — strips all WASI imports so the kernel doesn't need to provide WASI. Without this, the component would fail to instantiate against the kernel's linker.

These are not configurable — they are correctness requirements, not options.

Development

npm install
node src/index.mjs ../../examples/test-capsule

License

Dual MIT/Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.