55 lines
1.4 KiB
JavaScript
55 lines
1.4 KiB
JavaScript
// core/state-machine.js
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
class StateMachine {
|
|
constructor(statesPath) {
|
|
this.statesPath = statesPath;
|
|
this.states = new Map();
|
|
this.currentState = null;
|
|
this.loadStates();
|
|
}
|
|
|
|
loadStates() {
|
|
const files = fs.readdirSync(this.statesPath);
|
|
for (const file of files) {
|
|
if (file.endsWith('.js')) {
|
|
const stateName = path.basename(file, '.js');
|
|
const stateModule = require(path.join(this.statesPath, file));
|
|
this.states.set(stateName, stateModule);
|
|
}
|
|
}
|
|
}
|
|
|
|
async run(initialState) {
|
|
if (!this.states.has(initialState)) {
|
|
throw new Error(`Initial state '${initialState}' not found.`);
|
|
}
|
|
this.currentState = initialState;
|
|
await this.executeCurrent();
|
|
}
|
|
|
|
async transition(nextState) {
|
|
if (!this.states.has(nextState)) {
|
|
console.warn(`State '${nextState}' not found. Ignoring.`);
|
|
return;
|
|
}
|
|
this.currentState = nextState;
|
|
await this.executeCurrent();
|
|
}
|
|
|
|
async executeCurrent() {
|
|
const stateFn = this.states.get(this.currentState);
|
|
if (typeof stateFn !== 'function') {
|
|
console.warn(`State '${this.currentState}' is not executable.`);
|
|
return;
|
|
}
|
|
try {
|
|
await stateFn();
|
|
} catch (err) {
|
|
console.error(`Error executing state '${this.currentState}':`, err);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = { StateMachine };
|