[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [local‑first/Evolu](https://evolu.dev/docs/api-reference/common/local-first/Evolu) › AppOwnerEvolu

Defined in: [packages/common/src/local-first/Evolu.ts:2135](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L2135)

An [Evolu](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu) instance without disposal, for code that uses an instance it
doesn't own, such as one [createEvoluApp](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/createEvoluApp) opened, which the app
disposes.

## Extends

- [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys)\<[`Evolu`](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu)\<`S`\>, _typeof_ `Symbol.asyncDispose`\>

## Properties

<a id="appowner"></a>

### appOwner

```ts
readonly appOwner: AppOwner;
```

Defined in: [packages/common/src/local-first/Evolu.ts:530](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L530)

The instance's [AppOwner](https://evolu.dev/docs/api-reference/common/local-first/Owner/interfaces/AppOwner): the one [createEvoluApp](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/createEvoluApp) opened, or
the one passed to [createEvolu](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/createEvolu), available synchronously. Its
`mnemonic` is what the user backs up, such as in a recovery UI.

#### Inherited from

`Omit.appOwner`

---

<a id="deletedatabase"></a>

### deleteDatabase

```ts
readonly deleteDatabase: () => Promise<Result<void, DeleteDatabaseError>>;
```

Defined in: [packages/common/src/local-first/Evolu.ts:1000](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L1000)

Deletes the local database of this [Evolu](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu) instance on this device,
and resolves once its files are gone.

The deletion runs after the mutations and requests made before it. Then
every instance of the database, identified by [Evolu.name](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu#name), disposes
itself in every tab, and the requests they made after the deletion are
dropped, so their cached loads stay pending and a suspended component stays
suspended until the app replaces the instance, and their uncached loads
resolve with empty rows. Before it disposes itself, each instance, this one
included, calls [EvoluConfig.onDatabaseDeleted](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluConfig#ondatabasedeleted), or reloads the app
without it. An AppOwner's instance of [createEvoluApp](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/createEvoluApp) does neither: a
tab that has the AppOwner open opens its database again, empty, with a new
instance; see [EvoluApp.current](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluApp#current).

It deletes only this device's copy. Changes not yet synced are lost. An
instance created later with the same [EvoluConfig.appOwner](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluConfig#appowner) opens a
new, empty database, which its transports fill again from relays, so forget
the owner first if the data must not come back. Encrypted copies in device
backups and in freed storage remain. A deletion is as durable as a commit:
a power loss right after it can undo it.

A database kept in memory, as with [EvoluConfig.memoryOnly](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluConfig#memoryonly), has a
name of its own and no files, so deleting it leaves a stored database of
the same owner alone.

It deletes the files by name, so it also deletes a database that doesn't
open, such as a corrupt one or one of a newer version. Concurrent calls, of
any instance of the database in any tab, share one deletion. It deletes no
file another context holds, because that context could still write to it,
and fails with [DatabaseHeldError](https://evolu.dev/docs/api-reference/common/local-first/Db/interfaces/DatabaseHeldError) when such a file stays held, or
when the deletion doesn't finish in time, such as while the tab that starts
it shows a modal dialog. Evolu's instances release the files before the
deletion, so only a context outside Evolu's coordination can hold them,
such as a React Native runtime that a reload replaced. Its next DbWorker
then waits for the files, as every startup does, and the database is
refused with that error when they stay held. It fails with an
[UnknownError](https://evolu.dev/docs/api-reference/common/Error/variables/UnknownError) when the platform fails to delete them. After a
failure, the database may be partly or wholly deleted, its instances keep
working, and the next call deletes again. It fails with
[EvoluDisposedError](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluDisposedError) when this instance is disposed before the
deletion ends, which may or may not then run, so await it before
disposing.

### Example

```ts
import {
  assertType,
  type DeleteDatabaseError,
  type Evolu,
  type Result,
} from "@evolu/common";

const deleteLocalData = (evolu: Evolu) => evolu.deleteDatabase();

assertType<
  Awaited<ReturnType<typeof deleteLocalData>>,
  Result<void, DeleteDatabaseError>
>();
```

#### Inherited from

`Omit.deleteDatabase`

---

<a id="deleteowner"></a>

### deleteOwner

```ts
readonly deleteOwner: (owner:
  | ShardOwner
  | SharedOwner
| SharedReadonlyOwner) => Promise<Result<void, DeleteOwnerError>>;
```

Defined in: [packages/common/src/local-first/Evolu.ts:1061](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L1061)

Deletes the rows of a [ShardOwner](https://evolu.dev/docs/api-reference/common/local-first/Owner/interfaces/ShardOwner), [SharedOwner](https://evolu.dev/docs/api-reference/common/local-first/Owner/interfaces/SharedOwner), or
[SharedReadonlyOwner](https://evolu.dev/docs/api-reference/common/local-first/Owner/interfaces/SharedReadonlyOwner) from the local database of this [Evolu](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu)
instance on this device, stops syncing the owner, and resolves once the
rows are gone.

The deletion runs after the mutations and requests made before it. It
deletes the owner's rows of every table, local-only tables included, and
its history in one transaction. Then it ends every [Evolu.useOwner](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu#useowner)
registration of the owner in every instance of the database, identified by
[Evolu.name](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu#name), in every tab, so relays don't bring the rows back, and
calling the [UnuseOwner](https://evolu.dev/docs/api-reference/common/local-first/Evolu/type-aliases/UnuseOwner) of such a registration does nothing. Then
each instance calls [EvoluConfig.onOwnerDeleted](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluConfig#onownerdeleted), this one before code
awaiting this call continues, and loads its subscribed queries again, which
return the owner's rows until they load.

It deletes only this device's copy. Changes not yet synced are lost. Relays
keep the owner's data, and so do other local databases that use the owner.
A later `useOwner` syncs the data back, and a mutation with the owner
stores its rows again, so stop using the owner first, such as by removing
it from where the app lists it. Encrypted copies in device backups and in
freed storage remain.

It takes no [AppOwner](https://evolu.dev/docs/api-reference/common/local-first/Owner/interfaces/AppOwner), whose ID names the database;
[Evolu.deleteDatabase](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu#deletedatabase) deletes the whole database instead. An owner
created from the AppOwner's secret has the same ID, so this method throws
for it.

Each call deletes on its own, in call order. It fails with an
[UnknownError](https://evolu.dev/docs/api-reference/common/Error/variables/UnknownError) when SQLite fails the deletion, which then deletes
nothing, and the owner keeps syncing. When the database is refused, it
fails with the refusal's error, as [EvoluError](https://evolu.dev/docs/api-reference/common/local-first/Evolu/type-aliases/EvoluError) describes. It fails
with [EvoluDisposedError](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluDisposedError) when this instance is disposed before the
deletion ends, which may or may not then run.

### Example

```ts
import {
  assertType,
  type DeleteOwnerError,
  type Evolu,
  type Result,
  type ShardOwner,
} from "@evolu/common";

const deleteWallet = (evolu: Evolu, walletOwner: ShardOwner) =>
  evolu.deleteOwner(walletOwner);

assertType<
  Awaited<ReturnType<typeof deleteWallet>>,
  Result<void, DeleteOwnerError>
>();

const _deleteAppOwner = (evolu: Evolu) =>
  // @ts-expect-error deleteOwner takes no AppOwner, which names the database.
  evolu.deleteOwner(evolu.appOwner);
```

#### Inherited from

`Omit.deleteOwner`

---

<a id="devicepersistence"></a>

### devicePersistence

```ts
readonly devicePersistence: Promise<DevicePersistence>;
```

Defined in: [packages/common/src/local-first/Evolu.ts:562](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L562)

Whether this device keeps the database, which [createEvolu](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/createEvolu) decides
before it creates the instance.

Apps tell the user when it is `NotPersisted`, because then data that has
not synced is lost when the instance ends. On the web this includes its tab
entering the back-forward cache. Apps must not tell the user that data is
saved on the device when it is `Unknown`.

### Example

```ts
import { assertEqual } from "@evolu/common";
import type { DevicePersistence } from "@evolu/common/local-first";

// The notice for `await evolu.devicePersistence`, or null for none.
const persistenceNotice = (
  devicePersistence: DevicePersistence,
): string | null =>
  devicePersistence === "NotPersisted"
    ? "Your data isn't kept on this device. Changes that haven't synced are lost when you close this tab."
    : null;

assertEqual(persistenceNotice("Unknown"), null);
assertEqual(
  persistenceNotice("NotPersisted"),
  "Your data isn't kept on this device. Changes that haven't synced are lost when you close this tab.",
);
```

#### Inherited from

`Omit.devicePersistence`

---

<a id="exportdatabase"></a>

### exportDatabase

```ts
readonly exportDatabase: () => Promise<Uint8Array<ArrayBuffer>>;
```

Defined in: [packages/common/src/local-first/Evolu.ts:934](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L934)

Exports the SQLite database file.

The exported file is not encrypted, even when the local database is. Any
SQLite tool can read all local data from it, so treat it as plaintext.

Exports are sequential: concurrent calls share one pending export instead
of starting parallel exports.

The pending promise rejects with an [EvoluDisposedError](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluDisposedError) if this
[Evolu](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu) instance is disposed before export completion, and with an
[UnknownError](https://evolu.dev/docs/api-reference/common/Error/variables/UnknownError) when SQLite fails the export, after which the next call
exports again. If the database is refused, export stays pending until
disposal; see [Evolu.loadQuery](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu#loadquery).

#### Inherited from

`Omit.exportDatabase`

---

<a id="getmutationsize"></a>

### getMutationSize

```ts
readonly getMutationSize: <TableName>(table: TableName, values: Partial<MutationValues<S[TableName], "update">>) => number & Brand<"NonNaN"> & Brand<"Finite"> & Brand<"Int"> & Brand<"NonNegative"> & Brand<"Positive">;
```

Defined in: [packages/common/src/local-first/Evolu.ts:733](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L733)

Returns the size of a mutation of `table` with `values`, measured as
[maxMutationSize](https://evolu.dev/docs/api-reference/common/local-first/Evolu/variables/maxMutationSize) describes.

Use it to check values that column Types do not bound before mutating, or
to show how much of the limit a mutation uses. It accepts any of the
table's columns, so the values of an insert, update, or upsert fit, and it
ignores `id` and `isDeleted`, which are not columns. Mutations of
local-only tables are measured too, although they are exempt from the
limit.

### Example

```ts
import {
  assertType,
  type Evolu,
  maxMutationSize,
  type NonEmptyTrimmedString100,
  type TestEvoluSchema,
} from "@evolu/common";

const fitsTodo = (
  evolu: Evolu<TestEvoluSchema>,
  title: NonEmptyTrimmedString100,
) => evolu.getMutationSize("todo", { title }) <= maxMutationSize;

assertType<ReturnType<typeof fitsTodo>, boolean>();
```

#### Inherited from

`Omit.getMutationSize`

---

<a id="getqueryrows"></a>

### getQueryRows

```ts
readonly getQueryRows: <R>(query: Query<S, R>) => QueryRows<R>;
```

Defined in: [packages/common/src/local-first/Evolu.ts:917](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L917)

Get [QueryRows](https://evolu.dev/docs/api-reference/common/local-first/Query/type-aliases/QueryRows).

### Example

```ts
import {
  assertType,
  createQueryBuilder,
  testEvoluSchema,
  type TestEvoluSchema,
  type Evolu,
  type QueryRows,
} from "@evolu/common";

const createQuery = createQueryBuilder(testEvoluSchema);
const allTodos = createQuery((db) => db.selectFrom("todo").select("title"));
const getTodos = (evolu: Evolu<TestEvoluSchema>) =>
  evolu.getQueryRows(allTodos);

assertType<ReturnType<typeof getTodos>, QueryRows<typeof allTodos.Row>>();
```

#### Inherited from

`Omit.getQueryRows`

---

<a id="insert"></a>

### insert

```ts
readonly insert: Mutation<S, "insert">;
```

Defined in: [packages/common/src/local-first/Evolu.ts:616](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L616)

Inserts a row and returns the generated [Id](https://evolu.dev/docs/api-reference/common/Type/variables/Id).

All non-nullable columns are required, nullable columns are optional, and
`id` is omitted because Evolu generates it automatically. This ensures
every row has a globally unique, conflict-free identifier without
coordination.

Pass `onSuccess` when follow-up work must wait until the mutation is stored
and subscribed queries reflect it. It never runs when the database is
unavailable; see [Evolu.loadQuery](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu#loadquery). When the mutation could not be
stored, [MutationOptions.onError](https://evolu.dev/docs/api-reference/common/local-first/Schema/interfaces/MutationOptions#onerror) runs instead, and
[EvoluErrorDep.evoluError](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluErrorDep#evoluerror) reports the error. A stored change is not
always visible; see [MutationOptions.onSuccess](https://evolu.dev/docs/api-reference/common/local-first/Schema/interfaces/MutationOptions#onsuccess).

### Example

```ts
import {
  assertType,
  type TestEvoluSchema,
  NonEmptyTrimmedString100,
  type Evolu,
  type TestTodoId,
} from "@evolu/common";

const insertTodo = (evolu: Evolu<TestEvoluSchema>) =>
  evolu.insert("todo", {
    title: NonEmptyTrimmedString100.orThrow("Learn Evolu"),
  }).id;

const insertTodoAndNotify = (
  evolu: Evolu<TestEvoluSchema>,
  onSuccess: () => void,
) =>
  evolu.insert(
    "todo",
    { title: NonEmptyTrimmedString100.orThrow("Another todo") },
    { onSuccess },
  ).id;

assertType<
  [ReturnType<typeof insertTodo>, ReturnType<typeof insertTodoAndNotify>],
  [TestTodoId, TestTodoId]
>();
```

#### See

[Mutation](https://evolu.dev/docs/api-reference/common/local-first/Schema/type-aliases/Mutation)

#### Inherited from

`Omit.insert`

---

<a id="loadqueries"></a>

### loadQueries

```ts
readonly loadQueries: <Q>(queries: [...Q[]]) => [...QueriesToQueryRowsPromises<Q>[]];
```

Defined in: [packages/common/src/local-first/Evolu.ts:847](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L847)

Load an array of [Query](https://evolu.dev/docs/api-reference/common/local-first/Query/type-aliases/Query) values and return an array of
[QueryRows](https://evolu.dev/docs/api-reference/common/local-first/Query/type-aliases/QueryRows) promises. It's like `queries.map(loadQuery)` but with
proper types for returned promises.

### Example

```ts
import {
  assertType,
  createQueryBuilder,
  testEvoluSchema,
  type TestEvoluSchema,
  testTodoId,
  type Evolu,
  type QueryRows,
} from "@evolu/common";

const createQuery = createQueryBuilder(testEvoluSchema);
const allTodos = createQuery((db) =>
  db.selectFrom("todo").select(["id", "title"]),
);
const firstTodo = createQuery((db) =>
  db.selectFrom("todo").select("title").where("id", "=", testTodoId),
);
const loadTodoQueries = (evolu: Evolu<TestEvoluSchema>) =>
  evolu.loadQueries([allTodos, firstTodo]);

assertType<
  ReturnType<typeof loadTodoQueries>,
  [
    Promise<QueryRows<typeof allTodos.Row>>,
    Promise<QueryRows<typeof firstTodo.Row>>,
  ]
>();
```

#### Inherited from

`Omit.loadQueries`

---

<a id="loadquery"></a>

### loadQuery

```ts
readonly loadQuery: <R>(query: Query<S, R>, options?: LoadQueryOptions) => Promise<QueryRows<R>>;
```

Defined in: [packages/common/src/local-first/Evolu.ts:805](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L805)

Load [Query](https://evolu.dev/docs/api-reference/common/local-first/Query/type-aliases/Query) and return a promise with [QueryRows](https://evolu.dev/docs/api-reference/common/local-first/Query/type-aliases/QueryRows).

The returned promise rejects with an [UnknownError](https://evolu.dev/docs/api-reference/common/Error/variables/UnknownError) when SQLite fails
the query, for example on a syntax error in a raw SQL fragment or on data
its SQL functions cannot read, such as `json_extract` on text that is not
JSON. Only that query fails: other queries load, mutations are stored, and
[EvoluErrorDep.evoluError](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluErrorDep#evoluerror) is not set. React's `useQuery` throws the
error to the nearest error boundary. If the database is refused, because it
refused startup or its worker failed, an uncached load rejects with an
[UnknownError](https://evolu.dev/docs/api-reference/common/Error/variables/UnknownError), the refusal itself or one wrapping it, and cached
loads stay pending until disposal resolves them with empty rows, so a
suspended component stays suspended. Cached loads that a deletion of the
database dropped stay pending, because the app replaces the instance; see
[Evolu.deleteDatabase](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu#deletedatabase). An uncached load never stays pending past
disposal, also the disposal a deletion of the database causes: it resolves
with empty rows, which then say nothing about the database, and the
instance's methods throw. Observe [EvoluErrorDep.evoluError](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluErrorDep#evoluerror) to
display the refusal independently of query loading.

Cached loading is batched. Returned promises are cached while pending and
can be reused after they settle, which prevents redundant database queries
and supports React Suspense (stable references while pending). A mutation
or incoming sync invalidates the cache of an unsubscribed query, so its
next load reads again. A subscribed query keeps its cached result and the
subscription refreshes it, so a load can return rows that a pending refresh
is about to replace. When SQLite fails a refresh, the query keeps its rows,
its loads reject until a refresh succeeds, and its subscribers are
notified, so React's `useQuery` throws the error then. To skip the cache,
pass `cache: false`; see [LoadQueryOptions.cache](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/LoadQueryOptions#cache).

To subscribe a query for automatic updates, use
[Evolu.subscribeQuery](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu#subscribequery).

### Example

```ts
import {
  assertType,
  createQueryBuilder,
  testEvoluSchema,
  type TestEvoluSchema,
  type Evolu,
  type QueryRows,
} from "@evolu/common";

const createQuery = createQueryBuilder(testEvoluSchema);
const allTodos = createQuery((db) => db.selectFrom("todo").selectAll());
const loadTodos = async (evolu: Evolu<TestEvoluSchema>) => {
  const rows = await evolu.loadQuery(allTodos);
  return rows;
};
const loadUncachedTodos = (evolu: Evolu<TestEvoluSchema>) =>
  evolu.loadQuery(allTodos, { cache: false });

assertType<
  ReturnType<typeof loadTodos>,
  Promise<QueryRows<typeof allTodos.Row>>
>();
assertType<
  ReturnType<typeof loadUncachedTodos>,
  Promise<QueryRows<typeof allTodos.Row>>
>();
```

#### Inherited from

`Omit.loadQuery`

---

<a id="name"></a>

### name

```ts
readonly name: string & Brand<"UrlSafeString"> & Brand<"Name">;
```

Defined in: [packages/common/src/local-first/Evolu.ts:523](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L523)

Evolu instance name is derived from [EvoluConfig.appName](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluConfig#appname),
[AppOwner](https://evolu.dev/docs/api-reference/common/local-first/Owner/interfaces/AppOwner)'s hash, and, for a memory database, a random instance ID;
see [AppName](https://evolu.dev/docs/api-reference/common/local-first/Evolu/variables/AppName).

#### Inherited from

`Omit.name`

---

<a id="requestsync"></a>

### requestSync

```ts
readonly requestSync: (ownerId: string & Brand<"Id"> & Brand<"OwnerId">) => void;
```

Defined in: [packages/common/src/local-first/Evolu.ts:1179](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L1179)

Requests a new synchronization round for an active [OwnerId](https://evolu.dev/docs/api-reference/common/local-first/Owner/variables/OwnerId).

Reconciles locally stored changes, including writes previously rejected
with [ProtocolQuotaError](https://evolu.dev/docs/api-reference/common/local-first/Protocol/interfaces/ProtocolQuotaError), through the owner's active transports. Call
this after the relay provider confirms additional quota is available. It
also checks again the changes this database skipped from the owner's
relays, and sends such a relay the changes received from other relays,
which otherwise wait for its next sync, such as after a reconnect. On a
relay that sends no heartbeats, a request is also how the shared worker
notices a connection that died without closing: an unanswered request
replaces it after the request timeout, ninety seconds unless it has grown,
as Liveness in the Shared module describes. Existing connections and
[Evolu.useOwner](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu#useowner) registrations are retained, including registrations
shared by multiple instances or tabs.

The owner must have an active writable registration in this database.
Unregistered or read-only owners are ignored. Requests are skipped while
all of the owner's transports are closed; they synchronize when they
reopen. Disposal drops locally buffered requests. Calling a disposed
instance throws, like other Evolu operations.

Returns immediately, without waiting for synchronization to complete. The
owner's routes in sync state show a failure, such as a quota rejection, as
`failure`, and a skipped change as `skippedError`.

### Example

```ts
import { assertType, type Evolu, type OwnerId } from "@evolu/common";

// Call after successfully increasing the affected owner's relay quota.
const onQuotaIncreased = (evolu: Evolu, ownerId: OwnerId) => {
  evolu.requestSync(ownerId);
};

assertType<typeof onQuotaIncreased, (evolu: Evolu, ownerId: OwnerId) => void>();
```

#### Inherited from

`Omit.requestSync`

---

<a id="subscribequery"></a>

### subscribeQuery

```ts
readonly subscribeQuery: (query: Query<S>) => (listener: Listener) => Unsubscribe;
```

Defined in: [packages/common/src/local-first/Evolu.ts:885](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L885)

Subscribe to [Query](https://evolu.dev/docs/api-reference/common/local-first/Query/type-aliases/Query) [QueryRows](https://evolu.dev/docs/api-reference/common/local-first/Query/type-aliases/QueryRows) changes.

Cached rows invalidated before subscription are refreshed. Subscribing
alone does not load a query that has no cached rows.

### Example

```ts
import {
  assertType,
  createQueryBuilder,
  testEvoluSchema,
  type TestEvoluSchema,
  type Evolu,
  type QueryRows,
  type Unsubscribe,
} from "@evolu/common";

const createQuery = createQueryBuilder(testEvoluSchema);
const allTodos = createQuery((db) => db.selectFrom("todo").select("title"));
const subscribeToTodos = (
  evolu: Evolu<TestEvoluSchema>,
  onRows: (rows: QueryRows<typeof allTodos.Row>) => void,
) =>
  evolu.subscribeQuery(allTodos)(() => {
    onRows(evolu.getQueryRows(allTodos));
  });

assertType<ReturnType<typeof subscribeToTodos>, Unsubscribe>();
```

#### Inherited from

`Omit.subscribeQuery`

---

<a id="update"></a>

### update

```ts
readonly update: Mutation<S, "update">;
```

Defined in: [packages/common/src/local-first/Evolu.ts:663](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L663)

Updates a row and returns the [Id](https://evolu.dev/docs/api-reference/common/Type/variables/Id).

Only `id` is required, all other columns are optional.

In a [local-only](https://evolu.dev/docs/api-reference/common/local-first/Schema/functions/isLocalOnlyTable) table, whose deletes remove rows,
it changes only an existing row, so it doesn't bring back a deleted one;
[Evolu.upsert](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/Evolu#upsert) creates a row. There, an update of a missing row
changes nothing and isn't an error, so [MutationOptions.onSuccess](https://evolu.dev/docs/api-reference/common/local-first/Schema/interfaces/MutationOptions#onsuccess)
runs, as after a SQL `UPDATE` that matches no row.

### Example

```ts
import {
  assertType,
  type TestEvoluSchema,
  NonEmptyTrimmedString100,
  sqliteTrue,
  type Evolu,
  type TestTodoId,
} from "@evolu/common";

const renameTodo = (evolu: Evolu<TestEvoluSchema>, todoId: TestTodoId) =>
  evolu.update("todo", {
    id: todoId,
    title: NonEmptyTrimmedString100.orThrow("Updated title"),
  }).id;

const softDeleteTodo = (evolu: Evolu<TestEvoluSchema>, todoId: TestTodoId) =>
  evolu.update("todo", { id: todoId, isDeleted: sqliteTrue }).id;

assertType<
  [ReturnType<typeof renameTodo>, ReturnType<typeof softDeleteTodo>],
  [TestTodoId, TestTodoId]
>();
```

#### See

[Mutation](https://evolu.dev/docs/api-reference/common/local-first/Schema/type-aliases/Mutation)

#### Inherited from

`Omit.update`

---

<a id="upsert"></a>

### upsert

```ts
readonly upsert: Mutation<S, "upsert">;
```

Defined in: [packages/common/src/local-first/Evolu.ts:701](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L701)

Upserts a row and returns the [Id](https://evolu.dev/docs/api-reference/common/Type/variables/Id).

Like insert, but requires an `id`. Useful for rows with external ID via
[createIdFromString](https://evolu.dev/docs/api-reference/common/Type/functions/createIdFromString). All other non-nullable columns are required,
nullable columns are optional.

Upserting a row that already exists on this device sets its `updatedAt` and
does not change its `createdAt`. An upsert made on another device before it
synchronized the row can move `createdAt` earlier when it arrives. See
[SystemColumns](https://evolu.dev/docs/api-reference/common/local-first/Schema/variables/SystemColumns-1).

### Example

```ts
import {
  assertType,
  createIdFromString,
  type TestEvoluSchema,
  NonEmptyTrimmedString100,
  type Evolu,
  TestTodoId,
} from "@evolu/common";

const stableId = TestTodoId.orThrow(createIdFromString("my-todo-1"));
const upsertTodo = (evolu: Evolu<TestEvoluSchema>) =>
  evolu.upsert("todo", {
    id: stableId,
    title: NonEmptyTrimmedString100.orThrow("Learn Evolu"),
  }).id;

assertType<ReturnType<typeof upsertTodo>, TestTodoId>();
```

#### See

[Mutation](https://evolu.dev/docs/api-reference/common/local-first/Schema/type-aliases/Mutation)

#### Inherited from

`Omit.upsert`

---

<a id="useowner"></a>

### useOwner

```ts
readonly useOwner: (owner:
  | Owner
  | ReadonlyOwner, transports?: readonly [OwnerWebSocketTransport, OwnerWebSocketTransport]) => UnuseOwner;
```

Defined in: [packages/common/src/local-first/Evolu.ts:1132](https://github.com/evoluhq/evolu/blob/aa223771feea747ffb1b0f5f3271574455633e37/packages/common/src/local-first/Evolu.ts#L1132)

Use an Owner for sync. Returns a [UnuseOwner](https://evolu.dev/docs/api-reference/common/local-first/Evolu/type-aliases/UnuseOwner).

Using an Owner means syncing it with the provided transports, or with the
default transports defined in [EvoluConfig](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluConfig) when transports are
omitted. An AppOwner's data lives only in its own database, which its
deletion deletes, so an instance syncs its own AppOwner but throws for
another one. An instance of [createEvoluApp](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/createEvoluApp) recognizes another
AppOwner by the IDs the app lists; one of [createEvolu](https://evolu.dev/docs/api-reference/common/local-first/Evolu/functions/createEvolu) only by its
type, so it misses an owner with another AppOwner's ID but another type,
such as one created from that AppOwner's secret.

If [EvoluConfig.transports](https://evolu.dev/docs/api-reference/common/local-first/Evolu/interfaces/EvoluConfig#transports) is an empty array, this method must be
called with explicit non-empty transports.

Owners that use equal transports share one reference-counted connection.
The transports in one array must be distinct, so this method throws for
equal ones, such as two spellings that [RelayUrlFromString](https://evolu.dev/docs/api-reference/common/local-first/Owner/variables/RelayUrlFromString) converts
to one URL.

### Example

```ts
import {
  assertEqual,
  createOwnerWebSocketTransport,
  deriveShardOwner,
  RelayUrl,
  testAppOwner,
  type Evolu,
  type ReadonlyOwner,
  type UnuseOwner,
} from "@evolu/common";

const relayUrl = RelayUrl.orThrow("wss://relay.example.com/");
const shardOwner = deriveShardOwner(testAppOwner, ["todos", 1]);
const shardTransport = createOwnerWebSocketTransport({
  url: relayUrl,
  ownerId: shardOwner.id,
});
const _useShardOwner = (evolu: Evolu): UnuseOwner =>
  evolu.useOwner(shardOwner, [shardTransport]);

const _useOwners = (
  evolu: Evolu,
  owners: ReadonlyArray<ReadonlyOwner>,
): UnuseOwner => {
  const unuseOwners = owners.map((owner) =>
    evolu.useOwner(owner, [
      createOwnerWebSocketTransport({
        url: relayUrl,
        ownerId: owner.id,
      }),
    ]),
  );
  return () => {
    for (const unuse of unuseOwners) unuse();
  };
};

// Call each returned UnuseOwner once to stop syncing.
assertEqual(shardTransport, {
  type: "WebSocket",
  url: `wss://relay.example.com/?ownerId=${shardOwner.id}`,
});
```

#### Inherited from

`Omit.useOwner`