API reference@evolu/commonlocal‑first/Schema › MutationOptions

Defined in: packages/common/src/local-first/Schema.ts:221

Properties

onComplete?

readonly optional onComplete?: () => void;

Defined in: packages/common/src/local-first/Schema.ts:227

Called after the mutation is completed and the local state is updated. Useful for triggering side effects (e.g., notifications, UI updates) after insert, update, or upsert.

ownerId?

readonly optional ownerId?: string & Brand<"Id"> & Brand<"OwnerId">;

Defined in: packages/common/src/local-first/Schema.ts:286

Specifies the owner ID for this mutation. If omitted, the default AppOwner is used.

The owner must be used with evolu.useOwner() to enable sync. Mutations with unused owners are stored locally but not synced until the owner is used.

Example

import {
  createAppOwner,
  createOwnerSecret,
  createRandomBytes,
  createSharedOwner,
  deriveShardOwner,
  id,
  NonEmptyTrimmedString100,
  type Evolu,
} from "@evolu/common";

const Schema = {
  task: { id: id("Task"), title: NonEmptyTrimmedString100 },
  comment: { id: id("Comment"), text: NonEmptyTrimmedString100 },
};
const randomBytes = createRandomBytes();
// Create once, persist the mnemonic securely, and restore it on later runs.
const appOwner = createAppOwner(createOwnerSecret({ randomBytes }));
const projectOwner = deriveShardOwner(appOwner, ["project", "project-1"]);
const sharedOwner = createSharedOwner(createOwnerSecret({ randomBytes }));

const insertOwnedRows = (evolu: Evolu<typeof Schema>): void => {
  // Partition app data by project.
  evolu.insert(
    "task",
    { title: NonEmptyTrimmedString100.orThrow("Task 1") },
    { ownerId: projectOwner.id },
  );

  // Put collaborative data under a shared owner.
  evolu.insert(
    "comment",
    { text: NonEmptyTrimmedString100.orThrow("Hello") },
    { ownerId: sharedOwner.id },
  );
};

expect(projectOwner.type).toBe("ShardOwner");
expect(sharedOwner.type).toBe("SharedOwner");