API reference@evolu/commonTask › acquireUseRelease

function acquireUseRelease<
  Resource,
  T,
  EAcquire,
  EUse,
  DAcquire,
  DUse,
  DRelease,
>(
  acquire: Task<Resource, EAcquire, DAcquire>,
  use: (resource: Resource) => Task<T, EUse, DUse>,
  release: (resource: Resource) => Task<void, never, DRelease>,
): Task<T, EAcquire | EUse, DAcquire & DUse & DRelease>;

Defined in: packages/common/src/Task.ts:5287

Runs acquire, use, and release as one bracketed Task.

Acquire and release are masked once the helper starts, while use runs with the previous abort mask restored. If acquire returns an error, release is not run. Release must not return recoverable errors; handle expected cleanup failures inside the release Task.

Use this when a resource, lease, lock, or session must always be released after it is acquired, even when use fails or is aborted.

Prefer native using, await using, or AsyncDisposableStack for owned values that implement Disposable or AsyncDisposable. Use acquireUseRelease when acquisition must be balanced with a separate release step, such as unlocking, returning a pooled value, releasing a lease, or logging out of a session.

Example

import {
  assertErr,
  assertTrue,
  acquireUseRelease,
  createRun,
  err,
  ok,
  type Task,
  type Typed,
} from "@evolu/common";

interface Connection {
  readonly user: string;
  readonly isAvailable: boolean;
}

const openConnection: Task<Connection> = () =>
  ok({ user: "Ada", isAvailable: false });
const loadUser =
  (connection: Connection): Task<string, UserUnavailableError> =>
  () =>
    connection.isAvailable
      ? ok(connection.user)
      : err({ type: "UserUnavailable" });

interface UserUnavailableError extends Typed<"UserUnavailable"> {}

let connectionClosed = false;
const closeConnection =
  (_connection: Connection): Task<void> =>
  () => {
    connectionClosed = true;
    return ok();
  };

const queryUser = acquireUseRelease(openConnection, loadUser, (connection) =>
  closeConnection(connection),
);

await using run = createRun();
assertErr(await run(queryUser), { type: "UserUnavailable" });
// Release still runs when use returns a domain error.
assertTrue(connectionClosed);