import { Chain } from './Chain'; import * as Guard from './Guard'; import { Step } from './Step'; const defaultAmount = 3000; const defaultInterval = 10; const toStep = (p: (input: T) => R): Step => Step.stateful((input, next) => { next(p(input)); }); const sTryUntilPredicate = (label: string, p: (value: T) => boolean, interval: number = defaultInterval, amount: number = defaultAmount): Step => sTryUntil(label, Step.predicate(p), interval, amount); const sTryUntil = (label: string, step: Step, interval: number = defaultInterval, amount: number = defaultAmount): Step => Step.control(step, Guard.tryUntil(label, interval, amount)); const sTryUntilNot = (label: string, step: Step, interval: number = defaultInterval, amount: number = defaultAmount): Step => Step.control(step, Guard.tryUntilNot(label, interval, amount)); const sTimeout = (label: string, step: Step, limit: number = defaultAmount): Step => Step.control(step, Guard.timeout(label, limit)); const cTryUntilPredicate = (label: string, p: (value: T) => boolean, interval: number = defaultInterval, amount: number = defaultAmount): Chain => cTryUntil(label, Chain.predicate(p), interval, amount); const cTryUntil = (label: string, chain: Chain, interval: number = defaultInterval, amount: number = defaultAmount): Chain => Chain.control(chain, Guard.tryUntil(label, interval, amount)); const cTryUntilNot = (label: string, chain: Chain, interval: number = defaultInterval, amount: number = defaultAmount): Chain => Chain.control(chain, Guard.tryUntilNot(label, interval, amount)); const cTimeout = (label: string, chain: Chain, limit: number = defaultAmount): Chain => Chain.control(chain, Guard.timeout(label, limit)); const pTryUntilPredicate = (label: string, p: () => boolean, interval: number = defaultInterval, amount: number = defaultAmount): Promise => Step.toPromise(sTryUntilPredicate(label, p, interval, amount))(undefined); const pTryUntil = (label: string, p: () => R, interval: number = defaultInterval, amount: number = defaultAmount): Promise => Step.toPromise(sTryUntil(label, toStep(p), interval, amount))(undefined); const pTryUntilNot = (label: string, p: () => R, interval: number = defaultInterval, amount: number = defaultAmount): Promise => Step.toPromise(sTryUntilNot(label, Step.sync(p), interval, amount))(undefined); const pTimeout = (label: string, p: () => R, limit: number = defaultAmount): Promise => Step.toPromise(sTimeout(label, toStep(p), limit))(undefined); const pWait = (time: number): Promise => Step.toPromise(Step.wait(time))(undefined); const pWaitBetweenUserActions = (): Promise => // a real user won't perform multiple actions within a single frame, so we shouldn't either. // 17ms was chosen instead of requestAnimationFrame() because we want at least one full frame to complete between now and the next action. pWait(17); export { sTryUntilPredicate, sTryUntil, sTryUntilNot, sTimeout, cTryUntilPredicate, cTryUntil, cTryUntilNot, cTimeout, pTryUntilPredicate, pTryUntil, pTryUntilNot, pTimeout, pWait, pWaitBetweenUserActions };