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

@ue-too/being-portable

v0.19.2

Published

Portable, serializable definitions for [`@ue-too/being`](https://www.npmjs.com/package/@ue-too/being) state machines. A machine, behavior included, is a plain JSON document. Documents from strangers load safely, compile into ordinary `being` machines, and

Readme

@ue-too/being-portable

Portable, serializable definitions for @ue-too/being state machines. A machine, behavior included, is a plain JSON document. Documents from strangers load safely, compile into ordinary being machines, and snapshot and restore on another computer.

npm version license

Install

bun add @ue-too/being-portable

@ue-too/being is an ordinary dependency and installs with it.

Quick start

import { defineHost, loadMachine } from '@ue-too/being-portable';

// What the machine may do outside itself. The document must declare the
// same effects with the same types, or it will not load.
const host = defineHost({
    effects: {
        dispense: {
            args: { item: 'string' },
            run: ({ item }) => ui.dispense(item as string),
        },
    },
    onError: error => console.warn(error.code, error.path, error.message),
});

const result = loadMachine(JSON.parse(sharedFileText), host);
if (!result.ok) {
    showErrors(result.errors); // every problem (up to 1,000), with JSON paths
} else {
    result.machine.happens('insertCoin', { amount: 1 });
    save(JSON.stringify(result.machine.snapshot()));
}

Continue on another computer:

const resumed = loadMachine(definition, host, { snapshot: JSON.parse(saved) });

The document

{
    "context": { "balance": { "initial": 0, "type": "number" } },
    "effects": { "refund": { "args": { "amount": "number" } } },
    "events": { "cancel": {}, "insertCoin": { "amount": "number" } },
    "format": "being-machine@1",
    "id": "vending",
    "initialState": "IDLE",
    "revision": 1,
    "states": {
        "HAS_MONEY": {
            "on": {
                "cancel": {
                    "do": [
                        {
                            "args": { "amount": { "ctx": "balance" } },
                            "call": "refund"
                        },
                        { "set": "balance", "to": 0 }
                    ],
                    "target": "IDLE"
                }
            }
        },
        "IDLE": {
            "on": {
                "insertCoin": {
                    "do": [
                        {
                            "set": "balance",
                            "to": {
                                "args": [
                                    { "ctx": "balance" },
                                    { "payload": "amount" }
                                ],
                                "op": "+"
                            }
                        }
                    ],
                    "target": "HAS_MONEY"
                }
            }
        }
    }
}

A reaction runs in being's order: require guards first (a false one means the event is not handled), then do, then branches (first true one wins, and it sees the updated context), then target.

Values: number, string, boolean, and lists of one of those.

Expressions: literals, { "ctx": field }, { "payload": field }, { "list": [...] }, and { "op": name, "args": [...] } with + - * / % min max abs floor ceil round, == != < <= > >=, and or not cond, concat toString length, at contains indexOf, randomInt now.

Statements: set, push, removeAt, if/then/else, call (a host effect, optionally writing its result into a field) and output (the value happens() returns).

Nesting: a state can host a child machine from the document's machines. with passes values in when the child starts; when the child enters a state marked final, the parent's onDone runs in the same event and can read the child's context with { "childCtx": field }.

The full format is in the design spec.

Safety

  • No code in documents: no eval, no new Function. Behavior is data the interpreter walks.
  • Everything is checked before anything runs: structure, names, references, types, and where each construct may appear.
  • A document can only reach what it declared: its own context, the event payload and the host's declared effects. Names like __proto__ are rejected, and nothing is looked up through a prototype.
  • No loops or recursion, so every event finishes. Limits cap document size, nesting, list and string lengths, and machine instances; override them with defineHost({ limits }).
  • Each happens(), start(), reset() and wrapup() is also capped by maxEventWork (1,000,000 work units by default: one per expression and statement, plus the length of any list or string it copies or scans). Checking a document has a work budget too, in which a named guard counts at every place it is used.
  • Each happens(), start(), reset() and wrapup() is atomic: if anything fails, the whole machine tree rolls back and onError gets the error. Effects that already ran are listed but not undone.
  • onEventResult and onStateChange subscribers are notified while the event is still running, so they can see a result or a state change for an event that then fails and rolls back. What happens() returns and what onError receives are final.
  • An effect or subscriber that calls back into the machine gets a reentrant-call error; defer such calls with queueMicrotask.

Snapshots

machine.snapshot() returns plain JSON: the current state and context of the machine and of its running child, pinned to the definition's id and revision. restore() checks a snapshot like any untrusted input and either applies it completely or changes nothing. It runs no statements and calls no effects; rebuild your view from currentState and machine.context.

A snapshot from another revision is rejected unless you pass { mode: 'structural' } (or restoreMode: 'structural' to loadMachine), which keeps the fields that still fit, gives new fields their initial values, and reports everything it dropped or defaulted.

Works with being tools

A loaded machine is a being TemplateStateMachine, so extractMachineGraph and @ue-too/being-devtools work on it unchanged. Inline guards show up under their printed expression, such as balance >= payload.price.

Performance

In the package benchmark, typical machines handle an event in about a microsecond (a flat one in under one, a nested one in under two), so thousands of events fit in one 60 FPS frame. Run bun packages/being-portable/bench/happens.ts to measure on your machine. That measures ordinary documents; a hostile document is held in check by the limits, not by speed, and maxEventWork caps what any one event can cost.

API Reference

For complete API documentation with detailed type information, see the TypeDoc-generated documentation.

License

MIT

Repository

https://github.com/kinnet-studio/ue-too