AI agents: fetch the documentation index at llms.txt. Markdown versions are available by appending .md to any page URL, including this page's markdown.
Model base class
The Model base class provides change tracking, hydration, serialization, and CRUD operations for synced entities.
Every synced entity extends Model. Decorators register it with the ModelRegistry and wire it into the sync lifecycle.
Creating a model
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.
__dataholds raw backing data.storeis 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.
const task = await client.get<Task>("Task", taskId);
const hydrated = await task.hydrate();
// hydrated.project is a resolved Project instanceSignature: hydrate(): Promise<Hydrated<this>>
See 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.
task.title = "Updated title";
await task.save();Signature: save(): Promise<void>
delete()
Deletes this model instance.
await task.delete();Signature: delete(): Promise<void>
archive()
Soft-deletes by setting archivedAt.
await task.archive();Signature: archive(): Promise<void>
unarchive()
Restores a soft-deleted model.
await task.unarchive();Signature: unarchive(): Promise<void>
changeSnapshot()
Returns a snapshot of pending changes and their original values.
task.title = "New title";
const snapshot = task.changeSnapshot();
// snapshot.changes = { title: "New title" }
// snapshot.original = { title: "Old title" }Signature: changeSnapshot(): ChangeSnapshot
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.
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.
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 changesType utilities
Hydrated<T>
Converts lazy reference fields to resolved types.
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.
import type { LazyReference } from "@stratasync/core";
const project = await resolvePromise(task.project);