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

@miadi/stateloom-engine

v0.4.4

Published

State machine engine for stateloom — SMDF parser, validator (V001–V014), hierarchical runtime, in-memory interpreter and Python/TypeScript code generators

Readme

@miadi/stateloom-engine

npm

State Machine Craft — parse, validate, run, and generate code from hierarchical state machines described in a single JSON file.

Install

npm install @miadi/stateloom-engine

Renamed from smcraft. The npm package smcraft is deprecated and no longer published; @miadi/stateloom-engine continues its version line. The PyPI package The Python twin is now miadi-stateloom-engine (import package stateloom, CLI smcg).

What it is

@miadi/stateloom-engine reads a State Machine Definition Format document (.smdf.json): settings, event sources, and one nested tree of states with transitions. From that document it gives you four things — a parser, a rule-coded validator, an interpreter that drives the machine at runtime, and code generators that emit standalone TypeScript or Python classes.

It is not a hub, a UI, or a network protocol. Nothing here opens a socket or touches a browser. The live design surfaces — the socket.io hub, the CLI, the React canvas, the MCP server — are the @miadi/stateloom-* packages listed below, and they read the same .smdf.json this engine runs.

A Python twin ships on PyPI as miadi-stateloom-engine (pip install miadi-stateloom-engine, CLI smcg) with the same definition format.

Usage

Drive a definition directly with the Machine interpreter. The constructor validates, builds the state tree, and enters the initial leaf state:

import { Machine, listTransitions, type StateMachineDefinition } from "@miadi/stateloom-engine";

const def: StateMachineDefinition = {
  settings: { namespace: "shop", name: "OrderWorkflow", asynchronous: false },
  events: [
    { name: "OrderEvents", events: [{ id: "approve" }, { id: "ship" }] },
  ],
  state: {
    name: "Root",
    states: [
      { name: "Pending", transitions: [{ event: "approve", nextState: "Approved" }] },
      { name: "Approved", transitions: [{ event: "ship", nextState: "Shipped" }] },
      { name: "Shipped", kind: "final" },
    ],
  },
};

const machine = new Machine(def);

machine.state;              // "Pending"
machine.path;               // ["Root", "Pending"]
machine.availableEvents();  // ["approve"]

const r = machine.send("approve");
// { handled: true, changed: true, from: "Pending", to: "Approved", event: "approve" }

machine.send("ship");
machine.done;               // true
machine.visited;            // ["Pending", "Approved", "Shipped"]

listTransitions(def);       // every edge, flattened, for graph ingest

Guards are condition strings on a transition. The default guard reads them as truthy keys of a context object; pass your own guard to evaluate them however you like:

const withContext = new Machine(def, { context: { paymentCleared: true } });

const withCustomGuard = new Machine(def, {
  guard: (condition, payload, ctx) => evaluate(condition, { ...ctx, ...payload }),
});

Parse from disk, validate, and generate code:

import { parseFile, enrich, validate, TypeScriptCodeGenerator } from "@miadi/stateloom-engine";

const definition = parseFile("./order.smdf.json");
const model = enrich(definition);            // adds stateMap / parentMap / allStates

for (const e of validate(model)) {
  console.error(`${e.ruleId} ${e.message}`); // e.g. "V006 Undefined state: Shiped"
}

const source = new TypeScriptCodeGenerator(model).generate();

Machine throws MachineDefinitionError on the fatal rules (V001 no root state, V002 duplicate state name, V006 transition targets an undefined state) and collects the rest on machine.warnings. The TypeScript validator implements V001, V002, V003, V005, V006, V007 and V013; the Python build carries the full V001V014 set.

Subpath exports

| Import | Contents | |---|---| | @miadi/stateloom-engine | Everything below, re-exported | | @miadi/stateloom-engine/runtime | Context, ContextAsync, ContextBase, State, StateKind, TransitionHelper, ObserverNull, ObserverConsole | | @miadi/stateloom-engine/machine | Machine, MachineDefinitionError, listTransitions | | @miadi/stateloom-engine/parser | parseJson, parseFile, enrich, validate | | @miadi/stateloom-engine/codegen | TypeScriptCodeGenerator |

Generated code imports from @miadi/stateloom-engine/runtime, so the runtime is a dependency of what the generator emits — not a build-time artifact.

Part of the stateloom stack

| Package | Role | |---|---| | @miadi/stateloom-engine | this package — the engine | | @miadi/stateloom-protocol | Patch ops, diff/apply, layout, renderers — zero runtime deps | | @miadi/stateloom | socket.io hub holding the live document | | @miadi/stateloom-client | Framework-agnostic client for the hub | | @miadi/stateloom-react | React binding over the client | | @miadi/stateloom-cli | smcx — terminal design surface and renderers | | @miadi/stateloom-mcp | MCP server so LLM agents can design machines |

License

MIT © Guillaume Isabelle