Skip to content

Op

Op: object

Defined in: Core/Op.ts:113

interpret: <Args, E, A, O>(op, options) => InterpretResult<Args, E, A, O> = interpretFn

Creates a manager that runs an operation using the selected concurrency strategy.

Args extends readonly unknown[]

E

A

O extends AllInterpretOptions<Args, E>

Op<Args, E, A>

O

InterpretResult<Args, E, A, O>

Op.make to construct an Op blueprint.

const manager = Op.interpret(fetchUser, { strategy: "restartable" });

is: object

idle: <E, A>(state) => state is Idle = isIdle

Type guard that checks if an Op state is Idle.

E = unknown

A = unknown

State<E, A>

state is Idle

  • Op.is.pending to check if an Op is actively executing.
  • Op.is.settled to check if an Op has completed execution.
if (Op.is.idle(manager.state)) {
  console.log("Ready to execute");
}

pending: <E, A>(state) => state is Pending = isPending

Type guard that checks if an Op state is Pending (actively executing).

E = unknown

A = unknown

State<E, A>

state is Pending

  • Op.is.idle to check if an Op is waiting to execute.
  • Op.is.settled to check if an Op has completed execution.
if (Op.is.pending(manager.state)) {
  showSpinner();
}

queued: <E, A>(state) => state is Queued = isQueued

Type guard that checks if an Op state is Queued (waiting in a concurrency queue).

E = unknown

A = unknown

State<E, A>

state is Queued

Op.is.pending to check if an Op is actively executing.

if (Op.is.queued(manager.state)) {
  console.log("Position in queue:", manager.state.position);
}

retrying: <E, A>(state) => state is Retrying<E> = isRetrying

Type guard that checks if an Op state is Retrying after a failure.

E

A

State<E, A>

state is Retrying<E>

Op.is.pending to check if an Op is actively executing.

if (Op.is.retrying(manager.state)) {
  console.log("Retry attempt:", manager.state.attempt);
}

settled: <E, A>(state) => state is Outcome<E, A> = isSettled

Type guard that checks if an Op state has settled into an outcome (Ok, Err, or Nil).

E

A

State<E, A>

state is Outcome<E, A>

  • Op.is.pending to check if an Op is actively executing.
  • Op.is.idle to check if an Op has not yet run.
if (Op.is.settled(manager.state)) {
  console.log("Operation completed with outcome:", manager.state.kind);
}

make: <Args, E, A>(task, options?) => Op<Args, E, A> = makeFn

Turns a task factory into an operation blueprint.

The factory receives the arguments passed to manager.run(...) and returns a Task.Result, so the error channel is already typed before Op sees it. Map raw promises at the boundary with Task.Result.tryCatch; Op never inspects thrown values.

Args extends readonly unknown[]

E

A

(…args) => Result<E, A>

string

Op<Args, E, A>

Op.interpret to attach a concurrency strategy to the blueprint.

const fetchUser = Op.make((id: string) =>
  Task.Result.tryCatch(
    (signal) => fetch(`/users/${id}`, { signal }).then((r) => r.json() as Promise<User>),
    { onError: (error): ApiError => new ApiError(String(error)) },
  )
);

Outcome: object = OpOutcome

Settled outcome value constructors, type guards, eliminators, and combinators.

chain: <A, B, E2>(transform) => <E1>(outcome) => Outcome<E2 | E1, B>

Sequences an operation that produces an Op.Outcome if the current outcome is Ok.

A

B

E2 = never

(value) => Outcome<E2, B>

<E1>(outcome) => Outcome<E2 | E1, B>

Op.Outcome.map to transform the inner value without returning a new Op.Outcome.

pipe(outcome, Op.Outcome.chain((val) => validate(val)));

from: object

Maybe: <A>(maybe, onNone?) => Outcome<never, A>

Creates an Op.Outcome from a Maybe, mapping Some to OpOk and None to OpNil.

A

Maybe<A>

The Maybe to convert.

() => NilReason

Optional callback returning the cancellation or drop reason (defaults to “dropped”).

Outcome<never, A>

Op.Outcome.to.Maybe to convert an outcome to a Maybe.

const outcome = Op.Outcome.from.Maybe(Maybe.make.some(42));
// { kind: "OpOk", value: 42 }

const dropped = Op.Outcome.from.Maybe(Maybe.make.none(), () => "aborted");
// { kind: "OpNil", reason: "aborted" }

Result: <E, A>(result) => Outcome<E, A>

Creates an Op.Outcome from a Result, mapping Ok to OpOk and Err to OpErr.

E

A

Result<E, A>

Outcome<E, A>

Op.Outcome.to.Result to convert an outcome to a Result.

const outcome = Op.Outcome.from.Result(Result.make.ok(42));
// { kind: "OpOk", value: 42 }

getOrElse: <B>(fallback) => <E, A>(outcome) => B | A

Returns the value if Ok, otherwise executes the fallback function and returns its result.

B

() => B

<E, A>(outcome) => B | A

pipe(outcome, Op.Outcome.getOrElse(() => defaultValue));

is: object

err: <E, A>(stateOrOutcome) => stateOrOutcome is Err<E> = isErr

Type guard that checks if an Op state or outcome is Err.

E

A

State<E, A>

stateOrOutcome is Err<E>

  • Op.Outcome.is.ok to check if an outcome or state is Ok.
  • Op.Outcome.is.nil to check if an outcome or state is Nil.
if (Op.Outcome.is.err(outcome)) {
  showError(outcome.error);
}

nil: <E, A>(stateOrOutcome) => stateOrOutcome is Nil = isNil

Type guard that checks if an Op state or outcome is Nil.

E

A

State<E, A>

stateOrOutcome is Nil

  • Op.Outcome.is.ok to check if an outcome or state is Ok.
  • Op.Outcome.is.err to check if an outcome or state is Err.
if (Op.Outcome.is.nil(outcome)) {
  console.log("Skipped due to:", outcome.reason);
}

ok: <E, A>(stateOrOutcome) => stateOrOutcome is Ok<A> = isOk

Type guard that checks if an Op state or outcome is Ok.

E

A

State<E, A>

stateOrOutcome is Ok<A>

  • Op.Outcome.is.err to check if an outcome or state is Err.
  • Op.Outcome.is.nil to check if an outcome or state is Nil.
if (Op.Outcome.is.ok(outcome)) {
  render(outcome.value);
}

make: object

err: <E>(error) => Err<E> = makeErr

Creates an Err outcome with the given error.

E

E

Err<E>

  • Op.Outcome.make.ok to create an Ok outcome.
  • Op.Outcome.make.nil to create a Nil outcome.
Op.Outcome.make.err("Something went wrong"); // { kind: "OpErr", error: "Something went wrong" }

nil: (reason) => Nil = makeNil

Creates a Nil outcome with the given cancellation or drop reason.

NilReason

Nil

  • Op.Outcome.make.ok to create an Ok outcome.
  • Op.Outcome.make.err to create an Err outcome.
Op.Outcome.make.nil("aborted"); // { kind: "OpNil", reason: "aborted" }

ok: <A>(value) => Ok<A> = makeOk

Creates an Ok outcome with the given value.

A

A

Ok<A>

  • Op.Outcome.make.err to create an Err outcome.
  • Op.Outcome.make.nil to create a Nil outcome.
Op.Outcome.make.ok(42); // { kind: "OpOk", value: 42 }

map: <A, B>(transform) => <E>(outcome) => Outcome<E, B>

Transforms the value inside an Ok outcome using the provided function.

A

B

(value) => B

<E>(outcome) => Outcome<E, B>

  • Op.Outcome.chain to sequence operations that themselves return an Op.Outcome.
  • Op.Outcome.mapError to transform the error inside an Err outcome.
pipe(outcome, Op.Outcome.map((x) => x * 2));

mapError: <E, F>(transform) => <A>(outcome) => Outcome<F, A>

Transforms the error inside an Err outcome using the provided function.

E

F

(error) => F

<A>(outcome) => Outcome<F, A>

Op.Outcome.map to transform the value inside an Ok outcome.

pipe(outcome, Op.Outcome.mapError((err) => new CustomError(err)));

match: <E, A, B>(cases) => (outcome) => B

Matches on an Op outcome by providing handlers for each variant.

E

A

B

(error) => B

(reason) => B

(value) => B

(outcome) => B

pipe(
  outcome,
  Op.Outcome.match({
    ok: (value) => `Value: ${value}`,
    err: (error) => `Error: ${error}`,
    nil: (reason) => `Cancelled: ${reason}`,
  }),
);

recover: <E1, B, E2>(handler) => <A>(outcome) => Outcome<E2, B | A>

Recovers from an Err outcome by applying a recovery function that returns a new Op.Outcome.

E1

B

E2 = never

(error) => Outcome<E2, B>

<A>(outcome) => Outcome<E2, B | A>

pipe(outcome, Op.Outcome.recover((err) => Op.Outcome.make.ok(fallbackValue)));

tap: <A>(sideEffect) => <E>(outcome) => Outcome<E, A>

Executes a side effect if the outcome is Ok and returns the original outcome unchanged.

A

(value) => void

<E>(outcome) => Outcome<E, A>

Op.Outcome.tapError to execute a side effect on Err outcomes.

pipe(outcome, Op.Outcome.tap((val) => console.log(val)));

tapError: <E>(sideEffect) => <A>(outcome) => Outcome<E, A>

Executes a side effect if the outcome is Err and returns the original outcome unchanged.

E

(error) => void

<A>(outcome) => Outcome<E, A>

Op.Outcome.tap to execute a side effect on Ok outcomes.

pipe(outcome, Op.Outcome.tapError((err) => console.error(err)));

to: object

Maybe: <E, A>(outcome) => Maybe<A>

Converts an Op.Outcome to a Maybe, mapping Ok to Some and both Err and Nil to None.

E = never

A = never

Outcome<E, A>

Maybe<A>

  • Op.Outcome.to.Result to convert an outcome to a Result.
  • Op.Outcome.from.Maybe to create an outcome from a Maybe.
pipe(outcome, Op.Outcome.to.Maybe);

Result: <E2>(onNil) => <E1, A>(outcome) => Result<E2 | E1, A>

Converts an Op.Outcome to a Result.

E2

(reason) => E2

<E1, A>(outcome) => Result<E2 | E1, A>

  • Op.Outcome.to.Maybe to convert an outcome to a Maybe.
  • Op.Outcome.from.Result to create an outcome from a Result.
pipe(outcome, Op.Outcome.to.Result((reason) => new Error(`Skipped: ${reason}`)));

wire: <Args, E, A, S>(source, sideEffect) => () => void

Subscribes to an Op manager and executes a side-effect whenever the manager emits an Ok outcome. Returns an unsubscribe callback.

Args extends readonly unknown[]

E

A

S extends State<E, A>

Manager<Args, E, A, S>

(value) => void

() => void

const unsubscribe = Op.wire(userManager, (user) => analyticsManager.run(user.id));