webnarmin / automata
Framework-agnostic orchestration engine for finite state machines, statecharts, and multi-agent systems in PHP.
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/webnarmin/automata
Requires
- php: >=8.1
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.5
This package is auto-updated.
Last update: 2025-10-11 18:55:26 UTC
README
Framework-agnostic orchestration engine for finite state machines (FSM), statecharts, and small multi-agent systems in PHP.
Features
- Decouples automata execution from application code through a central orchestrator
- Supports collaborative scenarios with FSM automata and pluggable cycle middleware
- Provides immutable input payloads, shared context storage, and snapshot/restore facilities
- Ships with lightweight container and context implementations without framework dependencies
- Includes PHPUnit coverage for the orchestrator lifecycle and transition handling
Requirements
- PHP 8.1 or newer
- Composer
Installation
Install the library via Composer:
composer require webnarmin/automata
Or add it to your project's composer.json:
{
"require": {
"webnarmin/automata": "^1.0"
}
}
Then run composer install.
Add the library to your project through Composer or clone this repository and autoload it via the included PSR-4 configuration.
Getting Started
Instantiate the message bus, context, and orchestrator. Register automata that implement Automata\Contracts\AutomatonInterface and return a Automata\Core\CycleResponse, then start the orchestrator using the identifier of the initial FSM automaton.
<?php use Automata\Core\Context\ArrayContext; use Automata\Core\Orchestrator; use Automata\Contracts\AutomatonInterface; use Automata\Contracts\ContextInterface; use Automata\Contracts\InputInterface; use Automata\Core\CycleRequest; use Automata\Core\CycleResponse; $context = new ArrayContext(); $automaton = new class implements AutomatonInterface { public function getId(): string { return 'demo.automaton'; } public function onEnter(ContextInterface $context): void { /* setup */ } public function process(CycleRequest $request): CycleResponse { $context = $request->getContext(); // business logic mutating $context or reading $request->getInput()... return new CycleResponse(); // chain ->withCommand()/->withEvent() to enqueue messages } public function onLeave(ContextInterface $context): void { /* cleanup */ } }; $orchestrator = new Orchestrator($context); $orchestrator->registerState($automaton); $orchestrator->activate('demo.automaton'); $orchestrator->tick(new class implements InputInterface {});
Snapshots of automata and context state can be captured with Orchestrator::snapshot() and later reapplied using Orchestrator::activateFromSnapshot() to support persistence or time-travel debugging.
// Capture a snapshot for later recovery $snapshot = $orchestrator->snapshot(); // ...later, possibly in a different process $restoredContext = new ArrayContext(); $restoredOrchestrator = new Orchestrator($restoredContext); $restoredOrchestrator->registerState($automaton); $restoredOrchestrator->activateFromSnapshot($snapshot); // Continue processing with the same automaton after restoring $restoredOrchestrator->tick(new class implements InputInterface {});
Traffic Light Example
The examples/traffic-light directory contains a self-contained CLI simulation that demonstrates:
- three color-specific automata coordinating through transitions
- a middleware counting completed ticks
- command and event dispatch coordinated via
CycleResponse
Run the demo after installing dependencies:
php examples/traffic-light/run.php
A sample run prints the state changes and demonstrates snapshot/restore:
=== Initial execution ===
[2025-10-11 10:25:56] Traffic light changed from RED to GREEN
State -> color=GREEN | total_ticks=2 (even)
State -> color=GREEN | total_ticks=3 (odd)
[2025-10-11 10:25:56] Traffic light changed from GREEN to YELLOW
State -> color=YELLOW | total_ticks=4 (even)
State -> color=YELLOW | total_ticks=5 (odd)
=== Snapshot saved after tick 4 (active automaton: traffic_light.yellow) ===
=== Restored execution ===
State -> color=YELLOW | total_ticks=6 (even)
[2025-10-11 10:25:56] Traffic light changed from YELLOW to RED
State -> color=RED | total_ticks=7 (odd)
[2025-10-11 10:25:56] Traffic light changed from RED to GREEN
State -> color=GREEN | total_ticks=8 (even)
State -> color=GREEN | total_ticks=9 (odd)
Simulation complete.
Testing
composer test
License
This project is released under the MIT License. See LICENSE for details.