Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/mainser/cindel/llms.txt

Use this file to discover all available pages before exploring further.

Cindel’s sync engine lets your app continue using the same typed collections, queries, transactions, and watchers it always has. Under the hood, Cindel records every local mutation in a durable internal outbox and runs a background scheduler that calls your CindelSyncAdapter to push pending mutations and pull remote changes. Sync is configured once — at Cindel.open time — via CindelSyncConfig. There is no public API for manually triggering, pausing, or stopping sync after the database is open.
This is an early integration API, not a complete production conflict-resolution layer. Before using it for critical data, validate your backend’s idempotency, checkpoint, rejection, reset, and conflict policies with your own app flows. The sync API may change before it is marked stable.

CindelSyncConfig

CindelSyncConfig is passed to Cindel.open via the sync parameter to enable the sync engine for a database. All fields except adapter are optional.
final db = await Cindel.open(
  directory: dir.path,
  schemas: [UserSchema],
  sync: CindelSyncConfig(
    adapter: AppSyncAdapter(),
    onStatusChanged: (status) {
      // Reflect sync phase or pending count in your UI.
    },
    onError: (error, stackTrace) {
      // Report background sync failures.
    },
  ),
);

Constructor Parameters

adapter
CindelSyncAdapter
required
Backend adapter implemented by the application. Cindel calls adapter.push and adapter.pull on the background scheduler interval. See CindelSyncAdapter for the full contract.
clientId
String?
Stable identifier for this database instance used by the backend to deduplicate retried mutations. When omitted, Cindel generates and persists an internal id for the database directory, reusing it across app restarts. Supply an explicit value when your backend already tracks devices or installations.
onStatusChanged
void Function(CindelSyncStatus)?
Callback invoked whenever the internal sync scheduler changes phase. Use it to show an offline indicator, a pending-mutation badge, or a last-synced timestamp in your UI. This callback is informational only — it does not provide control over the sync engine.
onError
void Function(Object, StackTrace)?
Callback invoked when a background sync cycle throws an unhandled error. Use it to report failures to a crash-reporting service or to surface transient network errors without interrupting the app.
autoStart
bool
default:"true"
When true, the internal scheduler starts automatically after Cindel.open returns. Set to false if you need to defer background sync (for example, until the user has authenticated).
interval
Duration
default:"Duration(seconds: 5)"
How often the background scheduler wakes to run a push/pull cycle when the app is active. Shorter intervals provide lower latency at the cost of more network activity.
batchSize
int
default:"100"
Maximum number of pending mutations included in a single push call. Larger batches reduce round-trips; smaller batches limit payload size and make retries cheaper.

CindelSyncAdapter

CindelSyncAdapter is the abstract interface your application implements to connect Cindel to a backend. Cindel calls push and pull on every background scheduler cycle.
abstract interface class CindelSyncAdapter {
  Future<CindelPushResult> push(CindelPushRequest request);
  Future<CindelPullResult> pull(CindelPullRequest request);
}

Methods

push(CindelPushRequest)Future<CindelPushResult>

Called by Cindel to deliver pending local mutations to the backend. The backend should apply mutations idempotently using mutationId as the deduplication key and return the ids it has durably accepted. Mutations that the backend will never accept should be returned in rejectedMutations.

pull(CindelPullRequest)Future<CindelPullResult>

Called by Cindel to fetch remote changes since request.checkpoint. A null checkpoint signals an initial pull. The backend should return all changes the client has not yet seen, along with a new checkpoint that the client will supply on the next pull.

CindelPushRequest

Delivered to CindelSyncAdapter.push by the internal scheduler.

Properties

clientId
String
Stable client id for this database — either the value supplied in CindelSyncConfig.clientId or the one Cindel persisted internally.
lastPulledCheckpoint
String?
The last checkpoint successfully applied to the local database by a prior pull. null if no pull has completed yet. Backends can use this to detect push/pull ordering issues.
schemaVersionByCollection
Map<String, int>
Maps each registered application collection name to its current schema version. Backends can use this to detect mismatched client deployments.
mutations
List<CindelSyncMutation>
Ordered list of pending local mutations selected from the internal outbox, up to CindelSyncConfig.batchSize entries.

CindelPushResult

Returned by CindelSyncAdapter.push.

Properties

acceptedMutationIds
Set<String>
required
Mutation ids the backend has durably accepted. Cindel removes these from the outbox after a successful push cycle. Any mutation id not in this set (and not in rejectedMutations) is retried on the next push.
rejectedMutations
List<CindelSyncRejectedMutation>
default:"[]"
Mutations the backend will permanently never accept — for example, operations on deleted documents or authorization failures. Cindel discards these from the outbox so they are never retried.
correctedChanges
List<CindelRemoteChange>
default:"[]"
Backend truth to apply locally after optimistic mutations are accepted. Use this to reconcile any discrepancy between the optimistic local write and the canonical server state — for example, a server-generated timestamp or a normalized field value.
checkpoint
String?
Optional checkpoint produced while handling this push. When present, Cindel records it as the last pulled checkpoint, avoiding a redundant pull for changes the backend already applied as part of this push.

CindelPullRequest

Delivered to CindelSyncAdapter.pull by the internal scheduler.

Properties

clientId
String
Stable client id for this database.
checkpoint
String?
Last checkpoint applied locally. null on an initial pull. The backend should return all changes that occurred after this checkpoint.
schemaVersionByCollection
Map<String, int>
Maps each registered application collection name to its current schema version.
collections
Set<String>
Application collection names this database can accept changes for. The backend can omit changes for collections not in this set.

CindelPullResult

Returned by CindelSyncAdapter.pull.

Properties

checkpoint
String
required
New checkpoint that covers all returned changes. Cindel persists this value and passes it as checkpoint on the next pull. Your backend must always return a valid non-null checkpoint.
changes
List<CindelRemoteChange>
required
Remote changes to apply to the local database. Each element is a CindelRemoteUpsert, CindelRemoteDelete, or CindelRemoteReplaceLinks. Cindel applies changes in the order they appear in the list.
resetRequired
bool
default:"false"
When true, the backend is requesting that the client reset its local state before continuing sync — for example, after a checkpoint expires or a schema-breaking migration occurs server-side. Your application must handle the reset flow explicitly; Cindel surfaces this flag but does not perform the reset automatically.

CindelSyncStatus

Delivered to CindelSyncConfig.onStatusChanged whenever the internal sync scheduler changes state.

Properties

phase
CindelSyncPhase
Current phase of the internal sync scheduler. See CindelSyncPhase for values.
pendingCount
int
Number of durable local mutations still waiting for adapter acceptance. Display this value as an “unsynced changes” badge or counter in your UI.
lastSyncAt
DateTime?
UTC timestamp of the last completed sync cycle. null before a cycle completes successfully.
lastError
Object?
The most recent background error associated with this status event, or null if the cycle succeeded. This field is informational; the same error is also delivered to CindelSyncConfig.onError.

CindelSyncPhase

High-level phase of the background sync scheduler.
enum CindelSyncPhase { idle, syncing, offline, error }
ValueDescription
idleScheduler is active but no cycle is running. The database is up to date as of the last cycle.
syncingA push/pull cycle is currently in progress.
offlineThe adapter returned a network-level error; the scheduler is backing off.
errorA non-network error occurred during the last cycle.

Supporting Types

CindelSyncMutation

Represents a single local mutation sent to the backend in a push request.
PropertyTypeDescription
mutationIdStringStable id used by the backend to deduplicate retried pushes.
clientIdStringClient id that created this mutation.
sequenceintMonotonic local sequence number for this client.
collectionStringApplication collection affected by this mutation.
operationCindelSyncOperationOperation kind: upsert, delete, or replaceLinks.
documentIdint?Document id for upsert and delete operations.
documentMap<String, Object?>?Canonical document snapshot for upsert operations.
linkNameString?Link field name for replaceLinks operations.
targetCollectionString?Target collection for replaceLinks operations.
targetIdsList<int>Complete replacement id set for replaceLinks operations.
baseCheckpointString?Checkpoint known when this mutation was recorded locally.

CindelSyncOperation

enum CindelSyncOperation { upsert, delete, replaceLinks }
ValueDescription
upsertInsert or update a document. The canonical snapshot is in document.
deleteDelete the document identified by documentId.
replaceLinksReplace the full link set identified by linkName and targetCollection on documentId.

CindelRemoteChange (sealed)

Base class for remote changes returned by pull or backend corrections. Three concrete subtypes are defined: CindelRemoteUpsert — Insert or update a document.
PropertyTypeDescription
collectionStringTarget collection.
idintDocument id to write.
documentMap<String, Object?>Canonical document snapshot to apply.
CindelRemoteDelete — Delete a document.
PropertyTypeDescription
collectionStringTarget collection.
idintDocument id to delete.
CindelRemoteReplaceLinks — Replace a link set on a document.
PropertyTypeDescription
collectionStringSource collection.
idintSource document id whose link field should be replaced.
linkNameStringLink field name on the source collection.
targetCollectionStringTarget collection for linked ids.
targetIdsList<int>Complete replacement id set for this link.

CindelSyncRejectedMutation

Returned in CindelPushResult.rejectedMutations for mutations the backend will never accept.
PropertyTypeDescription
mutationIdStringId of the rejected mutation.
reasonStringBackend-provided human-readable rejection reason.

AppSyncAdapter Implementation Example

The following example is drawn from the README. It shows the minimal structure of a working CindelSyncAdapter that accepts all mutations and returns an empty pull result.
final class AppSyncAdapter implements CindelSyncAdapter {
  @override
  Future<CindelPushResult> push(CindelPushRequest request) async {
    // Send request.mutations to your backend idempotently.
    // Use mutation.mutationId as the deduplication key.
    return CindelPushResult(
      acceptedMutationIds: {
        for (final mutation in request.mutations) mutation.mutationId,
      },
    );
  }

  @override
  Future<CindelPullResult> pull(CindelPullRequest request) async {
    // Return backend changes after request.checkpoint.
    // A null checkpoint signals an initial pull.
    return const CindelPullResult(checkpoint: '0', changes: []);
  }
}
Pass the adapter to Cindel.open:
final db = await Cindel.open(
  directory: dir.path,
  schemas: [UserSchema],
  sync: CindelSyncConfig(
    adapter: AppSyncAdapter(),
    onStatusChanged: (status) {
      // Show offline/syncing/pending state in your UI.
    },
    onError: (error, stackTrace) {
      // Report background sync failures.
    },
  ),
);

Build docs developers (and LLMs) love