import { Disposable } from '@typed/disposable' import { Env, provide, Pure, Resume, runPure } from '@typed/env' import { CombinedCapabilities, Effect, Return } from '../Effect' import { runEffect } from '../run' export function* race>>( ...effects: E ): Effect, Return>, Return> { const env: Env, Return> = (c: CombinedCapabilities) => Resume.create>((cb) => { const disposable = Disposable.lazy() const ifNotResolved = createIfNotResolved>(cb, disposable) for (const effect of effects) { const pure = provide(runEffect(effect), c as any) as Pure> disposable.addDisposable(runPure(ifNotResolved, pure)) } return disposable }) return yield env } function createIfNotResolved(cb: (value: A) => Disposable, disposable: Disposable) { let resolved = false return (value: A) => { if (!resolved) { resolved = true disposable.dispose() return cb(value) } return Disposable.None } }