machiner v1.0.16
Machiner Documentation
Overview
The machiner
library is a TypeScript implementation of a typed state machine designed to handle complex workflows, time-based actions, service orchestration, debugging, and persistence. It provides a robust framework for managing state transitions with guards, actions, delayed executions, intervals, and cron jobs.
Getting Started
Installation
To install the library using npm:
npm install machiner
Importing
In your TypeScript project, import the necessary modules:
import { TypedStateMachine } from 'machiner';
Example Usage
Here's a simple example of creating and running a state machine:
import { TypedStateMachine } from 'machiner';
interface Context {
count: number;
}
type Events = 'increment' | 'reset';
interface Payloads {
increment: { amount: number };
reset: {};
}
const config = {
id: 'counter',
initial: 'active' as const,
context: { count: 0 } as Context,
states: {
active: {
id: 'active',
on: {
increment: {
actions: [
(context, event) => ({
count: context.count + event.data.amount
})
],
target: 'active'
},
reset: {
actions: [
() => ({
count: 0
})
],
target: 'active'
}
},
entry: [
(context, event) => {
console.log('Entering active state. Current count:', context.count);
}
]
}
}
};
const machine = TypedStateMachine.create<Events, Context, Payloads>(config);
machine.send({ type: 'increment', data: { amount: 5 } });
// Current state stays active, count becomes 5
machine.waitForState(['active']).then(({ state, context }) => {
console.log('Machine is in state:', state);
console.log('Current count:', context.count);
});
Core Concepts
States
A state defines the current situation of the machine. Each state can have:
- Transitions (on): Defined for events, which may include guards and actions.
- Entry/Exit Actions: Actions triggered when entering or exiting the state.
- Delayed Transitions (after): Execute after a delay.
- Intervals: Actions executed periodically.
- Cron Jobs: Actions executed based on a cron schedule.
- Services/Machines (invoke): Invoking external services or other state machines.
TypedEvents
Each event has a type and optional data, timestamp, and metadata.
Actions and Guards
- Actions: Functions that modify the context or send events.
- Guards: Functions that determine if a transition can occur based on the current state and event.
Advanced Features
Persistence
- Events are saved using a
PersistenceAdapter
, with LocalStorage as the default. - Customize persistence by implementing your own adapter.
Concurrency Handling
- Use an expected version when sending events to prevent race conditions.
Debugging and Monitoring
debugSubject
provides real-time debug events.machineInfoSubject
streams state and context changes.
Error Handling
- Define an error handler in the configuration to handle exceptions during actions or state transitions.
Services and Machines
ServiceInvocation
Define a function that performs an async task, with optional transitions on success or failure.
{
src: async (context, emit) => {
// Service logic here
return result;
},
onDone: {
target: 'doneState',
actions: [/* ... */]
},
onError: {
target: 'errorState',
actions: [/* ... */]
}
}
MachineInvocation
Embed another state machine, with optional input mapping, updates, and transitions on completion.
{
machine: childMachine,
input: (parentContext) => ({ /* child context */ }),
onUpdate: (childState, send) => {
// Handle updates from the child machine
},
onDone: { /* transition */ },
onError: { /* transition */ }
}
Managing Subscriptions
- Track subscriptions created during
invoke
operations. - Clean up resources on disposal to prevent memory leaks.
Real-World Integration
Best Practices
- Keep state definitions modular.
- Use version control for complex state machines.
- Test thoroughly, especially concurrency and error handling.
Performance Considerations
- Optimize loops and avoid heavy computations in actions.
- Monitor RxJS stream performance under high load.
Troubleshooting
Common issues and solutions:
- Concurrency Errors: Ensure expected versions match when sending events in concurrent environments.
- State Transitions Not Firing: Verify guards return
true
and actions don't throw errors blocking transitions. - Persistence Issues: Check adapter implementations for correct event saving and loading.
Conclusion
The machiner
library offers a powerful, flexible solution for managing stateful workflows in TypeScript. By leveraging its advanced features and following best practices, developers can build robust, maintainable applications with complex state management requirements.
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago