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

coremachine

v1.0.5

Published

A type-safe state machine built on top of Hypercore for distributed, append-only state management. Coremachine combines the power of state machines with the reliability and synchronization capabilities of Hypercore, making it perfect for building distribu

Downloads

601

Readme

Coremachine

A type-safe state machine built on top of Hypercore for distributed, append-only state management. Coremachine combines the power of state machines with the reliability and synchronization capabilities of Hypercore, making it perfect for building distributed applications that need consistent state across multiple peers.

Coremachine extends a Duplex stream — write actions in, read state changes out.

Features

  • 🔒 Type Safety: Full TypeScript support with automatic type inference
  • 🌐 Distributed: Built on Hypercore for peer-to-peer state synchronization
  • 📝 Append-Only: Immutable state history with complete audit trail
  • 🎯 State Machine: Predictable state transitions with guards and actions
  • 🔀 Streamable: Duplex stream interface — pipe actions in, pipe state out
  • 📦 Lightweight: Minimal dependencies, maximum functionality

Installation

npm install coremachine

Quick Start

import Corestore from "corestore";
import { createMachine, Coremachine } from "coremachine";

// Define your state machine
const definition = createMachine({
  initial: "idle",
  context: {
    running: false,
    counter: 0,
  },
  states: {
    idle: {
      on: {
        START: {
          target: "running",
          action: (ctx, counter) => {
            ctx.running = true;
            ctx.counter = counter;
          },
        },
      },
    },
    running: {
      on: {
        INCREMENT: {
          target: "running",
          action: (ctx) => {
            ctx.counter++;
          },
        },
        STOP: {
          target: "idle",
          action: (ctx, finalCount) => {
            ctx.running = false;
            if (finalCount !== undefined) {
              ctx.counter = finalCount;
            }
          },
        },
      },
    },
  },
});

// Initialize Coremachine
const store = new Corestore("./store");
const cube = new Coremachine(
  store.get({ name: "coremachine", valueEncoding: "json" }),
  definition,
);

// Call action directly
await cube.action("START", 1);
console.log(cube.state, cube.context); // "running", { running: true, counter: 1 }

// Or write actions into the stream
cube.write({ event: "INCREMENT" });

// Read state changes out
cube.on("data", ({ state, context }) => {
  console.log(state, context); // "running", { running: true, counter: 2 }
});

Core Concepts

State Machine Definition

Define your state machine using the createMachine function:

const definition = createMachine({
  initial: "stateName",     // Initial state
  context: {                // Shared context object
    // your data here
  },
  states: {
    stateName: {
      on: {
        EVENT_NAME: {
          target: "nextState",
          action: (context, payload) => {
            // Modify context here
          }
        }
      }
    }
  }
});

Duplex Stream Interface

Coremachine is a Duplex stream. The writable side accepts actions, the readable side emits state changes:

const cube = new Coremachine(core, definition);

// Write side — type-safe action messages
cube.write({ event: "START", value: 1 });
cube.write({ event: "INCREMENT" });

// Read side — typed state + context
cube.on("data", ({ state, context }) => {
  console.log(state, context);
});

// Pipe it
actionSource.pipe(cube).pipe(stateConsumer);

The stream opens lazily on first read or write, restoring the latest state from the underlying Hypercore automatically.

Actions and Transitions

Actions are functions that modify the context when transitioning between states:

action: (context, payload) => {
  // Directly modify the context object
  context.someProperty = payload;
  context.counter++;
}

API Reference

createMachine(config)

Creates a state machine definition.

Parameters:

  • config.initial (string): The initial state name
  • config.context (object): The initial context/data
  • config.states (object): State definitions with transitions and actions

Returns: Machine definition object

new Coremachine(hypercore, definition, opts?)

Creates a new Coremachine instance (a Duplex stream).

Parameters:

  • hypercore: A Hypercore instance with JSON encoding
  • definition: Machine definition from createMachine()
  • opts.eager (boolean): If true, push the current state immediately on open

Instance Methods

await cube.action(eventName, payload?)

Trigger a state transition directly.

Parameters:

  • eventName (string): The event to trigger
  • payload (any, optional): Data to pass to the action function

Returns: { state, context } after the transition

cube.write({ event, value? })

Write an action into the stream. Equivalent to calling action() but through the stream interface, with backpressure handled automatically.

await cube.forward()

Move forward in the state history.

await cube.backward()

Move backward in the state history.

cube.truncate(newLength)

Truncate the underlying Hypercore to a new length.

Properties

  • cube.state (string): Current state name
  • cube.context (object): Current context data
  • cube.isEmpty (boolean): Whether the hypercore is empty
  • cube.getAvailableActions() (array): Actions available in the current state

Stream Events

data

Emitted when the state changes. Each message contains the new state and context:

cube.on("data", ({ state, context }) => {
  console.log(`Now in state: ${state}`, context);
});

Advanced Usage

Monitoring State Changes

Use the deep-object-diff library to track specific changes:

import { diff } from "deep-object-diff";

let prev = null;
cube.on("data", ({ state, context }) => {
  if (prev) {
    const changes = diff(prev, context);
    console.log("Changes:", changes);
  }
  prev = structuredClone(context);
});

Distributed State Synchronization

Since Coremachine is built on Hypercore, multiple instances can synchronize automatically:

// Peer A
const storeA = new Corestore("./storeA");
const cubeA = new Coremachine(
  storeA.get({ name: "coremachine", valueEncoding: "json" }),
  definition
);

// Peer B
const storeB = new Corestore("./storeB");
const cubeB = new Coremachine(
  storeB.get({ key: storeA.key, valueEncoding: "json" }),
  definition
);

Piping

Since Coremachine is a standard Duplex stream, it composes with the rest of the streaming ecosystem:

// Pipe actions from one source into the cube
actionStream.pipe(cube);

// Pipe state changes to a consumer
cube.pipe(renderStream);

// Full pipeline
actionStream.pipe(cube).pipe(renderStream);

Use Cases

  • Distributed Applications: Synchronize application state across multiple peers
  • Audit Logging: Maintain immutable history of all state changes
  • Collaborative Tools: Build real-time collaborative applications
  • IoT Networks: Coordinate state across distributed IoT devices
  • Blockchain Alternatives: Create consensus without traditional blockchain overhead

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT


Built with ❤️ using Hypercore