diff --git a/packages/common/src/client/AbstractPowerSyncDatabase.ts b/packages/common/src/client/AbstractPowerSyncDatabase.ts index 843deb4c8..f9ecc6a87 100644 --- a/packages/common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/common/src/client/AbstractPowerSyncDatabase.ts @@ -267,7 +267,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { const result = await this.getAll( @@ -591,6 +594,8 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { return await this.readTransaction(async (tx) => { @@ -628,6 +633,8 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { return this.bucketStorageAdapter.getClientId(); @@ -652,14 +659,27 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver(sql: string, parameters?: any[]): Promise { await this.waitForReady(); @@ -685,6 +713,10 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver(sql: string, parameters?: any[]): Promise { await this.waitForReady(); @@ -693,6 +725,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver(sql: string, parameters?: any[]): Promise { await this.waitForReady(); @@ -724,6 +761,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver( callback: (tx: Transaction) => Promise, @@ -744,6 +786,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver( callback: (tx: Transaction) => Promise, @@ -818,6 +865,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver this.options.logger?.error(e) } = handler ?? {}; @@ -863,6 +915,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { return new EventIterator((eventOptions) => { @@ -883,6 +940,16 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { const resolvedTables = options?.tables ? [...options.tables] : []; if (!options?.tables) { @@ -955,7 +1022,9 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver void { const { onChange, onError = (e: Error) => this.options.logger?.error(e) } = handler ?? {}; @@ -1008,8 +1077,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { const resolvedOptions = options ?? {}; diff --git a/packages/common/src/db/crud/SyncStatus.ts b/packages/common/src/db/crud/SyncStatus.ts index 1356ab51d..2349a132e 100644 --- a/packages/common/src/db/crud/SyncStatus.ts +++ b/packages/common/src/db/crud/SyncStatus.ts @@ -33,34 +33,50 @@ export class SyncStatus { constructor(protected options: SyncStatusOptions) {} /** - * true if currently connected. + * Indicates if the client is currently connected to the PowerSync service. + * + * @returns {boolean} True if connected, false otherwise. Defaults to false if not specified. */ get connected() { return this.options.connected ?? false; } + /** + * Indicates if the client is in the process of establishing a connection to the PowerSync service. + * + * @returns {boolean} True if connecting, false otherwise. Defaults to false if not specified. + */ get connecting() { return this.options.connecting ?? false; } /** - * Time that a last sync has fully completed, if any. - * Currently this is reset to null after a restart. + * Time that a last sync has fully completed, if any. + * This timestamp is reset to null after a restart of the PowerSync service. + * + * @returns {Date | undefined} The timestamp of the last successful sync, or undefined if no sync has completed. */ get lastSyncedAt() { return this.options.lastSyncedAt; } /** - * Indicates whether there has been at least one full sync, if any. - * Is undefined when unknown, for example when state is still being loaded from the database. + * Indicates whether there has been at least one full sync completed since initialization. + * + * @returns {boolean | undefined} True if at least one sync has completed, false if no sync has completed, + * or undefined when the state is still being loaded from the database. */ get hasSynced() { return this.options.hasSynced; } /** - * Upload/download status + * Provides the current data flow status regarding uploads and downloads. + * + * @returns {SyncDataFlowStatus} An object containing: + * - downloading: True if actively downloading changes (only when connected is also true) + * - uploading: True if actively uploading changes + * Defaults to {downloading: false, uploading: false} if not specified. */ get dataFlowStatus() { return ( @@ -79,26 +95,33 @@ export class SyncStatus { } /** - * Partial sync status for involved bucket priorities. + * Provides sync status information for all bucket priorities, sorted by priority (highest first). + * + * @returns {SyncPriorityStatus[]} An array of status entries for different sync priority levels, + * sorted with highest priorities (lower numbers) first. */ get priorityStatusEntries() { return (this.options.priorityStatusEntries ?? []).slice().sort(SyncStatus.comparePriorities); } /** - * Reports a pair of {@link SyncStatus#hasSynced} and {@link SyncStatus#lastSyncedAt} fields that apply - * to a specific bucket priority instead of the entire sync operation. - * + * Reports the sync status (a pair of {@link SyncStatus#hasSynced} and {@link SyncStatus#lastSyncedAt} fields) + * for a specific bucket priority level. + * * When buckets with different priorities are declared, PowerSync may choose to synchronize higher-priority * buckets first. When a consistent view over all buckets for all priorities up until the given priority is * reached, PowerSync makes data from those buckets available before lower-priority buckets have finished - * synchronizing. - * When PowerSync makes data for a given priority available, all buckets in higher-priorities are guaranteed to - * be consistent with that checkpoint. For this reason, this method may also return the status for lower priorities. - * In a state where the PowerSync just finished synchronizing buckets in priority level 3, calling this method + * syncing. + * + * This method returns the status for the requested priority or the next higher priority level that has + * status information available. This is because when PowerSync makes data for a given priority available, + * all buckets in higher-priorities are guaranteed to be consistent with that checkpoint. + * + * For example, if PowerSync just finished synchronizing buckets in priority level 3, calling this method * with a priority of 1 may return information for priority level 3. * - * @param priority The bucket priority for which the status should be reported. + * @param {number} priority The bucket priority for which the status should be reported + * @returns {SyncPriorityStatus} Status information for the requested priority level or the next higher level with available status */ statusForPriority(priority: number): SyncPriorityStatus { // priorityStatusEntries are sorted by ascending priorities (so higher numbers to lower numbers). @@ -117,15 +140,33 @@ export class SyncStatus { }; } + /** + * Compares this SyncStatus instance with another to determine if they are equal. + * Equality is determined by comparing the serialized JSON representation of both instances. + * + * @param {SyncStatus} status The SyncStatus instance to compare against + * @returns {boolean} True if the instances are considered equal, false otherwise + */ isEqual(status: SyncStatus) { return JSON.stringify(this.options) == JSON.stringify(status.options); } + /** + * Creates a human-readable string representation of the current sync status. + * Includes information about connection state, sync completion, and data flow. + * + * @returns {string} A string representation of the sync status + */ getMessage() { const dataFlow = this.dataFlowStatus; return `SyncStatus`; } + /** + * Serializes the SyncStatus instance to a plain object. + * + * @returns {SyncStatusOptions} A plain object representation of the sync status + */ toJSON(): SyncStatusOptions { return { connected: this.connected,