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

@nanobpm/engine-wasm

v0.8.1

Published

The nanobpmn engine (engine-core) compiled to WebAssembly for in-browser BPMN execution: deploy a diagram, start instances, activate/complete jobs, and read live snapshots/traces. Published as two subpath entrypoints — a lean baseline engine (default) and

Readme

@nanobpm/engine-wasm

The nanobpmn engine (engine-core) compiled to WebAssembly for in-browser BPMN execution. Deploy a diagram, start instances, activate/complete jobs, drive the virtual clock, and read live snapshots/traces — all client-side, with no gateway. It is the substrate for the Bojtos demo framework (ADR 0043) and the console test-run panel.

The package ships two independent engines from one install, selectable by import path:

| Import | Engine | Wire size (brotli) | Use it for | | --- | --- | ---: | --- | | @nanobpm/engine-wasm | lean — primary state only | ~252 KB | demos, the modeler, debuggers, anything that reads via snapshot() / events() | | @nanobpm/engine-wasm/readmodel | read-model — lean surface + the gateway's C8-style REST read methods | ~561 KB | full-surface app testing in CI that wants gateway read parity | | @nanobpm/engine-wasm/readmodel-types | types only — the DTOs the read-model search* / get*ByKey methods return | 0 KB (erased) | typing read-model query results in a consumer (e.g. @nanobpm/bojtos-kit) without hand-mirroring the shapes |

Why two binaries (not a runtime toggle)

Each variant is its own wasm-pack --target web JS glue + _bg.wasm. A bundler follows the static module graph, so it only emits the wasm for the subpath you actually import — wasm cannot be tree-shaken out of a single fat build. So:

  • Lean-only pages pay zero read-model weight (the +309 KB brotli never lands).
  • You can await import("@nanobpm/engine-wasm/readmodel") to code-split the heavy engine behind a runtime decision.
  • You can even instantiate both on one page.

The read-model variant is the lean engine plus an in-memory wasm SQLite read model (the same projection the gateway serves from), exposing the REST read surface the lean engine lacks.

Install

npm install @nanobpm/engine-wasm

Usage — lean (default)

import init, { TestEngine } from "@nanobpm/engine-wasm";

await init();                       // instantiate the wasm module
const engine = new TestEngine();

engine.deploy(bpmnXml);             // deploy a BPMN diagram
const handle = engine.createInstance("my-process", "{}");
const snap = JSON.parse(engine.snapshot());   // live primary state
const trace = JSON.parse(engine.events());    // the event log
engine.reset();                     // back to a clean engine

The lean surface covers primary state and execution: deploy, createInstance, snapshot, events, job ops (activateJobs, completeJob, failJob, updateRetries, throwError), user-task ops (completeUserTask, assignUserTask, …), messaging/signals, the virtual clock (advanceTime, tickNow), and reset. It links no SQLite / read-model code.

Usage — read-model

import init, { TestEngine } from "@nanobpm/engine-wasm/readmodel";

await init();
const engine = new TestEngine();

engine.deploy(bpmnXml);
engine.createInstance("my-process", "{}");

// Same lean surface as above, PLUS the gateway's REST read channel:
const form  = JSON.parse(engine.getFormByKey("2251799813685250"));
const open  = JSON.parse(engine.searchUserTasks(JSON.stringify({ state: "CREATED" })));
const insts = JSON.parse(engine.searchProcessInstances("{}"));
const res   = JSON.parse(engine.getResourceByKey("2251799813685251"));
const vars  = JSON.parse(engine.searchVariables("{}"));

Read methods (read-model subpath only)

Each returns the same JSON shapes the Camunda v2 REST surface returns; each delegates to the in-memory read model, kept current after every command and cleared by reset().

  • getFormByKey(formKey) → the latest deployed form for formKey ({ tenantId, formId, schema, version, formKey }), or null. Mirrors GET /forms/{formKey}.
  • searchUserTasks(filterJson){ items, page }. Honours an optional { state? } filter (e.g. "CREATED") through the read model. Mirrors POST /user-tasks/search.
  • searchProcessInstances(filterJson){ items, page }. Body is shape-validated; filter/sort/page fields are not yet honoured (returns every instance). Mirrors POST /process-instances/search.
  • getResourceByKey(resourceKey) → the generic resource, or null. Mirrors GET /resources/{resourceKey}.
  • searchVariables(filterJson){ items, page }. Body is shape-validated; long values are truncated with isTruncated: true. Mirrors POST /variables/search.

Typing the results — @nanobpm/engine-wasm/readmodel-types

The methods above hand off opaque JSON strings (the wasm boundary is strings), so the subpath @nanobpm/engine-wasm/readmodel-types ships the DTO types for those results — UserTaskSearchQueryResult, ProcessInstanceSearchQueryResult, VariableSearchQueryResult, FormResult, ResourceResult — so a consumer can type them without hand-mirroring the shapes:

import type { UserTaskSearchQueryResult } from "@nanobpm/engine-wasm/readmodel-types";

const open = JSON.parse(
  engine.searchUserTasks(JSON.stringify({ state: "CREATED" })),
) as UserTaskSearchQueryResult;

These are derived from the single source of truth — the Camunda-parity REST OpenAPI in spec/ — by engine-wasm/readmodel-types (@hey-api/openapi-ts); a CI drift guard regenerates and fails on any stale artifact. The subpath is types-only (its runtime module is empty), so importing it adds zero wire weight.

Choosing a subpath

  • Reach for lean for demos, the modeler, debuggers/adapters, and anything that only inspects snapshot() / events(). Keeping these paths lean is the whole point of the split — the +309 KB brotli must never ship in a demo page.
  • Reach for /readmodel when you need gateway read parity — full-surface app testing in CI — instead of hand-rolling shadow read stores in JS/TS.

References

  • Epic #796 — the read channel via a wasm SQLite read model (size table, toolchain note, downstream consumers).
  • ADR 0043 — Bojtos (the demo framework this engine backs).