API reference › @evolu/common › Task › 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);