FSM Usage
FSMContextManager
FSMContextManager is a service class that should receive a Disposable owner via dependency injection, not extend ViewModel. The owner is responsible for cleanup of subscriptions.
Class Definition
class FSMContextManager<
TConfig extends FSMStateConfig<PropertyKey, unknown>,
TSelf extends FSMContextManager<TConfig, TSelf>
> {
constructor(
owner: Disposable,
currentStatePort: StatePort<FSMContextState<TSelf>>
);
initialize(): Promise<TSelf>;
dispatch<T extends keyof TConfig>(payload: TConfig[T]): Promise<void>;
transitionTo(state: FSMContextState<TSelf>): Promise<void>;
get currentState(): StatePort<FSMContextState<TSelf>>;
}
Usage Example
In a React Component
import { useCreateStatePort, useReactiveValue, useViewModel } from '@xndrjs/adapter-react';
import { ViewModel, type StatePort } from '@xndrjs/core';
import { FSMContextManager, type FSMContextState } from '@xndrjs/fsm';
// Define your FSM
class MyFSM extends FSMContextManager<MyConfig, MyFSM> {
constructor(
owner: Disposable,
currentStatePort: StatePort<FSMContextState<MyFSM>>
) {
super(owner, currentStatePort);
// Use owner for computed values
this.someComputed = createComputed(...)
.as(...)
.for(owner);
}
}
// Create a ViewModel wrapper
class MyFSMViewModel extends ViewModel {
readonly fsm: MyFSM;
constructor(currentStatePort: StatePort<FSMContextState<MyFSM>>) {
super();
this.fsm = new MyFSM(this, currentStatePort);
this.fsm.initialize();
}
}
// Use in component
function MyComponent() {
const currentStatePort = useCreateStatePort(initialState);
const vm = useViewModel(() => new MyFSMViewModel(currentStatePort));
const fsm = vm.fsm;
const currentState = useReactiveValue(fsm.currentState);
return <div>Current state: {currentState.name}</div>;
}
Key Points
FSMContextManageris a service, not a ViewModel- It receives a
Disposableowner via dependency injection - Wrap it in a
ViewModelin your component for automatic lifecycle management - Use the owner for
.for(owner)when creating computed values