Last active
March 5, 2022 02:36
-
-
Save serrg/e794b30b8dc3ebee29b096770f075b1c to your computer and use it in GitHub Desktop.
simple state machine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Transition { | |
name: string; | |
from: string; | |
to: string; | |
} | |
export interface Action { | |
[actionName: string]: () => void; | |
} | |
interface State { | |
init: string; | |
transitions: Transition[]; | |
actions: Action; | |
} | |
interface Machine { | |
definition: State, | |
state: string, | |
action: (actionName: string) => string | |
} | |
function createMachine<F extends State>(stateDefinition: F): Machine { | |
const machine = { | |
definition: stateDefinition, | |
state: stateDefinition.init, | |
action(actionName: string): string { | |
const destinationState: string | undefined = | |
this.definition.transitions.find( | |
(transition: Transition) => transition.name === actionName)?.to; | |
const action = this.definition.actions[actionName]; | |
typeof action === "function" && action(); | |
this.state = destinationState ?? this.state; | |
return this.state; | |
} | |
}; | |
return machine; | |
} | |
const machine: Machine = createMachine<State>({ | |
init: "idle", | |
transitions: [ | |
{ name: "start", from: "idle", to: "pending" }, | |
{ name: "success", from: "pending", to: "fulfilled" }, | |
{ name: "failure", from: "pending", to: "rejected" } | |
], | |
actions: { | |
start: () => { | |
console.log("action started"); | |
}, | |
success: () => { | |
console.log("action successed"); | |
}, | |
failure: () => { | |
console.log("action failured"); | |
} | |
} | |
}); | |
machine.state; // state: idle | |
machine.action("start"); // action started, state: pending | |
machine.action("success"); // action successed, state: fulfilled | |
machine.action("failure"); // action failured, state: rejected |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment