@cuongnt.kiotviet/syncgatewayclient
v1.0.29
Published
TypeScript client library for SyncGateway API
Readme
SyncGateway Web Client
A TypeScript client for synchronizing data with SyncGateway server.
Features
- Data version tracking
- Automatic sync planning
- Support for multiple data types
- Custom storage implementations
- Client settings persistence
- Automatic device detection
- Client identification
- Automatic client settings generation
- HTTP header management
- Context switching (tenant/branch)
- Data revision tracking
- Modified date tracking
- Automatic UUID generation
- Package version detection
- Chunked data processing
- Automatic error handling
Installation
npm install @cuongnt.kiotviet/syncgatewayclientUsage
Basic Setup
import { SyncGatewayClient } from '@cuongnt.kiotviet/syncgatewayclient';
const client = new SyncGatewayClient({
baseUrl: 'http://api.example.com',
tenantId: 1,
branchId: 1,
httpClient: new MyHttpClient(),
storage: new LocalStorageSync(1, 1), // Optional
clientId: 'custom-client-id', // Optional
clientVersion: '1.0.0', // Optional
clientType: 'mobile' // Optional
});Client Configuration
interface SyncGatewayClientConfig {
baseUrl: string;
tenantId: number;
branchId: number;
storage?: ISyncStorage;
httpClient: ISyncHttpClient;
clientId: string;
clientVersion: string;
clientType: string;
fetchIntervalMs?: number;
}Data Version Tracking
interface DataTrackingVersionItem {
dataType: string;
revision: string;
modifiedDate: Date | null;
}Sync Planning
interface SyncPlanItem {
dataType: string;
fromRevision: string;
fromModifiedDate: Date | null;
}
interface SyncPlan {
items: {
[dataType: string]: SyncPlanItem;
};
}
interface SyncPlanResponse {
syncSessionId: number;
plan: SyncPlan;
success: boolean;
error?: string;
}Data Types
interface CustomDataType<T = any> {
/** The name of the data type */
name: string;
/** The base URL endpoint for fetching data */
baseFetchUrl: string;
/** How to handle the data after fetching (Merge or Replace) */
saveOption: SaveOption;
/** Whether the data type uses revision tracking */
isUsingRevision: boolean;
/** Whether the data type uses modified date tracking */
isUsingModifiedDate: boolean;
/** The data repository implementation for this data type */
dataRepository: IDataRepository<T>;
}
interface SyncPullData<T> {
Data: T[];
RemovedIds: number[];
LatestRevision: string;
Timestamp: string;
}Sync Operations
interface SyncOperation {
dataType: string;
revision: string;
modifiedDate: Date | null;
data: any[];
deletedIds: string[];
}
interface SyncOperationResult {
success: boolean;
dataType: string;
updatedCount: number;
deletedCount: number;
error?: string;
}
interface CompletedSyncResult {
dataType: string;
revision: string;
modifiedDate: Date | null;
success: boolean;
updatedCount?: number;
deletedCount?: number;
error?: string;
}Error Handling
The client provides graceful error handling for all operations:
getSyncPlans: Returns aSyncPlanResponsewithsuccess: falseand error details if the server call failsexecuteSync: Returns an array ofCompletedSyncResultwhere each item indicates success/failure with error detailscommitSync: Returns an object withsuccess: booleanand optional error message
Example error handling:
// Get sync plans
const syncPlan = await client.getSyncPlans();
if (!syncPlan.success) {
console.error('Failed to get sync plans:', syncPlan.error);
// Use local plan as fallback
const localPlan = syncPlan.plan;
}
// Execute sync
const results = await client.executeSync(syncPlan);
const failedItems = results.filter(r => !r.success);
if (failedItems.length > 0) {
console.error('Some items failed to sync:', failedItems);
}
// Commit sync
const commitResult = await client.commitSync(syncPlan.syncSessionId, results);
if (!commitResult.success) {
console.error('Failed to commit sync:', commitResult.error);
}Storage Interface
interface ISyncStorage {
/**
* Save client settings
* @param key The key to store the settings under
* @param value The settings value to store
*/
saveSettings(key: string, value: any): Promise<void>;
/**
* Get client settings
* @param key The key to retrieve settings for
* @returns The stored settings value, or null if not found
*/
getSettings(key: string): Promise<any>;
}API Reference
SyncGatewayClient
Constructor
constructor(config: SyncGatewayClientConfig)Public Methods
start(): Promise<CompletedSyncResult[]>switchContext(tenantId: number, branchId: number, storage?: ISyncStorage): voidregisterStorage(storage: ISyncStorage): voidgetStorage(): ISyncStorageregisterCustomDataType<T>(dataType: string, baseFetchUrl: string, saveOption: SaveOption, dataRepository: IDataRepository<T>, isUsingRevision?: boolean, isUsingModifiedDate?: boolean): voidunregisterCustomDataType(dataTypeName: string): booleangetTenantId(): numbergetBranchId(): numberstopSyncSchedule(): void
The client provides a public API through these methods:
- Core Sync Operation:
// Start the sync process
const results = await client.start();- Context Management:
// Switch to a different tenant/branch
client.switchContext(newTenantId, newBranchId);
// Get current tenant and branch IDs
const tenantId = client.getTenantId();
const branchId = client.getBranchId();- Storage Management:
// Register custom storage
client.registerStorage(newStorage);
// Get current storage
const storage = client.getStorage();- Data Type Management:
// Register a new data type
client.registerCustomDataType(
'myDataType',
'/api/my-data',
SaveOption.Merge,
new MyDataRepository(),
true, // isUsingRevision
true // isUsingModifiedDate
);
// Unregister a data type
client.unregisterCustomDataType('myDataType');- Schedule Management:
// Stop the sync schedule
client.stopSyncSchedule();Example complete usage:
const client = new SyncGatewayClient({
baseUrl: 'http://api.example.com',
tenantId: 1,
branchId: 1,
httpClient: new MyHttpClient(),
storage: new LocalStorageSync(1, 1), // Optional
clientId: 'custom-client-id', // Optional
clientVersion: '1.0.0', // Optional
clientType: 'mobile', // Optional
fetchIntervalMs: 30000 // Optional: Sync every 30 seconds
});
// Register data types
client.registerCustomDataType(
'myDataType',
'/api/my-data',
SaveOption.Merge,
new MyDataRepository(),
true,
true
);
// Start the sync process
const results = await client.start();
// Check results
if (results.some(r => r.error)) {
console.warn('Some sync operations failed');
} else {
console.info('All sync operations completed successfully');
}
// Later, if needed
client.stopSyncSchedule();The client handles all synchronization operations internally, including:
- Data version tracking
- Sync planning
- Error handling
- Schedule management
- Data persistence
All other methods are private and used internally by the client to manage the sync process.
Complete Sync Workflow
The start() method provides a complete sync workflow that:
- Executes an initial sync operation
- Initializes the sync schedule if
fetchIntervalMsis configured
Example usage:
const client = new SyncGatewayClient({
// ... configuration
fetchIntervalMs: 30000 // Sync every 30 seconds
});
// Start the sync process and initialize schedule
const results = await client.start();
// Check results
if (results.some(r => r.error)) {
console.warn('Some sync operations failed');
} else {
console.info('All sync operations completed successfully');
}The method will:
- Execute an initial sync operation immediately
- Initialize the sync schedule if
fetchIntervalMsis configured - Return the results from the initial sync operation
SaveDataService
class SaveDataService<T> {
private readonly DEFAULT_CHUNK_SIZE = 5000;
constructor(
private readonly dataRepository: IDataRepository<T>,
private readonly chunkSize: number = 5000
);
/**
* Saves data according to the specified save option
* @param data The data to save
* @param saveOption The save option to use
* @param deletedIds Optional array of IDs to delete
*/
async saveData(data: T[], saveOption: SaveOption, deletedIds?: number[]): Promise<void>;
private async saveWithMerge(data: T[], deletedIds?: number[]): Promise<void>;
private async saveWithReplace(data: T[]): Promise<void>;
private async processDeletions(ids: number[]): Promise<void>;
private async processInChunks<TItem>(
items: TItem[],
processor: (chunk: TItem[]) => Promise<void>
): Promise<void>;
private splitIntoChunks<TItem>(array: TItem[], chunkSize: number): TItem[][];
}Constants
CLIENT_SETTINGS_KEY = 'sync_gateway_client_settings'
DATA_VERSIONS_KEY = 'sync_gateway_data_versions'
MODIFIED_DATES_KEY = 'sync_gateway_modified_dates'Data Type Registration
When registering a data type, you can specify whether it uses revision tracking and/or modified date tracking:
// Register a data type with both revision and modified date tracking
client.registerCustomDataType(
'myDataType',
'/api/my-data',
SaveOption.Merge,
new MyDataRepository(),
true, // isUsingRevision
true // isUsingModifiedDate
);
// Register a data type with only revision tracking
client.registerCustomDataType(
'otherDataType',
'/api/other-data',
SaveOption.Replace,
new OtherDataRepository(),
true, // isUsingRevision
false // isUsingModifiedDate
);The client will only include revision and modified date information in sync operations when the respective tracking is enabled for a data type.
Scheduled Sync
The client supports scheduled sync operations through the fetchIntervalMs configuration and related methods:
const client = new SyncGatewayClient({
// ... other configuration
fetchIntervalMs: 30000 // Sync every 30 seconds
});
// Initialize the sync schedule
client.initSyncSchedule();
// Later, if you need to stop the schedule
client.stopSyncSchedule();The fetchIntervalMs configuration:
- Optional parameter in
SyncGatewayClientConfig - Specifies the interval in milliseconds between sync operations
- If set to 0 or not provided, no automatic sync will be scheduled
- Must be greater than 0 to enable scheduled sync
Methods:
initSyncSchedule(): Starts the sync schedule using the configured intervalstopSyncSchedule(): Stops the sync schedule if it's running
The scheduled sync will:
- Run the complete sync workflow at the specified interval
- Handle errors gracefully without stopping the schedule
- Log information about schedule initialization and errors
- Allow stopping the schedule when needed
License
MIT
