Skip to content

Commit 5cf6749

Browse files
Merge pull request #8 from Couchbase-Ecosystem/rn-v1
Update for React Native version 1.0.0 docs
2 parents 1b557c2 + c8d2efa commit 5cf6749

14 files changed

Lines changed: 1334 additions & 221 deletions

File tree

docs/DataSync/remote-sync-gateway.md

Lines changed: 209 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -130,37 +130,97 @@ If you’re using a Sync Gateway release that is older than version 3.1, you won
130130
#### Example 1. Replication configuration and initialization
131131

132132
```typescript
133-
//assumes you are running sync gateway locally, if you are
134-
//running app services, replace enpoint with proper url and creditentials
135-
const target = new URLEndpoint('ws://localhost:4984/projects');
136-
const auth = new BasicAuthenticator('demo@example.com', 'P@ssw0rd12');
137-
const config = new ReplicatorConfiguration(target);
138-
config.addCollection(collectionName);
139-
config.setAuthenticator(auth);
140-
141-
const replicator = await Replicator.create(config);
142-
143-
//listen to the replicator change events
144-
const token = await replicator.addChangeListener((change) => {
145-
//check to see if there was an error
146-
const error = change.status.getError();
147-
if (error !== undefined) {
148-
//do something with the error
149-
}
150-
//get the status of the replicator using ReplicatorActivityLevel enum
151-
if (change.status.getActivityLevel() === ReplicatorActivityLevel.IDLE) {
152-
//do something because the replicator is now IDLE
153-
}
154-
});
155-
156-
// start the replicator without making a new checkpoint
157-
await replicator.start(false);
158-
159-
//remember you must clean up the replicator when done with it by
160-
//doing the following lines
161-
162-
//await replicator.removeChangeListener(token);
163-
//await replicator.stop();
133+
import {
134+
ReplicatorConfiguration,
135+
CollectionConfiguration,
136+
URLEndpoint,
137+
BasicAuthenticator,
138+
Replicator,
139+
ListenerToken
140+
} from 'cbl-reactnative';
141+
142+
// Create endpoint and authenticator
143+
const endpoint = new URLEndpoint('ws://localhost:4984/projects');
144+
const auth = new BasicAuthenticator('demo@example.com', 'P@ssw0rd12');
145+
146+
// NEW API: Create collection configuration
147+
const collectionConfig = new CollectionConfiguration(collection);
148+
149+
// Pass collection configurations in constructor
150+
const config = new ReplicatorConfiguration(
151+
[collectionConfig], // Collections passed during initialization
152+
endpoint
153+
);
154+
155+
config.setAuthenticator(auth);
156+
157+
// Create replicator
158+
const replicator = await Replicator.create(config);
159+
160+
// Listen to replicator change events
161+
const token: ListenerToken = await replicator.addChangeListener((change) => {
162+
// Check for errors
163+
const error = change.status.getError();
164+
if (error) {
165+
console.error('Replication error:', error);
166+
}
167+
168+
// Check activity level
169+
if (change.status.getActivityLevel() === 3) { // IDLE
170+
console.log('Replication is idle');
171+
}
172+
});
173+
174+
// Start replication
175+
await replicator.start(false);
176+
177+
// Remember to clean up when done:
178+
// await token.remove();
179+
// await replicator.stop();
180+
```
181+
182+
:::important Version 1.0 API Change
183+
Collections are now passed during `ReplicatorConfiguration` construction using `CollectionConfiguration` objects.
184+
185+
**NEW API (Recommended):**
186+
```typescript
187+
const collectionConfig = new CollectionConfiguration(collection);
188+
const config = new ReplicatorConfiguration([collectionConfig], endpoint);
189+
```
190+
191+
**OLD API (Deprecated):**
192+
```typescript
193+
const config = new ReplicatorConfiguration(endpoint);
194+
config.addCollection(collection); // Deprecated
195+
```
196+
197+
The `addCollection()` method is deprecated. It remains available for backward compatibility, but new applications should use the new constructor pattern. Existing applications are strongly encouraged to migrate.
198+
:::
199+
200+
#### Example 1b. Multiple Collections
201+
202+
The new API allows each collection to have its own replication settings:
203+
204+
```typescript
205+
import { CollectionConfiguration } from 'cbl-reactnative';
206+
207+
// Configure users collection
208+
const usersConfig = new CollectionConfiguration(usersCollection)
209+
.setChannels(['public', 'users']);
210+
211+
// Configure orders collection with different settings
212+
const ordersConfig = new CollectionConfiguration(ordersCollection)
213+
.setChannels(['orders', 'admin'])
214+
.setDocumentIDs(['order-1', 'order-2']); // Only specific documents
215+
216+
// Pass both configurations during initialization
217+
const config = new ReplicatorConfiguration(
218+
[usersConfig, ordersConfig],
219+
endpoint
220+
);
221+
222+
config.setAuthenticator(auth);
223+
const replicator = await Replicator.create(config);
164224
```
165225

166226
## Configure
@@ -662,15 +722,68 @@ The returned *ReplicationStatus* structure comprises:
662722
#### Example 14. Monitor replication
663723

664724
```typescript
665-
// Optionally add a change listener
666-
// Retain token for use in deletion
667-
const token = replicator.addChangeListener((change) => {
668-
if (change.status.getActivityLevel() === 'STOPPED') {
669-
console.log("Replication stopped");
670-
} else {
671-
console.log(`Replicator is currently : ${change.status.getActivityLevel()}`);
672-
}
725+
import { ListenerToken } from 'cbl-reactnative';
726+
727+
const token: ListenerToken = await replicator.addChangeListener((change) => {
728+
const status = change.status;
729+
const activityLevel = status.getActivityLevel();
730+
const progress = status.getProgress();
731+
732+
const levelNames = ['stopped', 'offline', 'connecting', 'idle', 'busy'];
733+
console.log(`Status: ${levelNames[activityLevel]}`);
734+
console.log(`Progress: ${progress.getCompleted()}/${progress.getTotal()}`);
735+
});
736+
737+
// Remove listener when done
738+
await token.remove();
739+
```
740+
741+
### Replicator Status Data Structure
742+
743+
When replication status changes, your callback receives a `ReplicatorStatusChange` object:
744+
745+
```typescript
746+
interface ReplicatorStatusChange {
747+
status: ReplicatorStatus;
748+
}
749+
```
750+
751+
**ReplicatorStatus Methods:**
752+
- `getActivityLevel()` - Returns 0-4 (see activity levels table below)
753+
- `getProgress()` - Returns ReplicatorProgress object
754+
- `getError()` - Returns error message string or undefined
755+
756+
**ReplicatorProgress Methods:**
757+
- `getCompleted()` - Returns number of changes completed
758+
- `getTotal()` - Returns total number of changes
759+
760+
#### Example 14b. Advanced Replication Status Monitoring
761+
762+
```typescript
763+
import { ListenerToken, ReplicatorActivityLevel } from 'cbl-reactnative';
764+
765+
const token: ListenerToken = await replicator.addChangeListener((change) => {
766+
const status = change.status;
767+
const level = status.getActivityLevel();
768+
const progress = status.getProgress();
769+
770+
console.log(`Activity: ${level}`);
771+
console.log(`Progress: ${progress.getCompleted()}/${progress.getTotal()}`);
772+
773+
if (status.getError()) {
774+
console.error('Replication error:', status.getError());
775+
}
776+
777+
// Check specific states
778+
if (level === ReplicatorActivityLevel.IDLE) {
779+
console.log('Sync complete');
780+
} else if (level === ReplicatorActivityLevel.BUSY) {
781+
console.log('Syncing data...');
782+
}
673783
});
784+
785+
// Remove when done
786+
await token.remove();
674787
```
675788

676789
### Replication States
@@ -701,37 +814,73 @@ On other platforms, Couchbase Lite doesn’t react to OS backgrounding or foregr
701814

702815
You can choose to register for document updates during a replication.
703816

817+
#### When to Use Document Listeners
818+
819+
- Track which specific documents are syncing
820+
- Detect replication conflicts
821+
- Handle document-level replication errors
822+
- Monitor deleted documents during sync
823+
824+
#### Document Replication Data Structure
825+
826+
```typescript
827+
interface DocumentReplicationRepresentation {
828+
isPush: boolean; // true = push, false = pull
829+
documents: ReplicatedDocument[];
830+
}
831+
832+
interface ReplicatedDocument {
833+
id: string; // Document ID
834+
scopeName: string; // Scope name
835+
collectionName: string; // Collection name
836+
flags: string[]; // ['DELETED', 'ACCESS_REMOVED']
837+
error?: { message: string }; // Present if replication failed
838+
}
839+
```
840+
841+
**Document Flags:**
842+
- `'DELETED'` - Document was deleted
843+
- `'ACCESS_REMOVED'` - User lost access to document
844+
704845
For example, the code snippet in [Example 15](#example-15-register-a-document-listener) registers a listener to monitor document replication performed by the replicator referenced by the variable `replicator`. It prints the document ID of each document received and sent. Stop the listener as shown in [Example 16](#example-16-stop-document-listener).
705846

706847
#### Example 15. Register a document listener
707848

708849
```typescript
709-
const token = await replicator.addDocumentChangeListener((replication) => {
710-
console.log(`Replication type :: ${replication.isPush ? "Push" : "Pull"}`);
850+
import { ListenerToken } from 'cbl-reactnative';
851+
852+
const token: ListenerToken = await replicator.addDocumentChangeListener((replication) => {
853+
const direction = replication.isPush ? "Push" : "Pull";
854+
console.log(`${direction}: ${replication.documents.length} documents`);
855+
711856
for (const document of replication.documents) {
712857
if (document.error === undefined) {
713-
console.log(`Doc ID :: ${document.id}`);
858+
console.log(` Doc ID: ${document.id}`);
859+
714860
if (document.flags.includes('DELETED')) {
715-
console.log("Successfully replicated a deleted document");
861+
console.log(" Successfully replicated a deleted document");
716862
}
717863
} else {
718-
console.error("Error replicating document:", document.error);
864+
console.error(` Error: ${document.error.message}`);
719865
}
720866
}
721867
});
722868

723-
// Start the replicator without resetting the checkpoint
869+
// Start the replicator
724870
await replicator.start(false);
725871
```
726872

727873
#### Example 16. Stop document listener
728874

729-
This code snippet shows how to stop the document listener using the token from the previous example.
730-
731875
```typescript
732-
await this.replicator.removeChangeListener(token);
876+
// Remove listener using new API
877+
await token.remove();
733878
```
734879

880+
:::caution Deprecated
881+
The `replicator.removeChangeListener(token)` method is deprecated. It remains available for backward compatibility, but new applications should use `token.remove()`. Existing applications are strongly encouraged to migrate.
882+
:::
883+
735884
### Document Access Removal Behavior
736885

737886
When access to a document is removed on Sync Gateway (see: Sync Gateway’s [Sync Function](https://docs.couchbase.com/sync-gateway/current/sync-function-api.html)), the document replication listener sends a notification with the `AccessRemoved` flag set to `true` and subsequently purges the document from the database.
@@ -763,10 +912,10 @@ You can find further information on database operations in [Databases](../databa
763912

764913
```typescript
765914
// Remove the change listener
766-
await this.replicator.removeChangeListener(token)
915+
await token.remove()
767916

768917
// Stop the replicator
769-
await this.replicator.stop()
918+
await replicator.stop()
770919
```
771920

772921
Here we initiate the stopping of the replication using the `stop()` method. It will stop any active `change listener` once the replication is stopped.
@@ -819,15 +968,20 @@ As always, when there is a problem with replication, logging is your friend. You
819968

820969
#### Example 21. Set logging verbosity
821970

822-
823971
```typescript
824-
// Verbose / Replicator
825-
database.setLogLevel(LogDomain.REPLICATOR, Loglevel.VERBOSE);
972+
import { LogSinks, LogLevel, LogDomain } from 'cbl-reactnative';
826973

827-
// Verbose / Network
828-
database.setLogLevel(LogDomain.NETWORK, Loglevel.VERBOSE);
974+
// Verbose / Replicator and Network
975+
await LogSinks.setConsole({
976+
level: LogLevel.VERBOSE,
977+
domains: [LogDomain.REPLICATOR, LogDomain.NETWORK]
978+
});
829979
```
830980

981+
:::caution
982+
Enable VERBOSE logging only during development or debugging. Avoid using it in production builds.
983+
:::
984+
831985
For more on troubleshooting with logs, see: [Using Logs](../Troubleshooting/using-logs.md).
832986

833987
### Authentication Errors
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"label": "Migration",
3+
"position": 1,
4+
"collapsible": true,
5+
"collapsed": false
6+
}
7+

0 commit comments

Comments
 (0)