PouchDB's replication system provides comprehensive data synchronization between local and remote databases. It supports both one-way replication and bidirectional sync with extensive configuration options, conflict resolution, filtering capabilities, and robust error handling.
Replicates data from a source database to a target database using the static method.
/**
* Replicate from source to target database
* @param source - Source database (PouchDB instance or URL string)
* @param target - Target database (PouchDB instance or URL string)
* @param options - Replication configuration options
* @param callback - Optional callback function (err, result) => void
* @returns Replication object with event emitter interface
*/
PouchDB.replicate(source, target, options, callback);Usage Examples:
// Basic replication
const replication = PouchDB.replicate('local-db', 'https://example.com/remote-db');
// Continuous replication with options
const replication = PouchDB.replicate(localDB, remoteDB, {
live: true,
retry: true,
batch_size: 100
});
// One-time replication with callback
PouchDB.replicate(sourceDB, targetDB, {
filter: 'myfilter/active-docs'
}, (err, result) => {
if (err) {
console.error('Replication failed:', err);
} else {
console.log('Replication completed:', result);
}
});Performs bidirectional synchronization between two databases using the static method.
/**
* Bidirectional sync between two databases
* @param source - First database (PouchDB instance or URL string)
* @param target - Second database (PouchDB instance or URL string)
* @param options - Sync configuration options
* @param callback - Optional callback function (err, result) => void
* @returns Sync object with event emitter interface
*/
PouchDB.sync(source, target, options, callback);Usage Examples:
// Basic bidirectional sync
const sync = PouchDB.sync(localDB, remoteDB);
// Continuous sync with custom options
const sync = PouchDB.sync(localDB, 'https://example.com/db', {
live: true,
retry: true,
push: { batch_size: 50 },
pull: { batch_size: 100 }
});
// Sync with separate push/pull configuration
const sync = PouchDB.sync(localDB, remoteDB, {
push: {
filter: 'myfilter/outgoing',
live: true
},
pull: {
filter: 'myfilter/incoming',
live: true
}
});Replicates from the current database instance to a target database.
/**
* Replicate this database to target
* @param target - Target database (PouchDB instance or URL string)
* @param options - Replication configuration options
* @param callback - Optional callback function (err, result) => void
* @returns Replication object with event emitter interface
*/
db.replicate.to(target, options, callback);Usage Examples:
// Push local changes to remote
const replication = localDB.replicate.to(remoteDB, {
live: true,
retry: true
});
// Filtered push replication
const replication = localDB.replicate.to('https://example.com/db', {
filter: (doc) => doc.type === 'public',
live: true
});Replicates from a source database to the current database instance.
/**
* Replicate from source to this database
* @param source - Source database (PouchDB instance or URL string)
* @param options - Replication configuration options
* @param callback - Optional callback function (err, result) => void
* @returns Replication object with event emitter interface
*/
db.replicate.from(source, options, callback);Usage Examples:
// Pull remote changes to local
const replication = localDB.replicate.from(remoteDB, {
live: true,
retry: true
});
// Pull specific documents
const replication = localDB.replicate.from('https://example.com/db', {
doc_ids: ['doc1', 'doc2', 'doc3']
});Performs bidirectional synchronization between the current database instance and a target database.
/**
* Bidirectional sync with target database
* @param target - Target database (PouchDB instance or URL string)
* @param options - Sync configuration options
* @param callback - Optional callback function (err, result) => void
* @returns Sync object with event emitter interface
*/
db.sync(target, options, callback);Usage Examples:
// Basic sync
const sync = localDB.sync(remoteDB);
// Continuous sync with error handling
const sync = localDB.sync('https://example.com/db', {
live: true,
retry: true
});
sync.on('error', (err) => {
console.error('Sync error:', err);
});All replication and sync objects emit events that can be listened to for monitoring progress and handling errors.
/**
* Replication change event - fired when documents are replicated
* @param info - Change information object
*/
replication.on('change', (info) => {
// info.direction: 'push' | 'pull' (for sync operations)
// info.change.docs: array of changed documents
// info.change.docs_read: number of documents read
// info.change.docs_written: number of documents written
});
/**
* Replication complete event - fired when replication finishes
* @param info - Completion information object
*/
replication.on('complete', (info) => {
// info.ok: boolean indicating success
// info.start_time: replication start timestamp
// info.end_time: replication end timestamp
// info.docs_read: total documents read
// info.docs_written: total documents written
});
/**
* Replication error event - fired when replication encounters an error
* @param err - Error object
*/
replication.on('error', (err) => {
// err.status: HTTP status code (if applicable)
// err.name: error name
// err.message: error message
});
/**
* Replication denied event - fired when document replication is denied
* @param err - Denial information
*/
replication.on('denied', (err) => {
// err.id: document ID that was denied
// err.reason: reason for denial
});
/**
* Replication active event - fired when replication becomes active
*/
replication.on('active', () => {
// Replication is actively transferring data
});
/**
* Replication paused event - fired when replication is paused
* @param err - Error that caused pause (if any)
*/
replication.on('paused', (err) => {
// Replication has been paused (may resume automatically with retry: true)
});const replication = PouchDB.replicate(localDB, remoteDB, {
live: true,
retry: true
});
// Track replication progress
replication.on('change', (info) => {
console.log(`Replicated ${info.change.docs_written} documents`);
info.change.docs.forEach((doc) => {
console.log(`Document updated: ${doc._id}`);
});
});
// Handle completion
replication.on('complete', (info) => {
console.log('Replication completed successfully');
console.log(`Total documents: ${info.docs_written}`);
});
// Handle errors
replication.on('error', (err) => {
console.error('Replication error:', err);
if (err.status === 401) {
console.error('Authentication required');
}
});
// Monitor active/paused status
replication.on('active', () => {
console.log('Replication is active');
});
replication.on('paused', (err) => {
if (err) {
console.log('Replication paused due to error:', err);
} else {
console.log('Replication paused');
}
});/**
* Cancel an ongoing replication
*/
replication.cancel();Usage Example:
const replication = PouchDB.replicate(localDB, remoteDB, { live: true });
// Cancel after 30 seconds
setTimeout(() => {
replication.cancel();
console.log('Replication canceled');
}, 30000);// Check if replication is cancelled
if (replication.cancelled) {
console.log('Replication has been cancelled');
}interface ReplicationOptions {
/** Enable continuous replication that stays open and listens for changes */
live?: boolean;
/** Automatically retry replication on failure */
retry?: boolean;
/** Number of documents to process in each batch */
batch_size?: number;
/** Maximum number of concurrent batches */
batches_limit?: number;
/** Use checkpoints to resume interrupted replications */
checkpoint?: boolean;
/** Filter function or design document filter name */
filter?: string | ((doc: any, params: any) => boolean);
/** Array of specific document IDs to replicate */
doc_ids?: string[];
/** Parameters to pass to filter functions */
query_params?: { [key: string]: any };
/** Include or exclude document conflicts */
style?: 'main_only' | 'all_docs';
/** Authentication credentials */
auth?: {
username: string;
password: string;
};
/** Custom headers for HTTP requests */
headers?: { [key: string]: string };
/** HTTP timeout in milliseconds */
timeout?: number;
/** Heartbeat interval for continuous replication */
heartbeat?: number;
}interface SyncOptions extends ReplicationOptions {
/** Separate options for push replication */
push?: ReplicationOptions;
/** Separate options for pull replication */
pull?: ReplicationOptions;
}// Filtered replication with custom function
const replication = PouchDB.replicate(localDB, remoteDB, {
live: true,
filter: (doc) => {
// Only replicate documents modified in last 24 hours
const dayAgo = Date.now() - (24 * 60 * 60 * 1000);
return new Date(doc.modified).getTime() > dayAgo;
}
});
// Replication with authentication and custom headers
const replication = PouchDB.replicate(localDB, 'https://example.com/db', {
auth: {
username: 'myuser',
password: 'mypassword'
},
headers: {
'Custom-Header': 'custom-value'
},
timeout: 30000,
batch_size: 50
});
// Asymmetric sync with different push/pull settings
const sync = PouchDB.sync(localDB, remoteDB, {
push: {
filter: 'myfilter/outgoing',
batch_size: 25
},
pull: {
filter: 'myfilter/incoming',
batch_size: 100
},
live: true,
retry: true
});interface ReplicationError {
/** HTTP status code (if applicable) */
status?: number;
/** Error name/type */
name: string;
/** Human-readable error message */
message: string;
/** Detailed error information */
error?: any;
/** Error reason/cause */
reason?: string;
}const replication = PouchDB.replicate(localDB, remoteDB, {
live: true,
retry: true
});
replication.on('error', (err) => {
switch (err.status) {
case 401:
console.error('Authentication failed');
// Handle authentication error
break;
case 404:
console.error('Database not found');
// Handle missing database
break;
case 409:
console.error('Conflict occurred');
// Handle conflict
break;
default:
console.error('Replication error:', err.message);
// Handle other errors
}
});
// Network error handling
replication.on('paused', (err) => {
if (err) {
console.log('Replication paused due to error, will retry...');
// Replication will automatically retry if retry: true
}
});// Optimize for throughput
const replication = PouchDB.replicate(localDB, remoteDB, {
batch_size: 500, // Larger batches for better throughput
batches_limit: 10, // More concurrent batches
live: true,
retry: true
});
// Optimize for responsiveness
const replication = PouchDB.replicate(localDB, remoteDB, {
batch_size: 50, // Smaller batches for quicker updates
batches_limit: 5, // Fewer concurrent batches
heartbeat: 10000, // More frequent heartbeats
live: true
});
// Memory-conscious replication
const replication = PouchDB.replicate(localDB, remoteDB, {
batch_size: 100,
batches_limit: 2, // Limit memory usage
live: true,
retry: true
});