Yieldless
Reference

yieldless/resource

Native async disposal with acquire and release functions.

yieldless/resource turns a pair of acquire/release functions into an object that participates in native await using cleanup.

Exports

  • type ResourceAcquire<T> = () => PromiseLike<T> | T
  • type ResourceRelease<T> = (resource: T) => PromiseLike<void> | void
  • interface AsyncResource<T> extends AsyncDisposable { readonly value: T }
  • acquireResource(acquire, release): Promise<AsyncResource<T>>

Example

import { acquireResource } from "yieldless/resource";

{
  await using db = await acquireResource(connect, disconnect);
  await db.value.query("select 1");
}

Where it fits

  • Database or queue connections scoped to a request or job
  • Temporary filesystem handles
  • External clients that need explicit teardown

Important detail

The resource wrapper exposes the underlying value as .value. That keeps the disposable handle explicit and avoids pretending that current await using syntax can destructure directly into a tuple.

Good

Use acquireResource() when cleanup must happen even if the body throws.

{
  await using temp = await acquireResource(
    () => createTempDirectory(),
    (directory) => rmSafe(directory, { recursive: true, force: true }),
  );

  await writeBuildArtifacts(temp.value);
}

Keep the resource lifetime as small as the work that needs it.

Avoid

Do not acquire a resource and hope every return path remembers cleanup.

const client = await connect();
const result = await runJob(client);
await disconnect(client);
return result;

Use await using when the TypeScript target and runtime support it. Otherwise keep try / finally explicit.

On this page