Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

128 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mechanoid

CI Maven Central Maven Central - Scala.js Maven Central - Web Maven Central - Postgres

A type-safe finite state machine library for Scala 3 and ZIO (JVM and Scala.js).

ZIO already gives you excellent effect composition. Many domains are also finite state machines. Mechanoid makes that graph explicit and typed: states and events as enums, transitions as ZIO effects, assemblies validated at compile time. Start in memory, then add persistence, durable timeouts, and distributed coordination as ZIO layers when you need them. In the browser, mechanoid-web persists to IndexedDB and syncs tabs over BroadcastChannel.

Docs: earlyeffect.rocks/mechanoid

Features

  • Declarative DSLState via Event to Target
  • Compile-time validation — duplicate transitions, overrides, produced-event types
  • Hierarchical states — nested sealed traits and all[T] group transitions
  • Composable assemblies — reusable fragments with full compile-time checks
  • ZIO on every edge — entry effects, producing effects, env and errors
  • Optional production rungs — event sourcing, durable timeouts, distributed locks
  • Scala.js + IndexedDB — multi-tab shared instances via mechanoid-web

Installation

// Core (JVM)
libraryDependencies += "rocks.earlyeffect" %% "mechanoid" % "0.3.2"
libraryDependencies += "dev.zio" %% "zio" % "2.1.26"

// Core (Scala.js)
libraryDependencies += "rocks.earlyeffect" %%% "mechanoid" % "0.3.2"
libraryDependencies += "dev.zio" %%% "zio" % "2.1.26"

// Browser IndexedDB + BroadcastChannel (Scala.js)
libraryDependencies += "rocks.earlyeffect" %%% "mechanoid-web" % "0.3.2"

// Optional PostgreSQL persistence (JVM)
libraryDependencies += "rocks.earlyeffect" %% "mechanoid-postgres" % "0.3.2"

Quick Start

import mechanoid.*
import zio.*

enum OrderState derives Finite:
  case Pending, Paid, Shipped

enum OrderEvent derives Finite:
  case Pay, Ship

import OrderState.*, OrderEvent.*

val orderMachine = Machine(assembly[OrderState, OrderEvent](
  Pending via Pay to Paid,
  Paid via Ship to Shipped,
))

val program = ZIO.scoped {
  for
    fsm   <- orderMachine.start(Pending)
    _     <- fsm.send(Pay)
    _     <- fsm.send(Ship)
    state <- fsm.currentState
  yield state // Shipped
}

Documentation

Full guide with Mermaid diagrams and docs-as-tests examples:

Development

./scripts/install-git-hooks  # once per clone: pre-commit runs scalafmtCheckAll
git config core.hooksPath hooks
npm ci                       # jsdom + fake-indexeddb for Scala.js tests
sbt testJVM                  # JVM tests + docs site
sbt testJS                   # coreJS + webJS (IndexedDB / multi-tab reconstruct)
sbt docsPreview              # watch + serve interactive docs

License

Apache 2.0 — see LICENSE

About

A type-safe, effect-oriented finite state machine library for Scala 3 built on ZIO

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages