import { Resume } from '@typed/env' import { Capabilities, Effects, Return } from '../Effect' import { fail } from '../failures' import { runEffects } from '../run/runEffects' import { createFiber } from './createFiber' import { Fiber, FiberFailure, FiberState } from './Fiber' export type Fork = { readonly fork: ( effect: A, c: Capabilities & FiberFailure, ) => Resume>> } export const Fork = { fork: (effect: A, c: Capabilities & FiberFailure) => { const fiber = createFiber>() function* tryRunEffect() { try { fiber.info = { state: FiberState.Returned, value: yield* effect } } catch (error) { fiber.info = { state: FiberState.Error, error } yield* fail(FiberFailure, error) } } fiber.addDisposable(runEffects(tryRunEffect(), c)) return Resume.of(fiber) }, } export function* fork( effect: A, ): Effects & Fork & FiberFailure, Fiber>> { return yield (c: Capabilities & FiberFailure & Fork) => c.fork(effect, c) }