Created
April 22, 2025 22:26
-
-
Save solanoepalacio/3b02cee4eb5c7ce376747665286287f6 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
type StepId = string; | |
interface StateMachineOptions { | |
steps: Step[]; | |
} | |
interface MachineIteratorInterface { | |
step: Step; | |
state: Record<StepId, StepState>; | |
} | |
interface StepState { | |
executed: boolean; | |
error?: string; // ? | |
result?: string; // this would be tied to the ExecutionStep.type | |
} | |
// this would be ExecutionStep that already exists on the sdk. | |
interface Step { | |
id: StepId; | |
tx: string; // this will be a very complex type depending on the platform and so on... but just using "string" just for the poc example. | |
} | |
export class AsyncStateMachine implements AsyncIterable<MachineIteratorInterface> { | |
private currentIndex = 0; | |
private steps: Step[]; | |
private state: Record<StepId, StepState>; | |
constructor(private options: StateMachineOptions) { | |
this.steps = options.steps; | |
this.state = Object.fromEntries(options.steps.map(s => [s.id, { executed: false }])); | |
} | |
completeStep(step: Step, result: string) { | |
this.state = { | |
...this.state, | |
[step.id]: { | |
executed: true, | |
result, | |
} | |
} | |
}; | |
async next(): Promise<IteratorResult<MachineIteratorInterface>> { | |
if (this.currentIndex >= this.steps.length) { | |
return { value: undefined, done: true }; | |
} | |
const step = this.steps[this.currentIndex]; | |
this.currentIndex++; | |
return { | |
value: { | |
state: this.state, | |
step | |
}, | |
done: false | |
}; | |
} | |
[Symbol.asyncIterator](): AsyncIterator<MachineIteratorInterface> { | |
return this; | |
} | |
} | |
(async function run () { | |
const steps = [ | |
{ id: "1", tx: "transaction-1" }, | |
{ id: "2", tx: "transaction-2" }, | |
{ id: "3", tx: "transaction-3" }, | |
]; | |
const workflow = new AsyncStateMachine({ steps }); | |
for await (const { state, step } of workflow) { | |
console.log(`Executing step ${step.id} transaction: ${step.tx}`); | |
if (step.id === "2") { | |
console.log("Because I'm in step 2 I'll require the result of step 2"); | |
console.log("Which is: ", state["1"].result); | |
} | |
workflow.completeStep(step, `TX ${step.id} executed successfully`); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment