> ## Documentation Index
> Fetch the complete documentation index at: https://stratasync.blode.md/llms.txt
> Use this file to discover all available pages before exploring further.

# Event system

Subscribe to typed events for UI updates, notifications, or side effects.

## Subscribing to events

Use `onEvent` to listen to all event types. It returns an unsubscribe function.

```ts
const unsubscribe = client.onEvent((event) => {
  switch (event.type) {
    case "syncStart":
      console.log("Sync started");
      break;
    case "syncComplete":
      console.log("Synced to ID:", event.lastSyncId);
      break;
    case "syncError":
      console.error("Sync error:", event.error);
      break;
    case "modelChange":
      console.log(`${event.action} ${event.modelName}:${event.modelId}`);
      break;
  }
});

// Clean up when done
unsubscribe();
```

## Specialized subscribers

Convenience methods for narrower subscriptions:

### onStateChange

Subscribe to sync state transitions only.

```ts
const unsubscribe = client.onStateChange((state) => {
  console.log("New state:", state);
  // "disconnected" | "connecting" | "bootstrapping" | "syncing" | "error"
});
```

### onConnectionStateChange

Subscribe to connection state transitions only.

```ts
const unsubscribe = client.onConnectionStateChange((state) => {
  console.log("Connection:", state);
});
```

## Event types

Every event has a `type` discriminant.

| Event Name         | Key Fields                                                                           | Description                                                                        |
| ------------------ | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| `syncStart`        | -                                                                                    | A sync cycle has begun.                                                            |
| `syncComplete`     | `lastSyncId: number`                                                                 | A sync cycle finished. `lastSyncId` is the highest sync ID received.               |
| `syncError`        | `error: Error`                                                                       | A sync cycle failed.                                                               |
| `stateChange`      | `state: SyncClientState`                                                             | The client transitioned to a new sync state.                                       |
| `connectionChange` | `state: ConnectionState`                                                             | The transport connection state changed.                                            |
| `outboxChange`     | `pendingCount: number`                                                               | The count of unsynced transactions changed.                                        |
| `modelChange`      | `modelName: string`, `modelId: string`, `action: ModelChangeAction`                  | A model was inserted, updated, deleted, archived, or unarchived (local or server). |
| `rebaseConflict`   | `modelName: string`, `modelId: string`, `conflictType: string`, `resolution: string` | A conflict was detected during transaction rebasing.                               |

```ts
// Full type definitions

type SyncEvent =
  | { type: "syncStart" }
  | { type: "syncComplete"; lastSyncId: number }
  | { type: "syncError"; error: Error }
  | { type: "stateChange"; state: SyncClientState }
  | { type: "connectionChange"; state: ConnectionState }
  | { type: "outboxChange"; pendingCount: number }
  | {
      type: "modelChange";
      modelName: string;
      modelId: string;
      action: ModelChangeAction;
    }
  | {
      type: "rebaseConflict";
      modelName: string;
      modelId: string;
      conflictType: string;
      resolution: string;
    };

type ModelChangeAction =
  | "insert"
  | "update"
  | "delete"
  | "archive"
  | "unarchive";
```

## SyncClientState values

| State             | Description                                              |
| ----------------- | -------------------------------------------------------- |
| `"disconnected"`  | Not connected to the server.                             |
| `"connecting"`    | Establishing a connection.                               |
| `"bootstrapping"` | Loading initial data from the server.                    |
| `"syncing"`       | Connected and syncing deltas. This is the "ready" state. |
| `"error"`         | An unrecoverable error occurred.                         |

## Usage with React

In React, use the hooks from `@stratasync/react` instead of calling `onEvent` directly.

```tsx
import { useConnectionState, usePendingCount } from "@stratasync/react";

function SyncStatus() {
  const { status, lastSyncId, error } = useConnectionState();
  const { count, hasPending } = usePendingCount();

  return (
    <div>
      <span>Status: {status}</span>
      <span>Sync ID: {lastSyncId}</span>
      {hasPending && <span>{count} pending</span>}
      {error && <span>Error: {error.message}</span>}
    </div>
  );
}
```

See [Offline-first patterns](/guides/offline-first) for a complete sync status indicator example.