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 machinerImporting
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
debugSubjectprovides real-time debug events.machineInfoSubjectstreams 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
invokeoperations. - 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
trueand 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.
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago