import {isPointer, valueDerivation} from '../Atom' import type {Pointer} from '../pointer' import type {IDerivation} from './IDerivation' import {isDerivation} from './IDerivation' export default function* iterateAndCountTicks( pointerOrDerivation: IDerivation | Pointer, ): Generator<{value: V; ticks: number}, void, void> { let d if (isPointer(pointerOrDerivation)) { d = valueDerivation(pointerOrDerivation) as IDerivation } else if (isDerivation(pointerOrDerivation)) { d = pointerOrDerivation } else { throw new Error(`Only pointers and derivations are supported`) } let ticksCountedSinceLastYield = 0 const untap = d.changesWithoutValues().tap(() => { ticksCountedSinceLastYield++ }) try { while (true) { const ticks = ticksCountedSinceLastYield ticksCountedSinceLastYield = 0 yield {value: d.getValue(), ticks} } } finally { untap() } }