import type * as HKT from "@principia/prelude/HKT"; import type { Sync } from "../Sync"; import { _A, _E, _I, _R, _U, TaskInstructionTag } from "../Task/Task/constants"; import type * as T from "../Task/Task/model"; import type * as Ex from "./AsyncExit"; import { _AI, AsyncInstructionTag } from "./constants"; import { asyncIntegrationNotImplemented, asyncTaskIntegration } from "./integration"; export abstract class Async implements T.Integration { readonly _tag = TaskInstructionTag.Integration; readonly _S1!: (_: unknown) => void; readonly _S2!: () => never; readonly [_U]!: T.URI; readonly [_R]!: (_: R) => void; readonly [_E]!: () => E; readonly [_A]!: () => A; get [_I](): T.Instruction { const ai = asyncTaskIntegration.get; if (ai._tag === "Some") { return ai.value(this)[_I]; } return asyncIntegrationNotImplemented; } get [_AI](): AsyncInstruction { return this as any; } } export const URI = "Async"; export type URI = typeof URI; export type V = HKT.V<"R", "-"> & HKT.V<"E", "+">; declare module "@principia/prelude/HKT" { interface URItoKind { readonly [URI]: Async; } } export type AsyncInstruction = | SucceedInstruction | SuspendInstruction | PromiseInstruction | ChainInstruction | FoldInstruction | AsksInstruction | DoneInstruction | GiveInstruction | FinalizeInstruction | AllInstruction | FailInstruction | TotalInstruction | PartialInstruction | Sync; export class SucceedInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Succeed; constructor(readonly value: A) { super(); } } export class TotalInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Total; constructor(readonly thunk: () => A) { super(); } } export class PartialInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Partial; constructor(readonly thunk: () => A, readonly onThrow: (error: unknown) => E) { super(); } } export class DoneInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Done; constructor(readonly exit: Ex.AsyncExit) { super(); } } export class FailInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Fail; constructor(readonly e: E) { super(); } } export class AsksInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Asks; constructor(readonly f: (_: R0) => Async) { super(); } } export class GiveInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Give; constructor(readonly async: Async, readonly env: R) { super(); } } export class AllInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.All; constructor(readonly asyncs: readonly Async[]) { super(); } } export class SuspendInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Suspend; constructor(readonly async: () => Async) { super(); } } export class PromiseInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Promise; constructor( readonly promise: (onInterrupt: (f: () => void) => void) => Promise, readonly onReject: (reason: unknown) => E ) { super(); } } export class ChainInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Chain; constructor(readonly async: Async, readonly f: (a: A) => Async) { super(); } } export class FoldInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Fold; constructor( readonly async: Async, readonly f: (e: E) => Async, readonly g: (a: A) => Async ) { super(); } } export class FinalizeInstruction extends Async { readonly _asyncTag = AsyncInstructionTag.Finalize; constructor(readonly async: Async, readonly f: () => Async) { super(); } }