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)
}