[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) › ResettableResource

Defined in: [packages/common/src/Resource.ts:577](https://github.com/evoluhq/evolu/blob/bc4578a260dd15d5bbf94b83765ca05984d194cb/packages/common/src/Resource.ts#L577)

A [Resource](https://evolu.dev/docs/api-reference/common/Resource/type-aliases/Resource) reset in place.

Holds one current resource and resets it on request: the current resource is
disposed first, then `create` runs again. At most one resource exists, and
there is an observable gap with none. Consumers keep the ResettableResource
and read the current resource through [get](https://evolu.dev/docs/api-reference/common/Resource/interfaces/ResettableResource#get), so
a reset needs no re-registration. A resource that cannot reset itself is the
case for it. One that can, as `WebSocket.reconnect` does, keeps a stable
identity and needs no wrapper.

The ResettableResource keeps a stable identity while its current resource
changes. [SharedResourceByKeyWithClaims](https://evolu.dev/docs/api-reference/common/Resource/interfaces/SharedResourceByKeyWithClaims) can retain it directly;
consumers read the current resource through `get`.

Repeated async disposal calls await the same cleanup and preserve any
disposal failure.

### Example

```ts
import {
  assertEqual,
  assertSame,
  createRun,
  createResettableResource,
  ok,
  type Task,
} from "@evolu/common";

interface Connection extends Disposable {
  readonly id: number;
  readonly isClosed: () => boolean;
}

let nextId = 1;
const createConnection: Task<Connection> = () => {
  const id = nextId++;
  let isClosed = false;
  return ok({
    id,
    isClosed: () => isClosed,
    [Symbol.dispose]: () => {
      isClosed = true;
    },
  });
};

await using run = createRun();
await using connection = await run.ok(
  createResettableResource(createConnection),
);
const first = connection.get();
assertEqual(first?.id, 1);

await run.ok(connection.reset(first));
assertSame(first?.isClosed(), true);
assertEqual(connection.get()?.id, 2);
```

## 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="get"></a>

### get

```ts
readonly get: () =>
  | DistributiveOmit<T, typeof dispose | typeof asyncDispose>
  | undefined;
```

Defined in: [packages/common/src/Resource.ts:586](https://github.com/evoluhq/evolu/blob/bc4578a260dd15d5bbf94b83765ca05984d194cb/packages/common/src/Resource.ts#L586)

Returns the current resource, or `undefined` when there is none: while a
reset is in progress, after a reset whose creation aborted, and after
disposal. Callers treat every absence alike, as the resource's own
not-ready state.

---

<a id="reset"></a>

### reset

```ts
readonly reset: (observed:
  | DistributiveOmit<T, typeof dispose | typeof asyncDispose>
| undefined) => Task<void>;
```

Defined in: [packages/common/src/Resource.ts:609](https://github.com/evoluhq/evolu/blob/bc4578a260dd15d5bbf94b83765ca05984d194cb/packages/common/src/Resource.ts#L609)

Resets the current resource: disposes it, then creates the next one.

A reset is requested because `observed` misbehaved, and it runs only while
`observed` is still current or there is no current resource. A request that
finds a different resource current returns without resetting, so every
observer of one dead resource shares one reset, however late its request
arrives. An `observed` of `undefined` is an observation of absence, as
[get](https://evolu.dev/docs/api-reference/common/Resource/interfaces/ResettableResource#get) returns during a reset: the request
runs only while nothing is current, so it retries an aborted creation and
skips once a replacement exists.

Resets are serialized. Owner disposal aborts a pending reset with
`runDisposedAbortReason`, and a resource that `create` returns after
disposal started is disposed and never becomes current.

Resets follow the resource-owned [Run](https://evolu.dev/docs/api-reference/common/Task/interfaces/Run)'s lifecycle: an abort request
can cancel them, and calling reset after that Run starts disposal is a
programmer error. Aborting the caller's [Fiber](https://evolu.dev/docs/api-reference/common/Task/interfaces/Fiber) does not cancel a
started reset; dependencies remain those captured at creation.