@nozbe/watermelondb
Version:
Build powerful React Native and React web apps that scale from hundreds to tens of thousands of records and remain fast
94 lines (79 loc) • 3.99 kB
TypeScript
import { $Exact } from '../types'
import type { Database, RecordId, TableName, Model } from '..'
import type { DirtyRaw } from '../RawRecord'
import type { SchemaVersion } from '../Schema'
import type { MigrationSyncChanges } from '../Schema/migrations/getSyncChanges'
export type Timestamp = number
export type SyncTableChangeSet = $Exact<{
created: DirtyRaw[]
updated: DirtyRaw[]
deleted: RecordId[]
}>
export type SyncDatabaseChangeSet = { [tableName: TableName<any>]: SyncTableChangeSet }
export type SyncLocalChanges = $Exact<{ changes: SyncDatabaseChangeSet; affectedRecords: Model[] }>
export type SyncPullArgs = $Exact<{
lastPulledAt?: Timestamp
schemaVersion: SchemaVersion
migration: MigrationSyncChanges
}>
export type SyncPullResult =
| $Exact<{ changes: SyncDatabaseChangeSet; timestamp: Timestamp }>
| $Exact<{ syncJson: string }>
| $Exact<{ syncJsonId: number }>
export type SyncRejectedIds = { [tableName: TableName<any>]: RecordId[] }
export type SyncPushArgs = $Exact<{ changes: SyncDatabaseChangeSet; lastPulledAt: Timestamp }>
export type SyncPushResult = $Exact<{ experimentalRejectedIds?: SyncRejectedIds }>
type SyncConflict = $Exact<{ local: DirtyRaw; remote: DirtyRaw; resolved: DirtyRaw }>
export type SyncLog = {
startedAt?: Date
lastPulledAt?: number
lastPulledSchemaVersion?: SchemaVersion
migration?: MigrationSyncChanges
newLastPulledAt?: number
resolvedConflicts?: SyncConflict[]
rejectedIds?: SyncRejectedIds
finishedAt?: Date
remoteChangeCount?: number
localChangeCount?: number
phase?: string // NOTE: an textual information, not a stable API!
error?: Error
}
export type SyncConflictResolver = (
table: TableName<any>,
local: DirtyRaw,
remote: DirtyRaw,
resolved: DirtyRaw,
) => DirtyRaw
export type SyncArgs = $Exact<{
database: Database
pullChanges: (_: SyncPullArgs) => Promise<SyncPullResult>
pushChanges?: (_: SyncPushArgs) => Promise<SyncPushResult | undefined | void>
// version at which support for migration syncs was added - the version BEFORE first syncable migration
migrationsEnabledAtVersion?: SchemaVersion
sendCreatedAsUpdated?: boolean
log?: SyncLog
// Advanced (unsafe) customization point. Useful when you have subtle invariants between multiple
// columns and want to have them updated consistently, or to implement partial sync
// It's called for every record being updated locally, so be sure that this function is FAST.
// If you don't want to change default behavior for a given record, return `resolved` as is
// Note that it's safe to mutate `resolved` object, so you can skip copying it for performance.
conflictResolver?: SyncConflictResolver
// commits changes in multiple batches, and not one - temporary workaround for memory issue
_unsafeBatchPerCollection?: boolean
// Advanced optimization - pullChanges must return syncJson or syncJsonId to be processed by native code.
// This can only be used on initial (login) sync, not for incremental syncs.
// This can only be used with SQLiteAdapter with JSI enabled.
// The exact API may change between versions of WatermelonDB.
// See documentation for more details.
unsafeTurbo?: boolean
// Called after pullChanges with whatever was returned by pullChanges, minus `changes`. Useful
// when using turbo mode
onDidPullChanges?: (_: Object) => Promise<void>
// Called after pullChanges is done, but before these changes are applied. Some stats about the pulled
// changes are passed as arguments. An advanced user can use this for example to show some UI to the user
// when processing a very large sync (could be useful for replacement syncs). Note that remote change count
// is NaN in turbo mode.
onWillApplyRemoteChanges?: (info: $Exact<{ remoteChangeCount: number }>) => Promise<void>
}>
export function synchronize(args: SyncArgs): Promise<void>
export function hasUnsyncedChanges({ database }: $Exact<{ database: Database }>): Promise<boolean>