| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- export type StateHandler<TState extends string> = () => Promise<TState | null>;
- export interface StateTransition<TState extends string> {
- from: TState | null;
- to: TState;
- }
- /**
- * 顺序异步状态机。
- *
- * 每个状态完成后返回下一个状态,返回 null 表示流程结束。
- * 状态处理器抛出的异常由调用方决定如何进入失败状态。
- */
- export class AsyncStateMachine<TState extends string> {
- private readonly handlers = new Map<TState, StateHandler<TState>>();
- private currentState: TState | null = null;
- private running = false;
- constructor(
- private readonly onTransition?: (transition: StateTransition<TState>) => void,
- ) { }
- get current(): TState | null {
- return this.currentState;
- }
- register(state: TState, handler: StateHandler<TState>): this {
- if (this.handlers.has(state)) {
- throw new Error(`State already registered: ${state}`);
- }
- this.handlers.set(state, handler);
- return this;
- }
- async start(initialState: TState): Promise<void> {
- if (this.running) {
- throw new Error('State machine is already running');
- }
- this.running = true;
- try {
- let nextState: TState | null = initialState;
- while (nextState !== null) {
- nextState = await this.execute(nextState);
- }
- } finally {
- this.running = false;
- }
- }
- async transition(state: TState): Promise<TState | null> {
- if (this.running) {
- throw new Error('Cannot transition manually while state machine is running');
- }
- return this.execute(state);
- }
- private async execute(state: TState): Promise<TState | null> {
- const handler = this.handlers.get(state);
- if (!handler) {
- throw new Error(`State is not registered: ${state}`);
- }
- const previous = this.currentState;
- this.currentState = state;
- this.onTransition?.({ from: previous, to: state });
- return handler();
- }
- }
|