npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@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/syncgatewayclient

Usage

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 a SyncPlanResponse with success: false and error details if the server call fails
  • executeSync: Returns an array of CompletedSyncResult where each item indicates success/failure with error details
  • commitSync: Returns an object with success: boolean and 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): void
  • registerStorage(storage: ISyncStorage): void
  • getStorage(): ISyncStorage
  • registerCustomDataType<T>(dataType: string, baseFetchUrl: string, saveOption: SaveOption, dataRepository: IDataRepository<T>, isUsingRevision?: boolean, isUsingModifiedDate?: boolean): void
  • unregisterCustomDataType(dataTypeName: string): boolean
  • getTenantId(): number
  • getBranchId(): number
  • stopSyncSchedule(): void

The client provides a public API through these methods:

  1. Core Sync Operation:
// Start the sync process
const results = await client.start();
  1. 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();
  1. Storage Management:
// Register custom storage
client.registerStorage(newStorage);

// Get current storage
const storage = client.getStorage();
  1. 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');
  1. 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:

  1. Executes an initial sync operation
  2. Initializes the sync schedule if fetchIntervalMs is 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 fetchIntervalMs is 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 interval
  • stopSyncSchedule(): 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