[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [Resource](https://evolu.dev/docs/api-reference/common/Resource) › SharedResource

Defined in: [packages/common/src/Resource.ts:197](https://github.com/evoluhq/evolu/blob/037c390af081e9944d616ff298a729515c5c5ab7/packages/common/src/Resource.ts#L197)

Shared [Resource](https://evolu.dev/docs/api-reference/common/Resource/type-aliases/Resource).

Lazily creates the underlying resource on the first
[acquire](https://evolu.dev/docs/api-reference/common/Resource/interfaces/SharedResource#acquire) call, shares it across callers via
[Lease](https://evolu.dev/docs/api-reference/common/Resource/interfaces/Lease)s, and disposes it when the last lease is released.

### Example

```ts
import {
  all,
  assertEqual,
  assertFalse,
  createRun,
  createSharedResource,
  ok,
  type Task,
} from "@evolu/common";

interface Connection extends Disposable {
  readonly send: (message: string) => void;
}

let createdCount = 0;
const createConnection: Task<Connection> = () => {
  createdCount += 1;
  return ok({
    send: (_message) => {},
    [Symbol.dispose]: () => {},
  });
};

await using run = createRun();
await using sharedConnection = await run.ok(
  createSharedResource(createConnection, { idleDisposeAfter: "5s" }),
);

// Creating the owner is lazy; no connection is open yet.
assertEqual(createdCount, 0);

// `use` owns and releases a lease around each operation.
const send = (message: string): Task<void> =>
  sharedConnection.use((connection) => () => {
    connection.send(message);
    return ok();
  });

{
  // An explicit lease can span several operations. Concurrent `use` calls
  // share the connection kept alive by this lease.
  using batchLease = await run.ok(sharedConnection.acquire);
  batchLease.resource.send("first");
  batchLease.resource.send("second");
  await run.ok(all([send("hello"), send("world")], { concurrency: 2 }));
}

// Reacquiring during the idle delay reuses the same generation.
using reusedLease = await run.ok(sharedConnection.acquire);
assertFalse(reusedLease.created);
assertEqual(createdCount, 1);
```

## FAQ

### Why release a lease with `using`?

`using` guarantees a [Lease](https://evolu.dev/docs/api-reference/common/Resource/interfaces/Lease) is released on every exit path: normal
completion, a thrown error, and abort — abort surfaces as an exception in
Task code, so stack unwinding runs disposers. Binding a lease to an ordinary
`const` instead is a deliberate ownership transfer; the new owner must
guarantee release.

### What happens when a lease leaks?

Nothing in JavaScript enforces `using` or release; a lease that is never
released compiles silently (see [MDN resource management
pitfalls](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Resource_management#pitfalls);
a lint rule may eventually close this gap:
https://github.com/typescript-eslint/typescript-eslint/issues/8255). Encoding
resource lifetime in the type system would not be bulletproof either: types
can force a lifetime to exist, but a lifetime scoped too widely leaks just as
silently. Evolu therefore stays JS-native — `using` in the language — and
bounds the damage structurally. A leaked lease keeps the resource alive but
never past its owner: disposing a SharedResource drains all outstanding
leases and disposes the resource. A leaked SharedResource is bounded by its
Run, whose disposal also drains its leases and disposes its current resource.
Leaks are also observable — [snapshot](https://evolu.dev/docs/api-reference/common/Resource/interfaces/SharedResource#snapshot) exposes
a lease count that never returns to zero — and detected: in development
builds, a lease that is garbage-collected without release logs a warning with
its acquire stack via the LeakDetector dependency.

## Extends

- [`AsyncDisposable`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management)

## Methods

<a id="asyncdispose"></a>

### \[asyncDispose\]()

```ts
asyncDispose: PromiseLike<void>;
```

Defined in: node\_modules/@typescript/old/lib/lib.esnext.disposable.d.ts:38

#### Inherited from

```ts
AsyncDisposable.[asyncDispose]
```

## Properties

<a id="acquire"></a>

### acquire

```ts
readonly acquire: Task<Lease<T>>;
```

Defined in: [packages/common/src/Resource.ts:220](https://github.com/evoluhq/evolu/blob/037c390af081e9944d616ff298a729515c5c5ab7/packages/common/src/Resource.ts#L220)

Acquires a [Lease](https://evolu.dev/docs/api-reference/common/Resource/interfaces/Lease) on the shared resource.

The first call lazily creates the resource. Later calls reuse the same
resource until the last lease is released.

Once started, acquire runs to completion even when the caller aborts its
Fiber, and the returned lease still counts as held. If resource creation or
disposal is in progress, acquire waits for it to complete. Always await the
result and release the lease; a caller that stops waiting (for example with
the `daemon` helper) abandons a lease that is never released, retaining the
resource until the owning [SharedResource](https://evolu.dev/docs/api-reference/common/Resource/interfaces/SharedResource) is disposed.

Owner disposal is different from caller abort: if disposal starts before a
lease is transferred, acquire aborts with `runDisposedAbortReason` from the
SharedResource's internal Run. A resource returned by `create` after
shutdown starts remains owned by this SharedResource and is disposed
without a lease escaping. Transfer occurs when the internal acquisition
completes, before the caller necessarily resumes. If owner disposal starts
in that gap, the caller can receive a lease already drained by disposal.
Its `release` returns `false`, and its resource must not be used.

---

<a id="acquirecurrent"></a>

### acquireCurrent

```ts
readonly acquireCurrent: Task<
  | Lease<T>
| undefined>;
```

Defined in: [packages/common/src/Resource.ts:230](https://github.com/evoluhq/evolu/blob/037c390af081e9944d616ff298a729515c5c5ab7/packages/common/src/Resource.ts#L230)

Acquires a [Lease](https://evolu.dev/docs/api-reference/common/Resource/interfaces/Lease) on the current resource without creating one.

Waits for preceding creation or disposal to finish. Returns `undefined` if
no current resource remains. Owner disposal while waiting aborts the
acquisition before a lease is transferred. As with `acquire`, owner
disposal after transfer can drain the lease before the caller resumes.

---

<a id="snapshot"></a>

### snapshot

```ts
readonly snapshot: () => SharedResourceSnapshot;
```

Defined in: [packages/common/src/Resource.ts:250](https://github.com/evoluhq/evolu/blob/037c390af081e9944d616ff298a729515c5c5ab7/packages/common/src/Resource.ts#L250)

Returns the current shared-resource state for monitoring/debugging.

### use

```ts
readonly use: <R, E, D>(callback: (resource: DistributiveOmit<T>, created: boolean) => Task<R, E, D>) => Task<R, E, D>;
```

Defined in: [packages/common/src/Resource.ts:242](https://github.com/evoluhq/evolu/blob/037c390af081e9944d616ff298a729515c5c5ab7/packages/common/src/Resource.ts#L242)

Acquires a [Lease](https://evolu.dev/docs/api-reference/common/Resource/interfaces/Lease), runs a Task with the shared resource, and releases
the lease after the Task settles.

Creates the resource when absent. The callback receives whether this use
created the resource generation. While the owner remains running, the lease
prevents ordinary idle disposal. Disposing this SharedResource is forceful:
it drains the lease and may dispose the resource before or while the
callback Task runs.