Task
Durable task definitions. A task is a state machine whose checkpoint is a Schema tagged union, with one handler per
tag. A handler advances the task only by committing through TaskRuntime.commit, atomically with the entries, state
and child tasks it wrote. There is no replay of a function body: after a crash the task re-enters the handler of its
last committed checkpoint.
import { Next, Task, TaskRuntime } from "@effective-harness/core"import * as Effect from "effect/Effect"import * as Schema from "effect/Schema"
const Payment = Task.make("app.payment", { version: 1, input: Schema.Struct({ card: Schema.String }), checkpoint: Schema.TaggedUnion({ Charge: {} }), initial: () => ({ _tag: "Charge" }), phases: { Charge: (task) => TaskRuntime.commit(Effect.succeed(Next.complete({ card: task.input.card }))) }, abort: () => TaskRuntime.commit(Effect.succeed(Next.aborted()))})Since v0.0.0
Any (type alias)
Section titled “Any (type alias)”A task definition of any shape, as the registry holds it.
Signature
type Any = Task<any, any, any>Since v0.0.0
Checkpoint (interface)
Section titled “Checkpoint (interface)”Any checkpoint: a tagged union member.
Signature
export interface Checkpoint { readonly _tag: string}Since v0.0.0
CheckpointOf (type alias)
Section titled “CheckpointOf (type alias)”The checkpoint union of a task.
Signature
type CheckpointOf<T extends Any> = T extends Task<any, infer C, any> ? C : neverSince v0.0.0
Input (type alias)
Section titled “Input (type alias)”The input type of a task.
Signature
type Input<T extends Any> = T extends Task<infer I, any, any> ? I : neverSince v0.0.0
Options (interface)
Section titled “Options (interface)”Signature
export interface Options<I, C extends Checkpoint, R> { /** Positive integer version of the stored input and checkpoint shapes. */ readonly version: number readonly input: Schema.Codec<I, any, never, never> /** A `Schema.TaggedUnion` of the task's phases. */ readonly checkpoint: Schema.Codec<C, any, never, never> /** Codec of the completed result; defaults to any JSON value. */ readonly result?: Schema.Codec<R, any, never, never> /** The first checkpoint of a new task. */ readonly initial: (input: I) => NoInfer<C> readonly phases: Phases<I, C> /** * Runs once, after the task's ordinary owned work is gone, when the task has an abort mark. It must commit a * terminal outcome, usually `Next.aborted()`; returning without one faults the task. It cannot wait. Default: commit * `Next.aborted()`, for tasks with nothing to undo. */ readonly abort?: (task: RunningTask<I, C>) => Effect.Effect<void, unknown, TaskRuntime> /** * Convert a task stored by an older version, given its encoded input and checkpoint. Runs at reservation. If it * throws, the task stays blocked. */ readonly migrate?: ( input: Json, checkpoint: Json, fromVersion: number ) => { readonly input: NoInfer<I>; readonly checkpoint: NoInfer<C> }}Since v0.0.0
PhaseHandler (type alias)
Section titled “PhaseHandler (type alias)”One phase of a task. Failing, or dying, faults the task; so does returning without committing progress.
Signature
type PhaseHandler<I, C> = (task: RunningTask<I, C>) => Effect.Effect<void, unknown, TaskRuntime>Since v0.0.0
Phases (type alias)
Section titled “Phases (type alias)”One handler per checkpoint tag; a missing tag is a type error.
Signature
type Phases<I, C extends Checkpoint> = { readonly [K in C["_tag"]]: PhaseHandler<I, Extract<C, { readonly _tag: K }>>}Since v0.0.0
Result (type alias)
Section titled “Result (type alias)”The result type of a task.
Signature
type Result<T extends Any> = T extends Task<any, any, infer R> ? R : neverSince v0.0.0
RunningTask (interface)
Section titled “RunningTask (interface)”The committed record of a running task, with its input and checkpoint decoded.
Signature
export interface RunningTask<I, C> { readonly id: TaskId readonly conversationId: ConversationId readonly kind: string readonly version: number readonly input: I /** Owning task of a child task; absent for a task its conversation owns. */ readonly owner?: TaskId readonly background: boolean readonly abortRequested: boolean readonly checkpoint: C readonly memos?: { readonly [name: string]: Json }}Since v0.0.0
Task (interface)
Section titled “Task (interface)”A task definition.
Signature
export interface Task<I, C extends Checkpoint, R> extends Options<I, C, R> { readonly [TypeId]: typeof TypeId readonly name: string readonly result: Schema.Codec<R, any, never, never> readonly abort: (task: RunningTask<I, C>) => Effect.Effect<void, unknown, TaskRuntime> /** @internal JSON codecs of the stored shapes. */ readonly codecs: { readonly input: Schema.Codec<I, Json> readonly checkpoint: Schema.Codec<C, Json> readonly result: Schema.Codec<R, Json> }}Since v0.0.0
TypeId
Section titled “TypeId”Signature
declare const TypeId: "~@effective-harness/core/Task"Since v0.0.0
Wait for a task’s outcome, whatever it is: completed, failed, aborted, orphaned or faulted. Interrupting
the caller only stops the wait. Fails with TaskNotFound for an unknown task.
Signature
declare const await: ( id: TaskId) => Effect.Effect<TaskOutcome, TaskNotFound | SchedulerClosed | StorageFailure | SessionPoisoned, Scheduler>Since v0.0.0
The committed task record; None for an unknown ID. Never starts scheduling.
Signature
declare const get: (id: TaskId) => Effect.Effect<Option.Option<TaskRecord>, StorageFailure | SessionPoisoned, Session>Since v0.0.0
isTask
Section titled “isTask”Signature
declare const isTask: (value: unknown) => value is AnySince v0.0.0
Define a task.
Signature
declare const make: <I, const C extends Checkpoint, R = Schema.Json>( name: string, options: Options<I, C, R>) => Task<I, C, R>Since v0.0.0