mirror of
https://github.com/robonen/tools.git
synced 2026-03-20 02:44:45 +00:00
Merge pull request #127 from robonen/stdlib-fix-reusing
refactor(core/stdlib): update state machine classes to use consistent property names and improve type safety
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import { isString } from '../../../types';
|
||||||
import { BaseStateMachine } from './base';
|
import { BaseStateMachine } from './base';
|
||||||
import type { AsyncStateNodeConfig, ExtractStates, ExtractEvents } from './types';
|
import type { AsyncStateNodeConfig, ExtractStates, ExtractEvents } from './types';
|
||||||
|
|
||||||
@@ -24,33 +25,33 @@ export class AsyncStateMachine<
|
|||||||
* @returns The current state after processing the event
|
* @returns The current state after processing the event
|
||||||
*/
|
*/
|
||||||
async send(event: Events): Promise<States> {
|
async send(event: Events): Promise<States> {
|
||||||
const stateNode = this._states[this._current];
|
const stateNode = this.states[this.currentState];
|
||||||
|
|
||||||
if (!stateNode?.on)
|
if (!stateNode?.on)
|
||||||
return this._current;
|
return this.currentState;
|
||||||
|
|
||||||
const transition = stateNode.on[event];
|
const transition = stateNode.on[event];
|
||||||
|
|
||||||
if (transition === undefined)
|
if (transition === undefined)
|
||||||
return this._current;
|
return this.currentState;
|
||||||
|
|
||||||
let target: string;
|
let target: string;
|
||||||
|
|
||||||
if (typeof transition === 'string') {
|
if (isString(transition)) {
|
||||||
target = transition;
|
target = transition;
|
||||||
} else {
|
} else {
|
||||||
if (transition.guard && !(await transition.guard(this._context)))
|
if (transition.guard && !(await transition.guard(this.context)))
|
||||||
return this._current;
|
return this.currentState;
|
||||||
|
|
||||||
await transition.action?.(this._context);
|
await transition.action?.(this.context);
|
||||||
target = transition.target;
|
target = transition.target;
|
||||||
}
|
}
|
||||||
|
|
||||||
await stateNode.exit?.(this._context);
|
await stateNode.exit?.(this.context);
|
||||||
this._current = target as States;
|
this.currentState = target as States;
|
||||||
await this._states[this._current]?.entry?.(this._context);
|
await this.states[this.currentState]?.entry?.(this.context);
|
||||||
|
|
||||||
return this._current;
|
return this.currentState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,7 +60,7 @@ export class AsyncStateMachine<
|
|||||||
* @param event - Event to check
|
* @param event - Event to check
|
||||||
*/
|
*/
|
||||||
async can(event: Events): Promise<boolean> {
|
async can(event: Events): Promise<boolean> {
|
||||||
const stateNode = this._states[this._current];
|
const stateNode = this.states[this.currentState];
|
||||||
|
|
||||||
if (!stateNode?.on)
|
if (!stateNode?.on)
|
||||||
return false;
|
return false;
|
||||||
@@ -69,8 +70,8 @@ export class AsyncStateMachine<
|
|||||||
if (transition === undefined)
|
if (transition === undefined)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (typeof transition !== 'string' && transition.guard)
|
if (!isString(transition) && transition.guard)
|
||||||
return await transition.guard(this._context);
|
return await transition.guard(this.context);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,28 +12,25 @@ export class BaseStateMachine<
|
|||||||
Context,
|
Context,
|
||||||
NodeConfig,
|
NodeConfig,
|
||||||
> {
|
> {
|
||||||
protected _current: States;
|
protected currentState: States;
|
||||||
protected _context: Context;
|
protected readonly states: Record<string, NodeConfig>;
|
||||||
protected _states: Record<string, NodeConfig>;
|
|
||||||
|
/** Machine context */
|
||||||
|
readonly context: Context;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
initial: States,
|
initial: States,
|
||||||
states: Record<string, NodeConfig>,
|
states: Record<string, NodeConfig>,
|
||||||
context: Context,
|
context: Context,
|
||||||
) {
|
) {
|
||||||
this._current = initial;
|
this.currentState = initial;
|
||||||
this._context = context;
|
this.context = context;
|
||||||
this._states = states;
|
this.states = states;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Current state of the machine */
|
/** Current state of the machine */
|
||||||
get current(): States {
|
get current(): States {
|
||||||
return this._current;
|
return this.currentState;
|
||||||
}
|
|
||||||
|
|
||||||
/** Machine context */
|
|
||||||
get context(): Context {
|
|
||||||
return this._context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,6 +39,6 @@ export class BaseStateMachine<
|
|||||||
* @param state - State to check
|
* @param state - State to check
|
||||||
*/
|
*/
|
||||||
matches(state: States): boolean {
|
matches(state: States): boolean {
|
||||||
return this._current === state;
|
return this.currentState === state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { isString } from '../../../types';
|
||||||
import { BaseStateMachine } from './base';
|
import { BaseStateMachine } from './base';
|
||||||
import type { SyncStateNodeConfig, ExtractStates, ExtractEvents } from './types';
|
import type { SyncStateNodeConfig, ExtractStates, ExtractEvents } from './types';
|
||||||
|
|
||||||
@@ -24,33 +25,33 @@ export class StateMachine<
|
|||||||
* @returns The current state after processing the event
|
* @returns The current state after processing the event
|
||||||
*/
|
*/
|
||||||
send(event: Events): States {
|
send(event: Events): States {
|
||||||
const stateNode = this._states[this._current];
|
const stateNode = this.states[this.currentState];
|
||||||
|
|
||||||
if (!stateNode?.on)
|
if (!stateNode?.on)
|
||||||
return this._current;
|
return this.currentState;
|
||||||
|
|
||||||
const transition = stateNode.on[event];
|
const transition = stateNode.on[event];
|
||||||
|
|
||||||
if (transition === undefined)
|
if (transition === undefined)
|
||||||
return this._current;
|
return this.currentState;
|
||||||
|
|
||||||
let target: string;
|
let target: string;
|
||||||
|
|
||||||
if (typeof transition === 'string') {
|
if (isString(transition)) {
|
||||||
target = transition;
|
target = transition;
|
||||||
} else {
|
} else {
|
||||||
if (transition.guard && !transition.guard(this._context))
|
if (transition.guard && !transition.guard(this.context))
|
||||||
return this._current;
|
return this.currentState;
|
||||||
|
|
||||||
transition.action?.(this._context);
|
transition.action?.(this.context);
|
||||||
target = transition.target;
|
target = transition.target;
|
||||||
}
|
}
|
||||||
|
|
||||||
stateNode.exit?.(this._context);
|
stateNode.exit?.(this.context);
|
||||||
this._current = target as States;
|
this.currentState = target as States;
|
||||||
this._states[this._current]?.entry?.(this._context);
|
this.states[this.currentState]?.entry?.(this.context);
|
||||||
|
|
||||||
return this._current;
|
return this.currentState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,7 +60,7 @@ export class StateMachine<
|
|||||||
* @param event - Event to check
|
* @param event - Event to check
|
||||||
*/
|
*/
|
||||||
can(event: Events): boolean {
|
can(event: Events): boolean {
|
||||||
const stateNode = this._states[this._current];
|
const stateNode = this.states[this.currentState];
|
||||||
|
|
||||||
if (!stateNode?.on)
|
if (!stateNode?.on)
|
||||||
return false;
|
return false;
|
||||||
@@ -69,8 +70,8 @@ export class StateMachine<
|
|||||||
if (transition === undefined)
|
if (transition === undefined)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (typeof transition !== 'string' && transition.guard)
|
if (!isString(transition) && transition.guard)
|
||||||
return transition.guard(this._context);
|
return transition.guard(this.context);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user