Clone
Full dataset retrieval for initial client setup.
Clone is the initial sync phase that downloads a complete dataset from the server to the client. It runs automatically on first launch or when a resource has not yet been hydrated.
How Clone Works
- The sync engine checks the hydration state of each resource.
- Resources with state
"notStarted"are marked as"hydrating". - A clone request is sent to the server with the list of resources to clone.
- The server returns all records for the requested resources, including join table data for many-many relations.
- Records are written to local storage and per-table cursors are set.
- Hydration state transitions to
"ready".
Server Endpoint
POST /datafn/cloneRequest body:
{
"clientId": "client-abc-123",
"tables": ["todos", "projects"],
"includeJoins": true
}Response:
{
"ok": true,
"data": {
"todos": [{ "id": "t1", "title": "Buy milk", "status": "active" }],
"projects": [{ "id": "p1", "name": "Work" }]
},
"cursors": {
"todos": "42",
"projects": "38"
},
"next": null
}Auto-Pagination
When a resource exceeds the configured page size, clone automatically paginates using cursor-based pagination:
sync: {
hydration: {
bootResources: ["todos", "projects"],
clonePageSize: 5000, // Global page size
},
}You can also set per-resource page sizes:
sync: {
hydration: {
bootResources: ["todos", "projects"],
clonePageSize: {
todos: 10000,
projects: 1000,
},
},
}During paginated clone, the engine sends requests with an afterId cursor and iterates until the server returns no more pages:
{
"clientId": "client-abc-123",
"tables": ["todos"],
"page": {
"table": "todos",
"afterId": "t500",
"limit": 5000
},
"includeJoins": true
}Selective Clone
You can clone a subset of resources instead of the entire schema:
// Clone only specific resources
await client.sync.clone(["todos", "projects"]);Resources marked as isRemoteOnly in the schema are excluded from clone operations.
Join Table Data
When includeJoins: true (the default), clone also downloads join rows for many-many relations. Join store keys follow the format fromResource.relationName.toResource, such as todos.tags.tags.
Events
Clone emits a sync_applied event on success:
client.events.on("sync_applied", (event) => {
if (event.context.phase === "clone") {
console.log("Cloned resources:", event.context.resources);
console.log("Cursors:", event.context.cursors);
}
});On failure, a sync_failed event is emitted with the error details:
client.events.on("sync_failed", (event) => {
if (event.context.phase === "clone") {
console.error("Clone failed:", event.context.error.message);
}
});