import * as Sy from "../../Sync"; import type { Exit } from "../Exit"; import type { Cause } from "../Exit/Cause"; import * as C from "../Exit/Cause"; import type { FiberStatus } from "./status"; import { Done, Running } from "./status"; export type FiberState = FiberStateExecuting | FiberStateDone; export type Callback = (exit: Exit) => void; export class FiberStateExecuting { readonly _tag = "Executing"; constructor( readonly status: FiberStatus, readonly observers: Callback>[], readonly interrupted: Cause ) {} } export class FiberStateDone { readonly _tag = "Done"; readonly interrupted = C.empty; readonly status: FiberStatus = new Done(); constructor(readonly value: Exit) {} } export const initial = (): FiberState => new FiberStateExecuting(new Running(false), [], C.empty); export const interrupting = (state: FiberState): boolean => { const loop = (status: FiberStatus): Sy.Sync => Sy.gen(function* (_) { switch (status._tag) { case "Running": { return status.interrupting; } case "Finishing": { return status.interrupting; } case "Suspended": { return yield* _(loop(status.previous)); } case "Done": { return false; } } }); return Sy.runIO(loop(state.status)); };