import * as asyncModule from "async" import { Executor, ExecutorBuilder, Evaluatable } from "./executor" import { Aggregator } from "./aggregator"; import { Topology } from "./topology"; import { ValueProvider } from "./valueProvider" export type RollEvals = { [K in keyof TInfo]: ValueProvider } type ResultOfEvaluator> = { [K in keyof TEvals]: RollEvalResult } type RollEvalResult> = T extends ValueProvider ? IResult : never export class Roll { constructor(public readonly routines: RollEvals) { } setRoutine(routine: RollEvals) { } go(callback: (err?: any, result?: TInfo, phase?: string) => void) { let keys = Object.keys(this.routines) let info: TInfo = {} as TInfo let phase = null asyncModule.eachSeries(keys, (key, done) => { let todo = this.routines[key] let _done = done let protect = false if (this.isDebug) { console.log(`At ${key}`) } phase = key done = (...args: any[]) => { if (protect) { console.trace() console.error("Multiple routine called") throw new Error("Multiple routine called") return } protect = true _done(...args) } try { ValueProvider.get(info, todo, (err, result) => { if (err) { done(err) return } info[key] = result done() }) } catch (e) { done(e) } }, (err) => { callback(err, info, phase) }) return this } private isDebug = false debug() { this.isDebug = !this.isDebug return this } }