> ## 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.

# Model base class

Every synced entity extends `Model`. Decorators register it with the `ModelRegistry` and wire it into the sync lifecycle.

## Creating a model

```ts
import { Model, ClientModel, Property, ManyToOne } from "@stratasync/core";

@ClientModel("Task")
class Task extends Model {
  @Property()
  title = "";

  @Property()
  status = "todo";

  @Property()
  priority = 0;

  @ManyToOne("Project", "tasks")
  project!: Project;
}
```

`@ClientModel` registers the class as `"Task"`. Each `@Property` marks a synced field for change tracking and delta processing.

## Model properties

| Property      | Type      | Description                                        |
| ------------- | --------- | -------------------------------------------------- |
| `id`          | `string`  | Primary key (UUID). Set automatically on creation. |
| `hydrated`    | `boolean` | Whether lazy references have been resolved.        |
| `__modelName` | `string`  | The registered model name (read-only getter).      |

> **Internals.** `__data` holds raw backing data. `store` is the backing store reference injected by the sync client. You shouldn't need either in application code.

## Instance methods

### `hydrate()`

Resolves all lazy references and collections.

```ts
const task = await client.get<Task>("Task", taskId);
const hydrated = await task.hydrate();
// hydrated.project is a resolved Project instance
```

**Signature:** `hydrate(): Promise<Hydrated<this>>`

See [Type utilities](#type-utilities) for details on the `Hydrated<T>` type.

### `save()`

Persists pending changes. Creates an update transaction, or an insert if the model has no `id`.

```ts
task.title = "Updated title";
await task.save();
```

**Signature:** `save(): Promise<void>`

### `delete()`

Deletes this model instance.

```ts
await task.delete();
```

**Signature:** `delete(): Promise<void>`

### `archive()`

Soft-deletes by setting `archivedAt`.

```ts
await task.archive();
```

**Signature:** `archive(): Promise<void>`

### `unarchive()`

Restores a soft-deleted model.

```ts
await task.unarchive();
```

**Signature:** `unarchive(): Promise<void>`

### `changeSnapshot()`

Returns a snapshot of pending changes and their original values.

```ts
task.title = "New title";
const snapshot = task.changeSnapshot();
// snapshot.changes = { title: "New title" }
// snapshot.original = { title: "Old title" }
```

**Signature:** `changeSnapshot(): ChangeSnapshot`

```ts
interface ChangeSnapshot {
  changes: Record<string, unknown>;
  original: Record<string, unknown>;
}
```

### `clearChanges()`

Discards all tracked changes without persisting.

**Signature:** `clearChanges(): void`

### `toJSON()`

Serializes the model for persistence or transport.

```ts
const json = task.toJSON();
// { id: "abc-123", title: "My Task", status: "todo", ... }
```

**Signature:** `toJSON(): Record<string, unknown>`

### `_applyUpdate(changes)`

Applies changes without triggering change tracking. Used internally when applying server deltas.

**Signature:** `_applyUpdate(changes: Record<string, unknown>): void`

## Change tracking

Decorated properties track changes automatically. Setting a property records the original value so the model can produce a delta on save.

```ts
const task = await client.get<Task>("Task", taskId);
task.title = "Updated";
task.priority = 3;

const snapshot = task.changeSnapshot();
// snapshot.changes = { title: "Updated", priority: 3 }
// snapshot.original = { title: "Original", priority: 0 }

await task.save(); // Creates an update transaction, then clears changes
```

## Type utilities

### `Hydrated<T>`

Converts lazy reference fields to resolved types.

```ts
import type { Hydrated } from "@stratasync/core";

// Before hydration: task.project is LazyReference<Project>
// After hydration: task.project is Project
const hydrated: Hydrated<Task> = await task.hydrate();
```

### `LazyReference<T>`

A reference that may not yet be loaded. Access triggers lazy loading when the sync client is available.

```ts
import type { LazyReference } from "@stratasync/core";

const project = await resolvePromise(task.project);
```